diff --git a/CONTRIBUTING.asciidoc b/CONTRIBUTING.asciidoc
index 0e066e3e807b3365dd3224d025b2bff7bb4d57b8..4126bc8d9ffd8cd9fb39a2122636471cf3b4d606 100644
--- a/CONTRIBUTING.asciidoc
+++ b/CONTRIBUTING.asciidoc
@@ -10,7 +10,7 @@ The toolkit includes tooling to support the entire development process of (super
 
 For more information, see:
 
-* Website: https://eclipse.org/escet
+* Website: https://eclipse.dev/escet
 * GitLab: https://gitlab.eclipse.org/eclipse/escet/escet
 * Project home: https://projects.eclipse.org/projects/technology.escet
 
@@ -18,7 +18,7 @@ For more information, see:
 
 For more information regarding source code management, builds, setting up a developer environment, coding standards, how to contribute, and more, see the Eclipse ESCET development documentation at:
 
-* https://eclipse.org/escet/development
+* https://eclipse.dev/escet/development
 
 The project maintains the following source code repositories:
 
@@ -38,7 +38,7 @@ Remember that contributions are always welcome!
 
 To contribute source code (e.g. patches) via GitLab, see:
 
-* https://eclipse.org/escet/development/development/contributing.html
+* https://eclipse.dev/escet/development/development/contributing.html
 
 To create issues, reply to issues, contribute patches and merge requests, etc, you need an Eclipse Foundation account.
 It can easily be created at https://accounts.eclipse.org/user/register.
diff --git a/DEPENDENCIES.txt b/DEPENDENCIES.txt
index 67ce7c17e001664190e0f08fb9a32e978a603345..69379efc5ecd00d134be91ab6de3a5cc607cb5ea 100644
--- a/DEPENDENCIES.txt
+++ b/DEPENDENCIES.txt
@@ -1,182 +1,186 @@
+maven/mavencentral/com.github.com-github-javabdd/com.github.javabdd/5.0.0, LGPL-2.0-or-later, approved, #2530
 maven/mavencentral/com.google.code.findbugs/jsr305/3.0.2, Apache-2.0, approved, #20
-maven/mavencentral/com.google.errorprone/error_prone_annotations/2.3.4, Apache-2.0, approved, #807
+maven/mavencentral/com.google.errorprone/error_prone_annotations/2.11.0, Apache-2.0, approved, clearlydefined
 maven/mavencentral/com.google.guava/failureaccess/1.0.1, Apache-2.0, approved, CQ22654
-maven/mavencentral/com.google.guava/guava/30.1-jre, Apache-2.0 AND CC0-1.0 AND LicenseRef-Public-Domain, approved, CQ23244
+maven/mavencentral/com.google.guava/guava/31.1-jre, Apache-2.0, approved, clearlydefined
 maven/mavencentral/com.google.guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava, Apache-2.0, approved, CQ22657
 maven/mavencentral/com.google.j2objc/j2objc-annotations/1.3, Apache-2.0, approved, CQ21195
+maven/mavencentral/com.ibm.icu/icu4j/72.1, ICU, approved, #4354
 maven/mavencentral/commons-io/commons-io/2.8.0, Apache-2.0, approved, CQ23182
 maven/mavencentral/javax.annotation/javax.annotation-api/1.2, CDDL-1.1 OR GPL-2.0-only WITH Classpath-exception-2.0, approved, CQ15728
 maven/mavencentral/junit/junit/4.13.2, EPL-2.0, approved, CQ23636
 maven/mavencentral/org.apache.ant/ant/1.10.9, Apache-2.0 AND W3C AND LicenseRef-Public-Domain, approved, CQ15560
-maven/mavencentral/org.apache.commons/commons-lang3/3.1, Apache-2.0, approved, CQ5902
-maven/mavencentral/org.apache.maven.plugin-tools/maven-plugin-annotations/3.6.4, Apache-2.0, approved, #808
-maven/mavencentral/org.apache.maven/maven-artifact/3.8.5, Apache-2.0, approved, #2687
-maven/mavencentral/org.apache.maven/maven-model/3.8.5, Apache-2.0, approved, #2688
-maven/mavencentral/org.apache.maven/maven-plugin-api/3.8.5, Apache-2.0, approved, #1662
-maven/mavencentral/org.checkerframework/checker-qual/3.5.0, MIT, approved, clearlydefined
+maven/mavencentral/org.apache.commons/commons-lang3/3.12.0, Apache-2.0, approved, clearlydefined
+maven/mavencentral/org.apache.commons/commons-text/1.10.0, Apache-2.0, approved, clearlydefined
+maven/mavencentral/org.apache.felix/org.apache.felix.scr/2.2.6, Apache-2.0 AND BSD-3-Clause AND MIT, approved, #798
+maven/mavencentral/org.apache.maven.plugin-tools/maven-plugin-annotations/3.8.2, Apache-2.0, approved, #7206
+maven/mavencentral/org.apache.maven/maven-artifact/3.8.7, Apache-2.0, approved, #2687
+maven/mavencentral/org.apache.maven/maven-model/3.8.7, Apache-2.0, approved, #2688
+maven/mavencentral/org.apache.maven/maven-plugin-api/3.8.7, Apache-2.0, approved, #1662
+maven/mavencentral/org.bouncycastle/bcpg-jdk18on/1.72.2, Apache-2.0, approved, #4295
+maven/mavencentral/org.bouncycastle/bcprov-jdk18on/1.72, MIT AND CC0-1.0, approved, #3538
+maven/mavencentral/org.checkerframework/checker-qual/3.12.0, MIT, approved, clearlydefined
 maven/mavencentral/org.codehaus.groovy/groovy-ant/3.0.8, Apache-2.0, approved, clearlydefined
 maven/mavencentral/org.codehaus.groovy/groovy-json/3.0.8, Apache-2.0, approved, clearlydefined
 maven/mavencentral/org.codehaus.groovy/groovy/3.0.8, Apache-2.0, approved, #818
+maven/mavencentral/org.codehaus.mojo/animal-sniffer-annotations/1.9, MIT, approved, clearlydefined
 maven/mavencentral/org.codehaus.plexus/plexus-classworlds/2.6.0, Apache-2.0 AND Plexus, approved, CQ22821
 maven/mavencentral/org.codehaus.plexus/plexus-component-annotations/1.5.5, Apache-2.0, approved, CQ4581
-maven/mavencentral/org.codehaus.plexus/plexus-utils/3.3.0, , approved, CQ21066
+maven/mavencentral/org.codehaus.plexus/plexus-utils/3.3.1, , approved, CQ21066
 maven/mavencentral/org.eclipse.sisu/org.eclipse.sisu.inject/0.3.5, EPL-1.0, approved, technology.sisu
 maven/mavencentral/org.eclipse.sisu/org.eclipse.sisu.plexus/0.3.5, EPL-1.0, approved, technology.sisu
 maven/mavencentral/org.hamcrest/hamcrest-core/1.3, BSD-2-Clause, approved, CQ11429
-maven/mavencentral/org.jsoup/jsoup/1.8.3, MIT, approved, CQ12749
+maven/mavencentral/org.jsoup/jsoup/1.15.3, MIT, approved, #3272
+maven/mavencentral/org.osgi/org.osgi.namespace.extender/1.0.1, Apache-2.0, approved, clearlydefined
+maven/mavencentral/org.osgi/org.osgi.namespace.implementation/1.0.0, Apache-2.0, approved, clearlydefined
+maven/mavencentral/org.osgi/org.osgi.service.component/1.5.1, Apache-2.0, approved, #5389
+maven/mavencentral/org.osgi/org.osgi.service.event/1.4.1, Apache-2.0, approved, clearlydefined
 maven/mavencentral/org.osgi/org.osgi.service.prefs/1.1.2, Apache-2.0, approved, #2451
 maven/mavencentral/org.osgi/org.osgi.util.function/1.2.0, Apache-2.0, approved, #6908
-maven/mavencentral/org.osgi/org.osgi.util.promise/1.2.0, Apache-2.0, approved, clearlydefined
+maven/mavencentral/org.osgi/org.osgi.util.promise/1.3.0, Apache-2.0, approved, #5266
 maven/mavencentral/org.osgi/osgi.annotation/8.0.1, Apache-2.0, approved, #6909
+maven/mavencentral/org.osgi/osgi.annotation/8.1.0, Apache-2.0, approved, #1985
 maven/mavencentral/org.ow2.sat4j/org.ow2.sat4j.core/2.3.6, (EPL-1.0 OR LGPL-2.0-or-later) AND MIT, approved, #1929
 maven/mavencentral/org.ow2.sat4j/org.ow2.sat4j.pb/2.3.6, (EPL-1.0 OR LGPL-2.1-or-later) AND MIT, approved, #1928
-p2/orbit/p2.eclipse.plugin/com.ibm.icu/67.1.0.v20200706-1749, ICU AND Unicode-TOU AND BSD-3-Clause AND BSD-2-Clause AND LicenseRef-ipadic-license AND LicenseRef-Public-Domain, approved, CQ22320
-p2/orbit/p2.eclipse.plugin/com.sun.jna.platform/5.8.0.v20210406-1004, Apache-2.0 OR LGPL-2.1-or-later, approved, CQ23218
-p2/orbit/p2.eclipse.plugin/com.sun.jna/5.8.0.v20210503-0343, Apache-2.0 OR LGPL-2.1-or-later, approved, CQ23217
-p2/orbit/p2.eclipse.plugin/io.github.java-diff-utils/4.8.0.v20201027-1614, Apache-2.0, approved, CQ22697
-p2/orbit/p2.eclipse.plugin/javax.annotation/1.3.5.v20200909-1856, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.ca
+maven/mavencentral/org.tukaani/xz/1.9, LicenseRef-Public-Domain, approved, CQ23498
+p2/orbit/p2.eclipse.plugin/com.sun.jna.platform/5.12.1.v20221103-2317, Apache-2.0 OR LGPL-2.1-or-later, approved, #4137
+p2/orbit/p2.eclipse.plugin/com.sun.jna/5.12.1.v20221103-2317, Apache-2.0 OR LGPL-2.1-or-later, approved, #4136
+p2/orbit/p2.eclipse.plugin/io.github.java-diff-utils/4.8.0.v20221112-0806, Apache-2.0, approved, CQ22697
+p2/orbit/p2.eclipse.plugin/javax.annotation/1.3.5.v20221203-1659, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.ca
 p2/orbit/p2.eclipse.plugin/javax.inject/1.0.0.v20220405-0441, Apache-2.0, approved, CQ3555
-p2/orbit/p2.eclipse.plugin/org.apache.batik.anim/1.14.0.v20210324-0332, Apache-2.0, approved, #196
-p2/orbit/p2.eclipse.plugin/org.apache.batik.awt.util/1.14.0.v20210324-0332, Apache-2.0, approved, #256
-p2/orbit/p2.eclipse.plugin/org.apache.batik.bridge/1.14.0.v20210324-0332, Apache-2.0, approved, #196
-p2/orbit/p2.eclipse.plugin/org.apache.batik.constants/1.14.0.v20210324-0332, Apache-2.0, approved, #196
-p2/orbit/p2.eclipse.plugin/org.apache.batik.css/1.14.0.v20210324-0332, Apache-2.0, approved, #196
-p2/orbit/p2.eclipse.plugin/org.apache.batik.dom.svg/1.14.0.v20210324-0332, Apache-2.0, approved, #196
-p2/orbit/p2.eclipse.plugin/org.apache.batik.dom/1.14.0.v20210324-0332, Apache-2.0, approved, #196
-p2/orbit/p2.eclipse.plugin/org.apache.batik.ext/1.14.0.v20210324-0332, Apache-2.0, approved, #196
-p2/orbit/p2.eclipse.plugin/org.apache.batik.gvt/1.14.0.v20210324-0332, Apache-2.0, approved, #196
-p2/orbit/p2.eclipse.plugin/org.apache.batik.i18n/1.14.0.v20210324-0332, Apache-2.0, approved, #196
-p2/orbit/p2.eclipse.plugin/org.apache.batik.parser/1.14.0.v20210324-0332, Apache-2.0, approved, #196
-p2/orbit/p2.eclipse.plugin/org.apache.batik.script/1.14.0.v20210324-0332, Apache-2.0, approved, #196
-p2/orbit/p2.eclipse.plugin/org.apache.batik.util/1.14.0.v20210324-0332, Apache-2.0, approved, #196
-p2/orbit/p2.eclipse.plugin/org.apache.batik.xml/1.14.0.v20210324-0332, Apache-2.0, approved, #196
+p2/orbit/p2.eclipse.plugin/org.apache.batik.anim/1.16.0.v20221027-0840, Apache-2.0, approved, #5348
+p2/orbit/p2.eclipse.plugin/org.apache.batik.awt.util/1.16.0.v20221027-0840, Apache-2.0, approved, #5325
+p2/orbit/p2.eclipse.plugin/org.apache.batik.bridge/1.16.0.v20230210-1249, Apache-2.0, approved, #5354
+p2/orbit/p2.eclipse.plugin/org.apache.batik.constants/1.16.0.v20221027-0840, Apache-2.0, approved, #4851
+p2/orbit/p2.eclipse.plugin/org.apache.batik.css/1.16.0.v20221027-0840, Apache-2.0, approved, #4852
+p2/orbit/p2.eclipse.plugin/org.apache.batik.dom.svg/1.16.0.v20221027-0840, Apache-2.0 AND W3C, approved, #5335
+p2/orbit/p2.eclipse.plugin/org.apache.batik.dom/1.16.0.v20230210-1249, Apache-2.0 AND W3C, approved, #5350
+p2/orbit/p2.eclipse.plugin/org.apache.batik.ext/1.16.0.v20221027-0840, Apache-2.0 AND W3C, approved, #5326
+p2/orbit/p2.eclipse.plugin/org.apache.batik.gvt/1.16.0.v20221027-0840, Apache-2.0, approved, #5351
+p2/orbit/p2.eclipse.plugin/org.apache.batik.i18n/1.16.0.v20221027-0840, Apache-2.0, approved, #4849
+p2/orbit/p2.eclipse.plugin/org.apache.batik.parser/1.16.0.v20221027-0840, Apache-2.0, approved, #5365
+p2/orbit/p2.eclipse.plugin/org.apache.batik.script/1.16.0.v20221027-0840, Apache-2.0, approved, #5327
+p2/orbit/p2.eclipse.plugin/org.apache.batik.util/1.16.0.v20221027-0840, Apache-2.0, approved, #4850
+p2/orbit/p2.eclipse.plugin/org.apache.batik.xml/1.16.0.v20221027-0840, Apache-2.0, approved, #5341
 p2/orbit/p2.eclipse.plugin/org.apache.commons.exec/1.1.0.v201301240602, Apache-2.0, approved, CQ6553
 p2/orbit/p2.eclipse.plugin/org.apache.commons.io/2.8.0.v20210415-0900, Apache-2.0, approved, CQ23182
 p2/orbit/p2.eclipse.plugin/org.apache.commons.jxpath/1.3.0.v200911051830, Apache-2.0, approved, CQ10790
-p2/orbit/p2.eclipse.plugin/org.apache.commons.lang3/3.1.0.v201403281430, Apache-2.0, approved, CQ5902
+p2/orbit/p2.eclipse.plugin/org.apache.commons.lang3/3.12.0.v20221221-1931, Apache-2.0, approved, #2077
 p2/orbit/p2.eclipse.plugin/org.apache.commons.logging/1.2.0.v20180409-1502, Apache-2.0, approved, CQ10162
-p2/orbit/p2.eclipse.plugin/org.apache.commons.math3/3.6.1.v20200817-1830, Apache-2.0 AND BSD-3-Clause AND BSD-2-Clause, approved, CQ22025
-p2/orbit/p2.eclipse.plugin/org.apache.felix.scr/2.1.24.v20200924-1939, Apache-2.0 AND MIT, approved, CQ21362
-p2/orbit/p2.eclipse.plugin/org.apache.xalan/2.7.2.v20201124-1837, Apache-2.0, approved, CQ9587
-p2/orbit/p2.eclipse.plugin/org.apache.xerces/2.12.2.v20220131-0835, Apache-2.0 AND W3C-19980720, approved, CQ16951
-p2/orbit/p2.eclipse.plugin/org.apache.xml.resolver/1.2.0.v20220401-1849, Apache-2.0, approved, CQ1441
-p2/orbit/p2.eclipse.plugin/org.apache.xmlgraphics/2.6.0.v20210409-0748, Apache-2.0, approved, CQ23228
-p2/orbit/p2.eclipse.plugin/org.bouncycastle.bcpg/1.70.0.v20220507-1208, Apache-2.0, approved, #3894
-p2/orbit/p2.eclipse.plugin/org.bouncycastle.bcprov/1.70.0.v20220507-1208, MIT, approved, #3893
-p2/orbit/p2.eclipse.plugin/org.eclipse.ant.core/3.6.400.v20220317-1003, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.compare.core/3.7.0.v20220513-0551, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.compare/3.8.400.v20220420-1133, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.core.commands/3.10.200.v20220512-0851, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.core.contenttype/3.8.100.v20210910-0640, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.core.databinding.observable/1.12.0.v20211231-1006, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.core.databinding.property/1.9.0.v20210619-1129, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.core.databinding/1.11.0.v20220118-1028, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.core.expressions/3.8.100.v20210910-0640, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.apache.commons.math3/3.6.1.v20221112-0806, Apache-2.0 AND BSD-3-Clause AND BSD-2-Clause, approved, CQ22025
+p2/orbit/p2.eclipse.plugin/org.apache.xmlgraphics/2.7.0.v20221018-0736, Apache-2.0, approved, 3367
+p2/orbit/p2.eclipse.plugin/org.eclipse.ant.core/3.6.500.v20220718-1722, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.compare.core/3.7.100.v20220812-1406, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.compare/3.8.500.v20220812-1406, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.core.commands/3.10.400.v20230220-0932, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.core.contenttype/3.8.200.v20220817-1539, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.core.databinding.observable/1.12.200.v20230220-0932, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.core.databinding.property/1.9.200.v20230220-0932, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.core.databinding/1.12.0.v20230214-1401, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.core.expressions/3.8.200.v20220613-1047, EPL-2.0, approved, eclipse.platform
 p2/orbit/p2.eclipse.plugin/org.eclipse.core.filebuffers/3.7.200.v20220202-1008, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.core.filesystem/1.9.400.v20220419-0658, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.core.jobs/3.13.0.v20220512-1935, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.core.net/1.3.1200.v20220312-1450, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.core.resources/3.17.0.v20220517-0751, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.core.runtime/3.25.0.v20220506-1157, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.core.filesystem/1.9.500.v20220817-1539, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.core.jobs/3.13.300.v20230111-0823, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.core.net/1.4.0.v20220813-1037, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.core.resources/3.18.200.v20230209-0754, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.core.runtime/3.26.100.v20221021-0005, EPL-2.0, approved, eclipse.platform
 p2/orbit/p2.eclipse.plugin/org.eclipse.core.variables/3.5.100.v20210721-1355, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.debug.core/3.19.100.v20220324-0630, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.e4.core.commands/1.0.100.v20211204-1536, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.e4.core.contexts/1.10.0.v20220430-0424, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.e4.core.di.annotations/1.7.100.v20210910-0640, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.e4.core.di.extensions.supplier/0.16.300.v20220503-2248, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.e4.core.di.extensions/0.17.100.v20210910-0640, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.e4.core.di/1.8.200.v20220512-1957, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.e4.core.services/2.3.200.v20220513-1235, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.e4.emf.xpath/0.3.0.v20210722-1426, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.e4.ui.bindings/0.13.100.v20210722-1426, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.e4.ui.css.core/0.13.200.v20211022-1402, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.e4.ui.css.swt.theme/0.13.100.v20220310-1056, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.e4.ui.css.swt/0.14.500.v20220511-1639, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.e4.ui.di/1.4.0.v20210621-1133, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.e4.ui.dialogs/1.3.200.v20211210-1500, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.e4.ui.ide/3.16.100.v20220310-1350, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.e4.ui.model.workbench/2.2.100.v20220331-0744, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.e4.ui.services/1.5.0.v20210115-1333, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.e4.ui.widgets/1.3.0.v20210621-1136, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.e4.ui.workbench.addons.swt/1.4.400.v20211102-0453, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.e4.ui.workbench.renderers.swt/0.15.500.v20220511-1638, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.e4.ui.workbench.swt/0.16.500.v20220506-1520, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.e4.ui.workbench/1.13.100.v20211019-0756, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.e4.ui.workbench3/0.16.0.v20210619-0956, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.emf.common/2.25.0.v20220325-0806, , approved, eclipse
-p2/orbit/p2.eclipse.plugin/org.eclipse.emf.ecore.change/2.14.0.v20190528-0725, , approved, eclipse
-p2/orbit/p2.eclipse.plugin/org.eclipse.emf.ecore.xmi/2.16.0.v20190528-0725, , approved, eclipse
-p2/orbit/p2.eclipse.plugin/org.eclipse.emf.ecore/2.27.0.v20220426-0617, , approved, eclipse
-p2/orbit/p2.eclipse.plugin/org.eclipse.emf.edit/2.17.0.v20220201-1551, , approved, eclipse
-p2/orbit/p2.eclipse.plugin/org.eclipse.emf.validation/1.8.0.202008210805, , approved, eclipse
-p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.app/1.6.100.v20211021-1418, EPL-2.0, approved, eclipse.equinox
-p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.bidi/1.4.100.v20211021-1418, EPL-2.0, approved, eclipse.equinox
-p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.common/3.16.100.v20220315-2327, EPL-2.0, approved, eclipse.equinox
-p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.event/1.6.100.v20211021-1418, EPL-2.0, approved, eclipse.equinox
+p2/orbit/p2.eclipse.plugin/org.eclipse.debug.core/3.20.100.v20230124-1239, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.e4.core.commands/1.0.400.v20230220-0932, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.e4.core.contexts/1.11.0.v20220716-0839, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.e4.core.di.annotations/1.7.200.v20220613-1008, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.e4.core.di.extensions.supplier/0.16.400.v20220613-1047, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.e4.core.di.extensions/0.17.200.v20220613-1008, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.e4.core.di/1.8.300.v20220817-1539, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.e4.core.services/2.3.400.v20220915-1347, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.e4.emf.xpath/0.3.200.v20230220-1427, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.e4.ui.bindings/0.13.300.v20230220-0932, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.e4.ui.css.core/0.13.500.v20230220-0932, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.e4.ui.css.swt.theme/0.13.300.v20230220-0932, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.e4.ui.css.swt/0.14.800.v20230220-0932, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.e4.ui.di/1.4.200.v20230220-0932, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.e4.ui.dialogs/1.3.500.v20230220-0932, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.e4.ui.ide/3.16.300.v20230220-0932, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.e4.ui.model.workbench/2.3.0.v20230220-1021, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.e4.ui.services/1.5.200.v20230220-0932, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.e4.ui.widgets/1.3.200.v20230220-0932, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.e4.ui.workbench.addons.swt/1.4.600.v20230220-0932, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.e4.ui.workbench.renderers.swt/0.15.800.v20230214-1401, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.e4.ui.workbench.swt/0.16.800.v20230220-0932, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.e4.ui.workbench/1.14.100.v20230220-1021, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.e4.ui.workbench3/0.16.200.v20230220-0932, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.emf.common/2.28.0.v20230223-0922, EPL-1.0, approved, modeling.emf
+p2/orbit/p2.eclipse.plugin/org.eclipse.emf.ecore.change/2.15.0.v20230211-1150, EPL-1.0, approved, modeling.emf
+p2/orbit/p2.eclipse.plugin/org.eclipse.emf.ecore.xmi/2.18.0.v20230211-1150, EPL-1.0, approved, modeling.emf
+p2/orbit/p2.eclipse.plugin/org.eclipse.emf.ecore/2.33.0.v20230226-0921, EPL-2.0, approved, modeling.emf.emf
+p2/orbit/p2.eclipse.plugin/org.eclipse.emf.edit/2.18.0.v20230211-1150, EPL-1.0, approved, modeling.emf
+p2/orbit/p2.eclipse.plugin/org.eclipse.emf.validation/1.8.1.202208271102, EPL-1.0, approved, modeling.emfservices
+p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.app/1.6.200.v20220720-2012, EPL-2.0, approved, eclipse.equinox
+p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.bidi/1.4.200.v20220710-1223, EPL-2.0, approved, eclipse.equinox
+p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.common/3.17.100.v20230202-1341, EPL-2.0, approved, eclipse.equinox
+p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.event/1.6.200.v20230120-0604, EPL-2.0, approved, eclipse.equinox
 p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.frameworkadmin.equinox/1.2.200.v20220315-2155, EPL-2.0, approved, eclipse.equinox
-p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.frameworkadmin/2.2.0.v20210315-2042, EPL-2.0, approved, eclipse.equinox
+p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.frameworkadmin/2.2.100.v20220817-1208, EPL-2.0, approved, eclipse.equinox
 p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.launcher/1.6.400.v20210924-0641, EPL-2.0, approved, eclipse.equinox
-p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.p2.artifact.repository/1.4.500.v20220420-1427, EPL-2.0, approved, eclipse.equinox
-p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.p2.core/2.9.100.v20220310-1733, EPL-2.0, approved, eclipse.equinox
-p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.p2.director.app/1.2.100.v20211220-1825, EPL-2.0, approved, eclipse.equinox
-p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.p2.director/2.5.300.v20220421-0708, EPL-2.0, approved, eclipse.equinox
-p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.p2.engine/2.7.400.v20220329-1456, EPL-2.0, approved, eclipse.equinox
-p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.p2.garbagecollector/1.2.0.v20210316-1209, EPL-2.0, approved, eclipse.equinox
-p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.p2.jarprocessor/1.2.300.v20220420-1427, EPL-2.0, approved, eclipse.equinox
+p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.p2.artifact.repository/1.4.800.v20221205-1614, EPL-2.0, approved, eclipse.equinox
+p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.p2.core/2.9.200.v20220817-1208, EPL-2.0, approved, eclipse.equinox
+p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.p2.director.app/1.2.300.v20220911-2007, EPL-2.0, approved, eclipse.equinox
+p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.p2.director/2.5.400.v20220817-1208, EPL-2.0, approved, eclipse.equinox
+p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.p2.engine/2.7.500.v20220817-1208, EPL-2.0, approved, eclipse.equinox
+p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.p2.garbagecollector/1.2.100.v20221111-1340, EPL-2.0, approved, eclipse.equinox
+p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.p2.jarprocessor/1.2.400.v20221201-0952, EPL-2.0, approved, eclipse.equinox
 p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.p2.metadata.repository/1.4.100.v20220329-1456, EPL-2.0, approved, eclipse.equinox
-p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.p2.metadata/2.6.200.v20220324-1313, EPL-2.0, approved, eclipse.equinox
-p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.p2.publisher.eclipse/1.4.100.v20220420-1427, EPL-2.0, approved, eclipse.equinox
-p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.p2.publisher/1.7.100.v20220420-1427, EPL-2.0, approved, eclipse.equinox
-p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.p2.repository.tools/2.3.100.v20220504-1755, EPL-2.0, approved, eclipse.equinox
-p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.p2.repository/2.6.100.v20220422-1806, EPL-2.0, approved, eclipse.equinox
-p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.p2.touchpoint.eclipse/2.3.200.v20220503-2330, EPL-2.0, approved, eclipse.equinox
-p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.preferences/3.10.0.v20220503-1634, EPL-2.0, approved, eclipse.equinox
-p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.registry/3.11.100.v20211021-1418, EPL-2.0, approved, eclipse.equinox
-p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.security/1.3.900.v20220108-1321, EPL-2.0, approved, eclipse.equinox
-p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.simpleconfigurator.manipulator/2.2.0.v20210315-2228, EPL-2.0, approved, eclipse.equinox
-p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.simpleconfigurator/1.4.0.v20210315-2228, EPL-2.0, approved, eclipse.equinox
+p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.p2.metadata/2.6.300.v20220817-1208, EPL-2.0, approved, eclipse.equinox
+p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.p2.publisher.eclipse/1.4.300.v20221214-0640, EPL-2.0, approved, eclipse.equinox
+p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.p2.publisher/1.7.300.v20221203-1819, EPL-2.0, approved, eclipse.equinox
+p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.p2.repository.tools/2.3.300.v20221203-1932, EPL-2.0, approved, eclipse.equinox
+p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.p2.repository/2.6.300.v20221030-1923, EPL-2.0, approved, eclipse.equinox
+p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.p2.touchpoint.eclipse/2.3.300.v20220817-1208, EPL-2.0, approved, eclipse.equinox
+p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.preferences/3.10.200.v20230120-0604, EPL-2.0, approved, eclipse.equinox
+p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.registry/3.11.200.v20220817-1601, EPL-2.0, approved, eclipse.equinox
+p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.security/1.3.1000.v20220801-1135, EPL-2.0, approved, eclipse.equinox
+p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.simpleconfigurator.manipulator/2.2.100.v20221117-1044, EPL-2.0, approved, eclipse.equinox
+p2/orbit/p2.eclipse.plugin/org.eclipse.equinox.simpleconfigurator/1.4.200.v20221111-1340, EPL-2.0, approved, eclipse.equinox
 p2/orbit/p2.eclipse.plugin/org.eclipse.help/3.9.100.v20210721-0601, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.jdt.compiler.tool/1.3.150.v20220318-0906, EPL-2.0, approved, eclipse.jdt
-p2/orbit/p2.eclipse.plugin/org.eclipse.jdt.core/3.30.0.v20220524-1333, EPL-2.0, approved, eclipse.jdt
-p2/orbit/p2.eclipse.plugin/org.eclipse.jdt.debug/3.19.200.v20220430-1851, EPL-2.0, approved, eclipse.jdt
-p2/orbit/p2.eclipse.plugin/org.eclipse.jdt.launching/3.19.600.v20220409-1932, EPL-2.0, approved, eclipse.jdt
-p2/orbit/p2.eclipse.plugin/org.eclipse.jface.databinding/1.13.0.v20210619-1146, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.jface.text/3.20.100.v20220516-0819, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.jface/3.26.0.v20220513-0449, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.ltk.core.refactoring/3.12.200.v20220502-1514, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.ltk.ui.refactoring/3.12.100.v20220329-1353, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.osgi.services/3.10.200.v20210723-0643, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.osgi/3.18.0.v20220516-2155, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.pde.build/3.11.200.v20220503-0921, EPL-2.0, approved, eclipse.pde
-p2/orbit/p2.eclipse.plugin/org.eclipse.pde.core/3.15.200.v20220527-1237, EPL-2.0, approved, eclipse.pde
-p2/orbit/p2.eclipse.plugin/org.eclipse.swt.cocoa.macosx.aarch64/3.120.0.v20220530-1036, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.swt.cocoa.macosx.x86_64/3.120.0.v20220530-1036, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.swt.gtk.linux.x86_64/3.120.0.v20220530-1036, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.swt.win32.win32.x86_64/3.120.0.v20220530-1036, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.swt/3.120.0.v20220530-1036, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.team.core/3.9.400.v20220511-1440, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.team.ui/3.9.300.v20220420-1133, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.text/3.12.100.v20220506-1404, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.ui.console/3.11.200.v20220324-0630, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.ui.editors/3.14.300.v20210913-0815, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.ui.forms/3.11.300.v20211022-1451, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.ui.ide.application/1.4.400.v20220502-1523, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.ui.ide/3.19.0.v20220511-1638, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.ui.intro.quicklinks/1.1.100.v20210315-0954, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.ui.intro.universal/3.4.200.v20210409-1747, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.ui.intro/3.6.500.v20220317-1346, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.ui.navigator.resources/3.8.400.v20220203-1803, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.ui.navigator/3.10.200.v20211009-1706, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.ui.views.properties.tabbed/3.9.100.v20201223-1348, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.ui.views/3.11.100.v20210816-0811, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.ui.workbench.texteditor/3.16.500.v20220331-0848, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.ui.workbench/3.125.100.v20220524-1304, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.ui/3.201.0.v20220124-1108, EPL-2.0, approved, eclipse.platform
-p2/orbit/p2.eclipse.plugin/org.eclipse.urischeme/1.2.100.v20211001-1648, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.jdt.core.compiler.batch/3.33.0.v20230218-1114, EPL-2.0, approved, eclipse.jdt
+p2/orbit/p2.eclipse.plugin/org.eclipse.jdt.core/3.33.0.v20230222-1748, EPL-2.0, approved, eclipse.jdt
+p2/orbit/p2.eclipse.plugin/org.eclipse.jdt.debug/3.20.100.v20230119-1127, EPL-2.0, approved, eclipse.jdt
+p2/orbit/p2.eclipse.plugin/org.eclipse.jdt.launching/3.19.900.v20230209-1222, EPL-2.0, approved, eclipse.jdt
+p2/orbit/p2.eclipse.plugin/org.eclipse.jface.databinding/1.14.100.v20230214-1401, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.jface.text/3.23.0.v20230123-1047, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.jface/3.29.0.v20230214-1401, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.ltk.core.refactoring/3.13.100.v20230117-1625, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.ltk.ui.refactoring/3.12.200.v20220808-2221, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.osgi/3.18.300.v20230220-1352, EPL-2.0, approved, eclipse.equinox
+p2/orbit/p2.eclipse.plugin/org.eclipse.pde.build/3.11.400.v20220923-1253, EPL-2.0, approved, eclipse.pde
+p2/orbit/p2.eclipse.plugin/org.eclipse.pde.core/3.16.100.v20230126-0956, EPL-2.0, approved, eclipse.pde
+p2/orbit/p2.eclipse.plugin/org.eclipse.swt.cocoa.macosx.aarch64/3.123.0.v20230220-1431, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.swt.cocoa.macosx.x86_64/3.123.0.v20230220-1431, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.swt.gtk.linux.x86_64/3.123.0.v20230220-1431, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.swt.win32.win32.x86_64/3.123.0.v20230220-1431, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.swt/3.123.0.v20230220-1431, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.team.core/3.9.700.v20221201-0946, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.team.ui/3.9.600.v20230207-1607, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.text/3.12.300.v20220921-1010, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.ui.console/3.11.400.v20221012-0524, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.ui.editors/3.15.0.v20221201-1935, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.ui.forms/3.11.600.v20230220-0932, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.ui.ide.application/1.4.700.v20230220-0932, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.ui.ide/3.20.100.v20230220-1021, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.ui.intro.quicklinks/1.1.200.v20220619-1918, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.ui.intro.universal/3.4.300.v20220619-1918, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.ui.intro/3.6.600.v20220619-1918, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.ui.navigator.resources/3.8.600.v20230220-1021, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.ui.navigator/3.11.0.v20230214-1401, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.ui.views.properties.tabbed/3.9.400.v20230220-1021, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.ui.views/3.11.400.v20230220-0932, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.ui.workbench.texteditor/3.16.700.v20230210-0941, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.ui.workbench/3.128.0.v20230220-1021, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.ui/3.202.0.v20230214-1401, EPL-2.0, approved, eclipse.platform
+p2/orbit/p2.eclipse.plugin/org.eclipse.urischeme/1.2.300.v20230220-0932, EPL-2.0, approved, eclipse.platform
 p2/orbit/p2.eclipse.plugin/org.hamcrest.core/1.3.0.v20180420-1519, BSD-2-Clause, approved, CQ7063
 p2/orbit/p2.eclipse.plugin/org.junit/4.13.2.v20211018-1956, EPL-1.0, approved, CQ21439
-p2/orbit/p2.eclipse.plugin/org.knowm.xchart/3.6.5.v20201023-2252, Apache-2.0, approved, CQ22695
-p2/orbit/p2.eclipse.plugin/org.tukaani.xz/1.9.0.v20210624-1259, LicenseRef-Public-Domain, approved, CQ23498
+p2/orbit/p2.eclipse.plugin/org.knowm.xchart/3.6.5.v20221112-0806, Apache-2.0, approved, CQ22695
 p2/orbit/p2.eclipse.plugin/org.w3c.css.sac/1.3.1.v200903091627, Apache-2.0 OR LicenseRef-Public-Domain OR W3C, approved, CQ1448
 p2/orbit/p2.eclipse.plugin/org.w3c.dom.events/3.0.0.draft20060413_v201105210656, Apache-2.0, approved, CQ208
 p2/orbit/p2.eclipse.plugin/org.w3c.dom.smil/1.0.1.v200903091627, Apache-2.0 OR LicenseRef-Public-Domain OR W3C, approved, CQ1448
diff --git a/Jenkinsfile b/Jenkinsfile
index 8f56e6c1e6c050f747d5f5f728ac641cf3c6f324..f74869d4d60f7e0956a5710e1b27f00103720c71 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -21,7 +21,7 @@ pipeline {
 
     tools {
         jdk 'openjdk-jdk17-latest'
-        maven 'apache-maven-3.8.4'
+        maven 'apache-maven-3.8.6'
     }
 
     options {
@@ -49,8 +49,24 @@ pipeline {
     }
 
     stages {
+        stage('Initialize GPG') {
+            steps {
+                withCredentials([file(credentialsId: 'secret-subkeys.asc', variable: 'KEYRING')]) {
+                    sh '''
+                        # Only sign certain branches. See similar condition below for details.
+                        if [[ "$GIT_BRANCH" == "master" || "$TAG_NAME" =~ ^v[0-9]+\\.[0-9]+.*$ ]]; then
+                            gpg --batch --import "${KEYRING}"
+                            for fpr in $(gpg --list-keys --with-colons | awk -F: \'/fpr:/ {print $10}\' | sort -u); do
+                              echo -e "5\ny\n" |  gpg --batch --command-fd 0 --expert --edit-key ${fpr} trust;
+                            done
+                        fi
+                    '''
+                }
+            }
+        }
         stage('Build & Test') {
             steps {
+                withCredentials([string(credentialsId: 'gpg-passphrase', variable: 'KEYRING_PASSPHRASE')]) {
                 wrap([$class: 'Xvnc', takeScreenshot: false, useXauthority: true]) {
                     sh '''
                         # Print versions.
@@ -74,8 +90,10 @@ pipeline {
                         # Configure 'sign' profile for build.
                         # Sign 'master' branch, to allow checking release signing before deployment.
                         # Sign releases. Determined based on release version tag name.
+                        # This condition must match a similar condition above.
                         if [[ "$GIT_BRANCH" == "master" || "$TAG_NAME" =~ ^v[0-9]+\\.[0-9]+.*$ ]]; then
                             BUILD_ARGS="$BUILD_ARGS -Psign"
+                            BUILD_ARGS="$BUILD_ARGS -Dgpg.passphrase=${KEYRING_PASSPHRASE}"
                         fi
 
                         # Override the 'escet.version.enduser' property for releases. Remains 'dev' otherwise.
@@ -102,7 +120,7 @@ pipeline {
                         # Perform build.
                         ./build.sh $BUILD_ARGS
                     '''
-                }
+                }}
             }
 
             post {
diff --git a/NOTICE.asciidoc b/NOTICE.asciidoc
index 9ee9d043bd72bb2c9e25ae120dd74fe3ac294015..15c03b0b0d9b42cdb71e5ccd459be5bc17b7637b 100644
--- a/NOTICE.asciidoc
+++ b/NOTICE.asciidoc
@@ -2,8 +2,8 @@
 
 This content is produced and maintained by the Eclipse Supervisory Control Engineering Toolkit (Eclipse ESCET(TM)) project.
 
-* Website: https://eclipse.org/escet
-* Downloads: https://eclipse.org/escet/download.html
+* Website: https://eclipse.dev/escet
+* Downloads: https://eclipse.dev/escet/download.html
 * GitLab development server: https://gitlab.eclipse.org/eclipse/escet/escet
 * Issue tracker: https://gitlab.eclipse.org/eclipse/escet/escet/-/issues
 * Forum: https://www.eclipse.org/forums/index.php/f/527/
diff --git a/README.asciidoc b/README.asciidoc
index 14016664ad3d63b15d14bdb5f3ed1122f24042aa..3b8b2ab6a21eb9f318c9ab099c3e29d59372e36a 100644
--- a/README.asciidoc
+++ b/README.asciidoc
@@ -6,6 +6,6 @@ The toolkit includes tooling to support the entire development process of (super
 
 For more information, see:
 
-* Website: https://eclipse.org/escet
+* Website: https://eclipse.dev/escet
 * GitLab: https://gitlab.eclipse.org/eclipse/escet/escet
 * Project home: https://projects.eclipse.org/projects/technology.escet
diff --git a/build-clean.launch b/build-clean.launch
index 36115c6a2a13c2fb7ec083e3c0d5e559264edb6d..7327048dff1253112c585694817189232ccec8ff 100644
--- a/build-clean.launch
+++ b/build-clean.launch
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <launchConfiguration type="org.eclipse.m2e.Maven2LaunchConfigurationType">
+    <intAttribute key="M2_COLORS" value="0"/>
     <booleanAttribute key="M2_DEBUG_OUTPUT" value="false"/>
     <stringAttribute key="M2_GOALS" value="clean"/>
     <booleanAttribute key="M2_NON_RECURSIVE" value="false"/>
@@ -14,8 +15,10 @@
     <booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="false"/>
     <stringAttribute key="M2_USER_SETTINGS" value=""/>
     <booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="false"/>
+    <booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
     <stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${workspace}"/>
     <booleanAttribute key="org.eclipse.jdt.launching.ATTR_ATTR_USE_ARGFILE" value="false"/>
+    <booleanAttribute key="org.eclipse.jdt.launching.ATTR_SHOW_CODEDETAILS_IN_EXCEPTION_MESSAGES" value="true"/>
     <booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_CLASSPATH_ONLY_JAR" value="false"/>
     <stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc:/org.eclipse.escet.root}"/>
 </launchConfiguration>
diff --git a/build-docs.launch b/build-docs.launch
index e07a28d4a57cdb8992c472aef30669e44572f674..42eab42e355579f80dc577424b920ea1b4fba7d0 100644
--- a/build-docs.launch
+++ b/build-docs.launch
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <launchConfiguration type="org.eclipse.m2e.Maven2LaunchConfigurationType">
+    <intAttribute key="M2_COLORS" value="0"/>
     <booleanAttribute key="M2_DEBUG_OUTPUT" value="false"/>
     <stringAttribute key="M2_GOALS" value="clean package --projects releng/org.eclipse.escet.releng.target,chi/org.eclipse.escet.chi.documentation,cif/org.eclipse.escet.cif.documentation,releng/org.eclipse.escet.releng.dev.documentation,releng/org.eclipse.escet.releng.project.documentation,tooldef/org.eclipse.escet.tooldef.documentation --also-make"/>
     <booleanAttribute key="M2_NON_RECURSIVE" value="false"/>
@@ -15,6 +16,7 @@
     <booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="true"/>
     <stringAttribute key="M2_USER_SETTINGS" value=""/>
     <booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="false"/>
+    <booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
     <stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${workspace}"/>
     <mapAttribute key="org.eclipse.debug.core.environmentVariables">
         <mapEntry key="JAVA_HOME" value="${system_property:java.home}"/>
diff --git a/build.launch b/build.launch
index b378b3595ff19923c3b63c22d4771b95aa7dffea..818c2c66697be240c4c6e6229ab15c6d70c53868 100644
--- a/build.launch
+++ b/build.launch
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <launchConfiguration type="org.eclipse.m2e.Maven2LaunchConfigurationType">
+    <intAttribute key="M2_COLORS" value="0"/>
     <booleanAttribute key="M2_DEBUG_OUTPUT" value="false"/>
     <stringAttribute key="M2_GOALS" value="clean verify"/>
     <booleanAttribute key="M2_NON_RECURSIVE" value="false"/>
@@ -14,6 +15,7 @@
     <booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="false"/>
     <stringAttribute key="M2_USER_SETTINGS" value=""/>
     <booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="false"/>
+    <booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
     <stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${workspace}"/>
     <mapAttribute key="org.eclipse.debug.core.environmentVariables">
         <mapEntry key="JAVA_HOME" value="${system_property:java.home}"/>
diff --git a/chi/org.eclipse.escet.chi.codegen/.settings/org.eclipse.jdt.core.prefs b/chi/org.eclipse.escet.chi.codegen/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/chi/org.eclipse.escet.chi.codegen/.settings/org.eclipse.jdt.core.prefs
+++ b/chi/org.eclipse.escet.chi.codegen/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/chi/org.eclipse.escet.chi.codegen/.settings/org.eclipse.jdt.ui.prefs b/chi/org.eclipse.escet.chi.codegen/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/chi/org.eclipse.escet.chi.codegen/.settings/org.eclipse.jdt.ui.prefs
+++ b/chi/org.eclipse.escet.chi.codegen/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/chi/org.eclipse.escet.chi.codegen/.settings/org.eclipse.ltk.core.refactoring.prefs b/chi/org.eclipse.escet.chi.codegen/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/chi/org.eclipse.escet.chi.codegen/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/chi/org.eclipse.escet.chi.codegen/META-INF/MANIFEST.MF b/chi/org.eclipse.escet.chi.codegen/META-INF/MANIFEST.MF
index 7580b572c72cf119a6fd9a10695ad1929c4c9bd9..2c80c8269b29f46cd5f83189e45e701863bda870 100644
--- a/chi/org.eclipse.escet.chi.codegen/META-INF/MANIFEST.MF
+++ b/chi/org.eclipse.escet.chi.codegen/META-INF/MANIFEST.MF
@@ -2,16 +2,16 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Chi Java Code Generator (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.chi.codegen;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
-Require-Bundle: org.eclipse.escet.chi.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.chi.metamodel.java;bundle-version="0.9.0",
- org.eclipse.escet.common.box;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.chi.typecheck;bundle-version="0.9.0",
- org.eclipse.escet.common.position.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.chi.runtime;bundle-version="0.9.0",
- org.eclipse.escet.common.position.common;bundle-version="0.9.0"
+Require-Bundle: org.eclipse.escet.chi.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.chi.metamodel.java;bundle-version="0.10.0",
+ org.eclipse.escet.common.box;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.chi.typecheck;bundle-version="0.10.0",
+ org.eclipse.escet.common.position.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.chi.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.common.position.common;bundle-version="0.10.0"
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Export-Package: org.eclipse.escet.chi.codegen,
diff --git a/chi/org.eclipse.escet.chi.documentation.utils/.settings/org.eclipse.jdt.core.prefs b/chi/org.eclipse.escet.chi.documentation.utils/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/chi/org.eclipse.escet.chi.documentation.utils/.settings/org.eclipse.jdt.core.prefs
+++ b/chi/org.eclipse.escet.chi.documentation.utils/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/chi/org.eclipse.escet.chi.documentation.utils/.settings/org.eclipse.jdt.ui.prefs b/chi/org.eclipse.escet.chi.documentation.utils/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/chi/org.eclipse.escet.chi.documentation.utils/.settings/org.eclipse.jdt.ui.prefs
+++ b/chi/org.eclipse.escet.chi.documentation.utils/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/chi/org.eclipse.escet.chi.documentation.utils/.settings/org.eclipse.ltk.core.refactoring.prefs b/chi/org.eclipse.escet.chi.documentation.utils/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/chi/org.eclipse.escet.chi.documentation.utils/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/chi/org.eclipse.escet.chi.documentation.utils/META-INF/MANIFEST.MF b/chi/org.eclipse.escet.chi.documentation.utils/META-INF/MANIFEST.MF
index ede7c2ecc7333e60187615b7335a7edcf82ea6de..428ac99f67cc63730077abb54a5602038e49d947 100644
--- a/chi/org.eclipse.escet.chi.documentation.utils/META-INF/MANIFEST.MF
+++ b/chi/org.eclipse.escet.chi.documentation.utils/META-INF/MANIFEST.MF
@@ -2,11 +2,11 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Chi Documentation Utils (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.chi.documentation.utils;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Automatic-Module-Name: org.eclipse.escet.chi.documentation.utils
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
 Require-Bundle: org.apache.commons.math3;bundle-version="3.5.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0"
+ org.eclipse.escet.common.java;bundle-version="0.10.0"
 Export-Package: org.eclipse.escet.chi.documentation.utils
diff --git a/chi/org.eclipse.escet.chi.documentation/META-INF/MANIFEST.MF b/chi/org.eclipse.escet.chi.documentation/META-INF/MANIFEST.MF
index 383218273855e5398659fc0434b469773f01e327..852d470b7e28d87c722fb70f523b03c45121dd27 100644
--- a/chi/org.eclipse.escet.chi.documentation/META-INF/MANIFEST.MF
+++ b/chi/org.eclipse.escet.chi.documentation/META-INF/MANIFEST.MF
@@ -2,6 +2,6 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Chi Documentation (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.chi.documentation;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Require-Bundle: org.eclipse.help
diff --git a/chi/org.eclipse.escet.chi.documentation/asciidoc/documentation.asciidoc b/chi/org.eclipse.escet.chi.documentation/asciidoc/documentation.asciidoc
index 60f09c7250f971aad9e7497cc3c5d014a8c86d7b..57d1477519a07dc9f230e64b7641fab2352f6459 100644
--- a/chi/org.eclipse.escet.chi.documentation/asciidoc/documentation.asciidoc
+++ b/chi/org.eclipse.escet.chi.documentation/asciidoc/documentation.asciidoc
@@ -30,7 +30,7 @@ It uses a process-based view, and uses synchronous point-to-point communication
 A process is written as an imperative program, with a syntax much inspired by the well-known Python language.
 
 Chi is one of the tools of the Eclipse ESCET(TM) project.
-Visit the link:https://eclipse.org/escet/{escet-website-version}[project website] for downloads, installation instructions, source code, general tool usage information, information on how to contribute, and more.
+Visit the link:https://eclipse.dev/escet/{escet-website-version}[project website] for downloads, installation instructions, source code, general tool usage information, information on how to contribute, and more.
 
 [WARNING]
 ====
diff --git a/chi/org.eclipse.escet.chi.documentation/asciidoc/release-notes.asciidoc b/chi/org.eclipse.escet.chi.documentation/asciidoc/release-notes.asciidoc
index 2a0d7c0ab58eb77fa3eb0b1c7a9e880a34bd6680..ca1e2553a50722e26638735978f09352b162619d 100644
--- a/chi/org.eclipse.escet.chi.documentation/asciidoc/release-notes.asciidoc
+++ b/chi/org.eclipse.escet.chi.documentation/asciidoc/release-notes.asciidoc
@@ -20,7 +20,16 @@ indexterm:[release, notes]
 
 The release notes for the versions of Chi and the associated tools, as part of the Eclipse ESCET project, are listed below in reverse chronological order.
 
-See also the Eclipse ESCET link:https://eclipse.org/escet/{escet-website-version}/release-notes.html[toolkit release notes] covering those aspects that are common to the various Eclipse ESCET tools.
+See also the Eclipse ESCET link:https://eclipse.dev/escet/{escet-website-version}/release-notes.html[toolkit release notes] covering those aspects that are common to the various Eclipse ESCET tools.
+
+=== Version 0.10
+
+TBD
+
+Improvements and fixes:
+
+* The Chi simulator's SVG visualizer _Save as_ dialog now properly starts in the directory that contains the SVG file, also on Windows.
+And it now properly handles paths with spaces and other special characters in them (issue {escet-issue}221[#221]).
 
 === Version 0.9 (2023-03-31)
 
diff --git a/chi/org.eclipse.escet.chi.documentation/build-docs-chi.launch b/chi/org.eclipse.escet.chi.documentation/build-docs-chi.launch
index 2ad9ddb1e0028d897237e38d197917abfee5b133..6e8e0bb40ef6b2d1f721f1e36d699add13c72b5f 100644
--- a/chi/org.eclipse.escet.chi.documentation/build-docs-chi.launch
+++ b/chi/org.eclipse.escet.chi.documentation/build-docs-chi.launch
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <launchConfiguration type="org.eclipse.m2e.Maven2LaunchConfigurationType">
+    <intAttribute key="M2_COLORS" value="0"/>
     <booleanAttribute key="M2_DEBUG_OUTPUT" value="false"/>
     <stringAttribute key="M2_GOALS" value="clean package --projects releng/org.eclipse.escet.releng.target,chi/org.eclipse.escet.chi.documentation --also-make"/>
     <booleanAttribute key="M2_NON_RECURSIVE" value="false"/>
@@ -15,6 +16,7 @@
     <booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="true"/>
     <stringAttribute key="M2_USER_SETTINGS" value=""/>
     <booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="false"/>
+    <booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
     <stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${workspace}"/>
     <mapAttribute key="org.eclipse.debug.core.environmentVariables">
         <mapEntry key="JAVA_HOME" value="${system_property:java.home}"/>
diff --git a/chi/org.eclipse.escet.chi.documentation/pom.xml b/chi/org.eclipse.escet.chi.documentation/pom.xml
index 8d6e1df306fbf9f584ad41048520aa4992e30e3a..8cc75e68b18854038a42ddcee3bd1e6629a4610d 100644
--- a/chi/org.eclipse.escet.chi.documentation/pom.xml
+++ b/chi/org.eclipse.escet.chi.documentation/pom.xml
@@ -16,7 +16,7 @@
     <parent>
         <groupId>org.eclipse.escet</groupId>
         <artifactId>org.eclipse.escet.root</artifactId>
-        <version>0.9.0-SNAPSHOT</version>
+        <version>0.10.0-SNAPSHOT</version>
         <relativePath>../../</relativePath>
     </parent>
 
diff --git a/chi/org.eclipse.escet.chi.feature/feature.xml b/chi/org.eclipse.escet.chi.feature/feature.xml
index d637dbba8cc80c58707e0ccc781f26f50eb025a7..b1f9065d44ea3f864cb15a17207d300f7079b4ff 100644
--- a/chi/org.eclipse.escet.chi.feature/feature.xml
+++ b/chi/org.eclipse.escet.chi.feature/feature.xml
@@ -13,11 +13,11 @@
 <feature
       id="org.eclipse.escet.chi.feature"
       label="ESCET Chi (Incubation)"
-      version="0.9.0.qualifier"
+      version="0.10.0.qualifier"
       provider-name="Eclipse ESCET"
       plugin="org.eclipse.escet.product.branding"
       license-feature="org.eclipse.escet.releng.license.mit"
-      license-feature-version="0.9.0.qualifier">
+      license-feature-version="0.10.0.qualifier">
 
    <description>
       Eclipse ESCET tooling for the Chi language.
@@ -32,8 +32,8 @@
    </license>
 
    <requires>
-      <import feature="org.eclipse.escet.common.feature" version="0.9.0.qualifier"/>
-      <import feature="org.eclipse.escet.setext.feature" version="0.9.0.qualifier"/>
+      <import feature="org.eclipse.escet.common.feature" version="0.10.0.qualifier"/>
+      <import feature="org.eclipse.escet.setext.feature" version="0.10.0.qualifier"/>
       <import plugin="org.apache.commons.math3"/>
    </requires>
 
diff --git a/chi/org.eclipse.escet.chi.metamodel.java/.settings/org.eclipse.jdt.core.prefs b/chi/org.eclipse.escet.chi.metamodel.java/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/chi/org.eclipse.escet.chi.metamodel.java/.settings/org.eclipse.jdt.core.prefs
+++ b/chi/org.eclipse.escet.chi.metamodel.java/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/chi/org.eclipse.escet.chi.metamodel.java/.settings/org.eclipse.jdt.ui.prefs b/chi/org.eclipse.escet.chi.metamodel.java/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/chi/org.eclipse.escet.chi.metamodel.java/.settings/org.eclipse.jdt.ui.prefs
+++ b/chi/org.eclipse.escet.chi.metamodel.java/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/chi/org.eclipse.escet.chi.metamodel.java/.settings/org.eclipse.ltk.core.refactoring.prefs b/chi/org.eclipse.escet.chi.metamodel.java/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/chi/org.eclipse.escet.chi.metamodel.java/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/chi/org.eclipse.escet.chi.metamodel.java/META-INF/MANIFEST.MF b/chi/org.eclipse.escet.chi.metamodel.java/META-INF/MANIFEST.MF
index 70511c3edd8f83dc0d4335ec1d081091bb7890ad..aba8a2f506c740398a03dfe1961f93400d168fdb 100644
--- a/chi/org.eclipse.escet.chi.metamodel.java/META-INF/MANIFEST.MF
+++ b/chi/org.eclipse.escet.chi.metamodel.java/META-INF/MANIFEST.MF
@@ -2,10 +2,10 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Chi Java Model Constructors (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.chi.metamodel.java;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
-Require-Bundle: org.eclipse.escet.chi.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.common.position.metamodel;bundle-version="0.9.0"
+Require-Bundle: org.eclipse.escet.chi.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.common.position.metamodel;bundle-version="0.10.0"
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
 Export-Package: org.eclipse.escet.chi.metamodel.java
diff --git a/chi/org.eclipse.escet.chi.metamodel/.settings/org.eclipse.jdt.core.prefs b/chi/org.eclipse.escet.chi.metamodel/.settings/org.eclipse.jdt.core.prefs
index a39882dc615f390c7a829a2c18eb7f17ffd8668b..eabbae9d848583c4a9412f97a7c7b9c9b344ef90 100644
--- a/chi/org.eclipse.escet.chi.metamodel/.settings/org.eclipse.jdt.core.prefs
+++ b/chi/org.eclipse.escet.chi.metamodel/.settings/org.eclipse.jdt.core.prefs
@@ -126,6 +126,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/chi/org.eclipse.escet.chi.metamodel/.settings/org.eclipse.ltk.core.refactoring.prefs b/chi/org.eclipse.escet.chi.metamodel/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/chi/org.eclipse.escet.chi.metamodel/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/chi/org.eclipse.escet.chi.metamodel/META-INF/MANIFEST.MF b/chi/org.eclipse.escet.chi.metamodel/META-INF/MANIFEST.MF
index 8ba3cd781aefbfc5ad528f550a03bc3c64a32657..87ef52cdae45660a65bc0daa72577ff8e54b4597 100644
--- a/chi/org.eclipse.escet.chi.metamodel/META-INF/MANIFEST.MF
+++ b/chi/org.eclipse.escet.chi.metamodel/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.escet.chi.metamodel;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-ClassPath: .
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
@@ -12,7 +12,7 @@ Export-Package: org.eclipse.escet.chi.metamodel.chi,
  org.eclipse.escet.chi.metamodel.chi.util
 Require-Bundle: org.eclipse.core.runtime;bundle-version="3.17.0",
  org.eclipse.emf.ecore;bundle-version="2.20.0";visibility:=reexport,
- org.eclipse.escet.common.position.metamodel;bundle-version="0.9.0";visibility:=reexport,
- org.eclipse.escet.common.emf.ecore.xmi;bundle-version="0.9.0"
+ org.eclipse.escet.common.position.metamodel;bundle-version="0.10.0";visibility:=reexport,
+ org.eclipse.escet.common.emf.ecore.xmi;bundle-version="0.10.0"
 Bundle-ActivationPolicy: lazy
 Automatic-Module-Name: org.eclipse.escet.chi.metamodel
diff --git a/chi/org.eclipse.escet.chi.metamodel/docs/chi_ecore_doc.bib b/chi/org.eclipse.escet.chi.metamodel/docs/chi_ecore_doc.bib
index a5c85eaf4c01aaf33e0b05fe119dc08930063af5..3398d6edd105256f2612fa4940b5472fc80b384e 100644
--- a/chi/org.eclipse.escet.chi.metamodel/docs/chi_ecore_doc.bib
+++ b/chi/org.eclipse.escet.chi.metamodel/docs/chi_ecore_doc.bib
@@ -1,7 +1,7 @@
 @misc{Eclipse:ESCET,
   author = {Contributors to the Eclipse Foundation},
   title = {{Eclipse Supervisory Control Engineering Toolkit (Eclipse ESCET)}},
-  howpublished = {\url{https://eclipse.org/escet}}
+  howpublished = {\url{https://eclipse.dev/escet}}
 }
 
 @misc{Eclipse:Incubation,
diff --git a/chi/org.eclipse.escet.chi.metamodel/docs/chi_ecore_doc.pdf b/chi/org.eclipse.escet.chi.metamodel/docs/chi_ecore_doc.pdf
index 518b234151a022869baca557431856472e3f3066..02cbaa3b81bf43233eb83c856712146b9aa8e1da 100644
Binary files a/chi/org.eclipse.escet.chi.metamodel/docs/chi_ecore_doc.pdf and b/chi/org.eclipse.escet.chi.metamodel/docs/chi_ecore_doc.pdf differ
diff --git a/chi/org.eclipse.escet.chi.metamodel/docs/chi_ecore_doc.tex b/chi/org.eclipse.escet.chi.metamodel/docs/chi_ecore_doc.tex
index 68f34f1f4eef28bd612383a731d865fbbedf4598..2904c7218d4bc90e1d68e29813115f98a19a27ce 100644
--- a/chi/org.eclipse.escet.chi.metamodel/docs/chi_ecore_doc.tex
+++ b/chi/org.eclipse.escet.chi.metamodel/docs/chi_ecore_doc.tex
@@ -43,7 +43,7 @@
 
 \title{Chi Metamodel Reference Documentation (Incubation)}
 \author{Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation}
-\date{Version 2021-10-19}
+\date{Version 2023-05-05}
 \titlepic{\includegraphics[width=0.5\textwidth]{figures/eclipse-incubation.png}}
 
 \begin{document}
diff --git a/chi/org.eclipse.escet.chi.parser/.settings/org.eclipse.jdt.core.prefs b/chi/org.eclipse.escet.chi.parser/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/chi/org.eclipse.escet.chi.parser/.settings/org.eclipse.jdt.core.prefs
+++ b/chi/org.eclipse.escet.chi.parser/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/chi/org.eclipse.escet.chi.parser/.settings/org.eclipse.jdt.ui.prefs b/chi/org.eclipse.escet.chi.parser/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/chi/org.eclipse.escet.chi.parser/.settings/org.eclipse.jdt.ui.prefs
+++ b/chi/org.eclipse.escet.chi.parser/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/chi/org.eclipse.escet.chi.parser/.settings/org.eclipse.ltk.core.refactoring.prefs b/chi/org.eclipse.escet.chi.parser/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/chi/org.eclipse.escet.chi.parser/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/chi/org.eclipse.escet.chi.parser/META-INF/MANIFEST.MF b/chi/org.eclipse.escet.chi.parser/META-INF/MANIFEST.MF
index 5866c3b54abc5d12e43670594f8e5020cfeaebbb..e37869dee41bdb487920d92b40185bbf10dccfb0 100644
--- a/chi/org.eclipse.escet.chi.parser/META-INF/MANIFEST.MF
+++ b/chi/org.eclipse.escet.chi.parser/META-INF/MANIFEST.MF
@@ -2,15 +2,15 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Chi Parser (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.chi.parser;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
-Require-Bundle: org.eclipse.escet.chi.metamodel.java;bundle-version="0.9.0",
- org.eclipse.escet.chi.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.common.emf;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.common.position.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
- org.eclipse.escet.common.position.common;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.chi.metamodel.java;bundle-version="0.10.0",
+ org.eclipse.escet.chi.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.common.emf;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.common.position.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.common.position.common;bundle-version="0.10.0",
  org.eclipse.jface.text;bundle-version="3.16.100"
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
diff --git a/chi/org.eclipse.escet.chi.runtime/.settings/org.eclipse.jdt.core.prefs b/chi/org.eclipse.escet.chi.runtime/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/chi/org.eclipse.escet.chi.runtime/.settings/org.eclipse.jdt.core.prefs
+++ b/chi/org.eclipse.escet.chi.runtime/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/chi/org.eclipse.escet.chi.runtime/.settings/org.eclipse.jdt.ui.prefs b/chi/org.eclipse.escet.chi.runtime/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/chi/org.eclipse.escet.chi.runtime/.settings/org.eclipse.jdt.ui.prefs
+++ b/chi/org.eclipse.escet.chi.runtime/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/chi/org.eclipse.escet.chi.runtime/.settings/org.eclipse.ltk.core.refactoring.prefs b/chi/org.eclipse.escet.chi.runtime/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/chi/org.eclipse.escet.chi.runtime/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/chi/org.eclipse.escet.chi.runtime/META-INF/MANIFEST.MF b/chi/org.eclipse.escet.chi.runtime/META-INF/MANIFEST.MF
index 88afa84e1bafc22af37d9aa5479f76262a134a85..77a47facbfdee932b76b4f3ca620cc92fad27337 100644
--- a/chi/org.eclipse.escet.chi.runtime/META-INF/MANIFEST.MF
+++ b/chi/org.eclipse.escet.chi.runtime/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Chi Runtime (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.chi.runtime;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Export-Package: org.eclipse.escet.chi.runtime,
@@ -10,11 +10,11 @@ Export-Package: org.eclipse.escet.chi.runtime,
  org.eclipse.escet.chi.runtime.data.io,
  org.eclipse.escet.chi.runtime.data.random
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
  org.apache.commons.math3;bundle-version="3.5.0",
- org.eclipse.escet.common.svg;bundle-version="0.9.0",
- org.eclipse.escet.common.eclipse.ui;bundle-version="0.9.0",
+ org.eclipse.escet.common.svg;bundle-version="0.10.0",
+ org.eclipse.escet.common.eclipse.ui;bundle-version="0.10.0",
  org.w3c.dom.svg;bundle-version="1.1.0",
  org.apache.batik.bridge;bundle-version="1.14.0",
  org.apache.commons.lang3;bundle-version="3.1.0"
diff --git a/chi/org.eclipse.escet.chi.simulator.ui/.settings/org.eclipse.jdt.core.prefs b/chi/org.eclipse.escet.chi.simulator.ui/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/chi/org.eclipse.escet.chi.simulator.ui/.settings/org.eclipse.jdt.core.prefs
+++ b/chi/org.eclipse.escet.chi.simulator.ui/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/chi/org.eclipse.escet.chi.simulator.ui/.settings/org.eclipse.jdt.ui.prefs b/chi/org.eclipse.escet.chi.simulator.ui/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/chi/org.eclipse.escet.chi.simulator.ui/.settings/org.eclipse.jdt.ui.prefs
+++ b/chi/org.eclipse.escet.chi.simulator.ui/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/chi/org.eclipse.escet.chi.simulator.ui/.settings/org.eclipse.ltk.core.refactoring.prefs b/chi/org.eclipse.escet.chi.simulator.ui/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/chi/org.eclipse.escet.chi.simulator.ui/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/chi/org.eclipse.escet.chi.simulator.ui/META-INF/MANIFEST.MF b/chi/org.eclipse.escet.chi.simulator.ui/META-INF/MANIFEST.MF
index af86ac5ca3b82306af7c4d9fcdf2b41410ed9377..84fffe8c6d7fa720f4bf6c6e483f8c427d74dad6 100644
--- a/chi/org.eclipse.escet.chi.simulator.ui/META-INF/MANIFEST.MF
+++ b/chi/org.eclipse.escet.chi.simulator.ui/META-INF/MANIFEST.MF
@@ -2,13 +2,13 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Chi Simulator UI (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.chi.simulator.ui;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Require-Bundle: org.eclipse.core.resources;bundle-version="3.13.600",
- org.eclipse.escet.common.eclipse.ui;bundle-version="0.9.0",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.chi.simulator;bundle-version="0.9.0",
+ org.eclipse.escet.common.eclipse.ui;bundle-version="0.10.0",
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.chi.simulator;bundle-version="0.10.0",
  org.eclipse.jface.text;bundle-version="3.16.100"
 Bundle-ActivationPolicy: lazy
 Automatic-Module-Name: org.eclipse.escet.chi.simulator.ui
diff --git a/chi/org.eclipse.escet.chi.simulator/.settings/org.eclipse.jdt.core.prefs b/chi/org.eclipse.escet.chi.simulator/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/chi/org.eclipse.escet.chi.simulator/.settings/org.eclipse.jdt.core.prefs
+++ b/chi/org.eclipse.escet.chi.simulator/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/chi/org.eclipse.escet.chi.simulator/.settings/org.eclipse.jdt.ui.prefs b/chi/org.eclipse.escet.chi.simulator/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/chi/org.eclipse.escet.chi.simulator/.settings/org.eclipse.jdt.ui.prefs
+++ b/chi/org.eclipse.escet.chi.simulator/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/chi/org.eclipse.escet.chi.simulator/.settings/org.eclipse.ltk.core.refactoring.prefs b/chi/org.eclipse.escet.chi.simulator/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/chi/org.eclipse.escet.chi.simulator/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/chi/org.eclipse.escet.chi.simulator/META-INF/MANIFEST.MF b/chi/org.eclipse.escet.chi.simulator/META-INF/MANIFEST.MF
index 4cd71d19352ccfb0773b85726049310b5c0c056d..a4fb043620159ec9af84e90f54662d41b54fb13e 100644
--- a/chi/org.eclipse.escet.chi.simulator/META-INF/MANIFEST.MF
+++ b/chi/org.eclipse.escet.chi.simulator/META-INF/MANIFEST.MF
@@ -2,24 +2,24 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Chi Simulator (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.chi.simulator;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Export-Package: org.eclipse.escet.chi.simulator,
  org.eclipse.escet.chi.simulator.options
-Require-Bundle: org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.chi.runtime;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.chi.runtime;bundle-version="0.10.0",
  org.apache.commons.math3;bundle-version="3.5.0",
- org.eclipse.escet.chi.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.chi.parser;bundle-version="0.9.0",
- org.eclipse.escet.chi.typecheck;bundle-version="0.9.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
+ org.eclipse.escet.chi.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.chi.parser;bundle-version="0.10.0",
+ org.eclipse.escet.chi.typecheck;bundle-version="0.10.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
  org.eclipse.emf.ecore;bundle-version="2.20.0",
- org.eclipse.escet.chi.codegen;bundle-version="0.9.0",
- org.eclipse.escet.common.box;bundle-version="0.9.0",
+ org.eclipse.escet.chi.codegen;bundle-version="0.10.0",
+ org.eclipse.escet.common.box;bundle-version="0.10.0",
  org.eclipse.core.runtime;bundle-version="3.17.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
  org.eclipse.ui;bundle-version="3.115.0"
 Bundle-ActivationPolicy: lazy
 Automatic-Module-Name: org.eclipse.escet.chi.simulator
diff --git a/chi/org.eclipse.escet.chi.tests/.settings/org.eclipse.jdt.core.prefs b/chi/org.eclipse.escet.chi.tests/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/chi/org.eclipse.escet.chi.tests/.settings/org.eclipse.jdt.core.prefs
+++ b/chi/org.eclipse.escet.chi.tests/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/chi/org.eclipse.escet.chi.tests/.settings/org.eclipse.jdt.ui.prefs b/chi/org.eclipse.escet.chi.tests/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/chi/org.eclipse.escet.chi.tests/.settings/org.eclipse.jdt.ui.prefs
+++ b/chi/org.eclipse.escet.chi.tests/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/chi/org.eclipse.escet.chi.tests/.settings/org.eclipse.ltk.core.refactoring.prefs b/chi/org.eclipse.escet.chi.tests/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/chi/org.eclipse.escet.chi.tests/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/chi/org.eclipse.escet.chi.tests/META-INF/MANIFEST.MF b/chi/org.eclipse.escet.chi.tests/META-INF/MANIFEST.MF
index cd9da89a6b5228a41f66a47d04513b3639f119a0..5f5be1cb6db3e28f1a3a61136de608da4f6aad00 100644
--- a/chi/org.eclipse.escet.chi.tests/META-INF/MANIFEST.MF
+++ b/chi/org.eclipse.escet.chi.tests/META-INF/MANIFEST.MF
@@ -2,14 +2,14 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Chi Tests (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.chi.tests;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
 Require-Bundle: org.junit;bundle-version="4.12.0",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.tooldef.interpreter;bundle-version="0.9.0",
- org.eclipse.escet.chi.simulator;bundle-version="0.9.0",
- org.eclipse.escet.chi.tooldefs;bundle-version="0.9.0"
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.tooldef.interpreter;bundle-version="0.10.0",
+ org.eclipse.escet.chi.simulator;bundle-version="0.10.0",
+ org.eclipse.escet.chi.tooldefs;bundle-version="0.10.0"
 Export-Package: org.eclipse.escet.chi.tests
 Automatic-Module-Name: org.eclipse.escet.chi.tests
diff --git a/chi/org.eclipse.escet.chi.texteditor/.settings/org.eclipse.jdt.core.prefs b/chi/org.eclipse.escet.chi.texteditor/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/chi/org.eclipse.escet.chi.texteditor/.settings/org.eclipse.jdt.core.prefs
+++ b/chi/org.eclipse.escet.chi.texteditor/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/chi/org.eclipse.escet.chi.texteditor/.settings/org.eclipse.jdt.ui.prefs b/chi/org.eclipse.escet.chi.texteditor/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/chi/org.eclipse.escet.chi.texteditor/.settings/org.eclipse.jdt.ui.prefs
+++ b/chi/org.eclipse.escet.chi.texteditor/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/chi/org.eclipse.escet.chi.texteditor/.settings/org.eclipse.ltk.core.refactoring.prefs b/chi/org.eclipse.escet.chi.texteditor/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/chi/org.eclipse.escet.chi.texteditor/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/chi/org.eclipse.escet.chi.texteditor/META-INF/MANIFEST.MF b/chi/org.eclipse.escet.chi.texteditor/META-INF/MANIFEST.MF
index eb5aa973c5311814da59958fd56cebf3e079b7be..a2ce4b259507556022289b0f8396c817080d6891 100644
--- a/chi/org.eclipse.escet.chi.texteditor/META-INF/MANIFEST.MF
+++ b/chi/org.eclipse.escet.chi.texteditor/META-INF/MANIFEST.MF
@@ -2,23 +2,23 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Chi Text Editor (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.chi.texteditor;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.chi.parser;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.chi.parser;bundle-version="0.10.0",
  org.eclipse.jface.text;bundle-version="3.16.100",
- org.eclipse.escet.common.eclipse.ui;bundle-version="0.9.0",
- org.eclipse.escet.chi.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.chi.typecheck;bundle-version="0.9.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.common.position.metamodel;bundle-version="0.9.0",
+ org.eclipse.escet.common.eclipse.ui;bundle-version="0.10.0",
+ org.eclipse.escet.chi.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.chi.typecheck;bundle-version="0.10.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.common.position.metamodel;bundle-version="0.10.0",
  org.eclipse.core.resources;bundle-version="3.13.600",
  org.eclipse.ui.editors;bundle-version="3.13.0",
- org.eclipse.escet.setext.texteditorbase;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
+ org.eclipse.escet.setext.texteditorbase;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
  org.eclipse.ui.ide;bundle-version="3.18.200",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0"
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0"
 Automatic-Module-Name: org.eclipse.escet.chi.texteditor
 Export-Package: org.eclipse.escet.chi.texteditor
diff --git a/chi/org.eclipse.escet.chi.tooldefs/.settings/org.eclipse.jdt.core.prefs b/chi/org.eclipse.escet.chi.tooldefs/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/chi/org.eclipse.escet.chi.tooldefs/.settings/org.eclipse.jdt.core.prefs
+++ b/chi/org.eclipse.escet.chi.tooldefs/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/chi/org.eclipse.escet.chi.tooldefs/.settings/org.eclipse.jdt.ui.prefs b/chi/org.eclipse.escet.chi.tooldefs/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/chi/org.eclipse.escet.chi.tooldefs/.settings/org.eclipse.jdt.ui.prefs
+++ b/chi/org.eclipse.escet.chi.tooldefs/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/chi/org.eclipse.escet.chi.tooldefs/.settings/org.eclipse.ltk.core.refactoring.prefs b/chi/org.eclipse.escet.chi.tooldefs/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/chi/org.eclipse.escet.chi.tooldefs/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/chi/org.eclipse.escet.chi.tooldefs/META-INF/MANIFEST.MF b/chi/org.eclipse.escet.chi.tooldefs/META-INF/MANIFEST.MF
index 2070fe7763ab022c188e09c82ad9b7d181b08083..869c2a1ea6c67500498ba957a015cab477a175c9 100644
--- a/chi/org.eclipse.escet.chi.tooldefs/META-INF/MANIFEST.MF
+++ b/chi/org.eclipse.escet.chi.tooldefs/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Chi ToolDefs (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.chi.tooldefs;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
diff --git a/chi/org.eclipse.escet.chi.typecheck/.settings/org.eclipse.jdt.core.prefs b/chi/org.eclipse.escet.chi.typecheck/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/chi/org.eclipse.escet.chi.typecheck/.settings/org.eclipse.jdt.core.prefs
+++ b/chi/org.eclipse.escet.chi.typecheck/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/chi/org.eclipse.escet.chi.typecheck/.settings/org.eclipse.jdt.ui.prefs b/chi/org.eclipse.escet.chi.typecheck/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/chi/org.eclipse.escet.chi.typecheck/.settings/org.eclipse.jdt.ui.prefs
+++ b/chi/org.eclipse.escet.chi.typecheck/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/chi/org.eclipse.escet.chi.typecheck/.settings/org.eclipse.ltk.core.refactoring.prefs b/chi/org.eclipse.escet.chi.typecheck/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/chi/org.eclipse.escet.chi.typecheck/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/chi/org.eclipse.escet.chi.typecheck/META-INF/MANIFEST.MF b/chi/org.eclipse.escet.chi.typecheck/META-INF/MANIFEST.MF
index a0d82f74e4e987a84b56354f343e0bf5280a2d60..b723aca8294769ca61f3040727f3b448faf08b78 100644
--- a/chi/org.eclipse.escet.chi.typecheck/META-INF/MANIFEST.MF
+++ b/chi/org.eclipse.escet.chi.typecheck/META-INF/MANIFEST.MF
@@ -2,16 +2,16 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Chi Type Checker (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.chi.typecheck;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
-Require-Bundle: org.eclipse.escet.chi.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.chi.metamodel.java;bundle-version="0.9.0",
- org.eclipse.escet.common.emf;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.common.position.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.common.position.common;bundle-version="0.9.0"
+Require-Bundle: org.eclipse.escet.chi.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.chi.metamodel.java;bundle-version="0.10.0",
+ org.eclipse.escet.common.emf;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.common.position.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.common.position.common;bundle-version="0.10.0"
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
 Export-Package: org.eclipse.escet.chi.typecheck,
diff --git a/cif/org.eclipse.escet.cif.checkers/.settings/org.eclipse.jdt.core.prefs b/cif/org.eclipse.escet.cif.checkers/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/cif/org.eclipse.escet.cif.checkers/.settings/org.eclipse.jdt.core.prefs
+++ b/cif/org.eclipse.escet.cif.checkers/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/cif/org.eclipse.escet.cif.checkers/.settings/org.eclipse.jdt.ui.prefs b/cif/org.eclipse.escet.cif.checkers/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/cif/org.eclipse.escet.cif.checkers/.settings/org.eclipse.jdt.ui.prefs
+++ b/cif/org.eclipse.escet.cif.checkers/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/cif/org.eclipse.escet.cif.checkers/.settings/org.eclipse.ltk.core.refactoring.prefs b/cif/org.eclipse.escet.cif.checkers/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.checkers/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/cif/org.eclipse.escet.cif.checkers/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.checkers/META-INF/MANIFEST.MF
index d93849a222ed43dd05c01e20973e22fd4c71e379..4ab377aedc65018361df1566162433612446da3c 100644
--- a/cif/org.eclipse.escet.cif.checkers/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.checkers/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET CIF Checkers (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.cif.checkers;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Automatic-Module-Name: org.eclipse.escet.cif.checkers
 Bundle-RequiredExecutionEnvironment: JavaSE-17
@@ -10,17 +10,17 @@ Bundle-ActivationPolicy: lazy
 Export-Package: org.eclipse.escet.cif.common.checkers,
  org.eclipse.escet.cif.common.checkers.checks,
  org.eclipse.escet.cif.common.checkers.checks.invcheck
-Require-Bundle: org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.cif.common;bundle-version="0.9.0",
- org.eclipse.escet.common.position.common;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel.java;bundle-version="0.9.0",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.cif.prettyprinter;bundle-version="0.9.0",
- org.eclipse.escet.common.box;bundle-version="0.9.0",
- org.eclipse.escet.cif.parser;bundle-version="0.9.0",
- org.eclipse.escet.cif.io;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
- org.eclipse.escet.cif.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.common.emf;bundle-version="0.9.0"
+Require-Bundle: org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.cif.common;bundle-version="0.10.0",
+ org.eclipse.escet.common.position.common;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel.java;bundle-version="0.10.0",
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.cif.prettyprinter;bundle-version="0.10.0",
+ org.eclipse.escet.common.box;bundle-version="0.10.0",
+ org.eclipse.escet.cif.parser;bundle-version="0.10.0",
+ org.eclipse.escet.cif.io;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.cif.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.common.emf;bundle-version="0.10.0"
diff --git a/cif/org.eclipse.escet.cif.cif2cif.app/.settings/org.eclipse.jdt.core.prefs b/cif/org.eclipse.escet.cif.cif2cif.app/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/cif/org.eclipse.escet.cif.cif2cif.app/.settings/org.eclipse.jdt.core.prefs
+++ b/cif/org.eclipse.escet.cif.cif2cif.app/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/cif/org.eclipse.escet.cif.cif2cif.app/.settings/org.eclipse.jdt.ui.prefs b/cif/org.eclipse.escet.cif.cif2cif.app/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/cif/org.eclipse.escet.cif.cif2cif.app/.settings/org.eclipse.jdt.ui.prefs
+++ b/cif/org.eclipse.escet.cif.cif2cif.app/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/cif/org.eclipse.escet.cif.cif2cif.app/.settings/org.eclipse.ltk.core.refactoring.prefs b/cif/org.eclipse.escet.cif.cif2cif.app/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.cif2cif.app/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/cif/org.eclipse.escet.cif.cif2cif.app/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.cif2cif.app/META-INF/MANIFEST.MF
index cf78ebc7051912fdd8a645bcf6f0814ce56ad85f..56eb96fcaccc11ec2e9c26ce2fe6b45e60ee2632 100644
--- a/cif/org.eclipse.escet.cif.cif2cif.app/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.cif2cif.app/META-INF/MANIFEST.MF
@@ -2,22 +2,22 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET CIF to CIF Transformation Applications (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.cif.cif2cif.app;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Export-Package: org.eclipse.escet.cif.cif2cif.app
 Bundle-ActivationPolicy: lazy
 Bundle-Vendor: Eclipse ESCET
 Require-Bundle: org.eclipse.core.resources;bundle-version="3.13.600",
- org.eclipse.escet.common.eclipse.ui;bundle-version="0.9.0",
- org.eclipse.escet.cif.io;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.cif.cif2cif;bundle-version="0.9.0",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel.java;bundle-version="0.9.0",
- org.eclipse.escet.cif.parser;bundle-version="0.9.0",
- org.eclipse.escet.cif.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
- org.eclipse.escet.cif.common;bundle-version="0.9.0"
+ org.eclipse.escet.common.eclipse.ui;bundle-version="0.10.0",
+ org.eclipse.escet.cif.io;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.cif.cif2cif;bundle-version="0.10.0",
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel.java;bundle-version="0.10.0",
+ org.eclipse.escet.cif.parser;bundle-version="0.10.0",
+ org.eclipse.escet.cif.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.cif.common;bundle-version="0.10.0"
 Automatic-Module-Name: org.eclipse.escet.cif.cif2cif.app
diff --git a/cif/org.eclipse.escet.cif.cif2cif/.settings/org.eclipse.jdt.core.prefs b/cif/org.eclipse.escet.cif.cif2cif/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/cif/org.eclipse.escet.cif.cif2cif/.settings/org.eclipse.jdt.core.prefs
+++ b/cif/org.eclipse.escet.cif.cif2cif/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/cif/org.eclipse.escet.cif.cif2cif/.settings/org.eclipse.jdt.ui.prefs b/cif/org.eclipse.escet.cif.cif2cif/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/cif/org.eclipse.escet.cif.cif2cif/.settings/org.eclipse.jdt.ui.prefs
+++ b/cif/org.eclipse.escet.cif.cif2cif/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/cif/org.eclipse.escet.cif.cif2cif/.settings/org.eclipse.ltk.core.refactoring.prefs b/cif/org.eclipse.escet.cif.cif2cif/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.cif2cif/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/cif/org.eclipse.escet.cif.cif2cif/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.cif2cif/META-INF/MANIFEST.MF
index 65593abc931218fd012ff00821fa31bf314194f2..0be4adcc57ac1ff686789211687db76ae24121e9 100644
--- a/cif/org.eclipse.escet.cif.cif2cif/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.cif2cif/META-INF/MANIFEST.MF
@@ -2,17 +2,17 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET CIF to CIF Transformations (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.cif.cif2cif;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.cif.metamodel.java;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.cif.common;bundle-version="0.9.0",
- org.eclipse.escet.common.emf;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.cif.metamodel.java;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.cif.common;bundle-version="0.10.0",
+ org.eclipse.escet.common.emf;bundle-version="0.10.0",
  org.apache.commons.lang3;bundle-version="3.1.0",
- org.eclipse.escet.common.position.common;bundle-version="0.9.0"
+ org.eclipse.escet.common.position.common;bundle-version="0.10.0"
 Export-Package: org.eclipse.escet.cif.cif2cif
 Automatic-Module-Name: org.eclipse.escet.cif.cif2cif
diff --git a/cif/org.eclipse.escet.cif.cif2cif/src/org/eclipse/escet/cif/cif2cif/MergeEnums.java b/cif/org.eclipse.escet.cif.cif2cif/src/org/eclipse/escet/cif/cif2cif/MergeEnums.java
index 0fcd2107a19e06ee51d77672c9a1b2bbbb96de8b..63e3cbc48425d3e5e004e664bd68db112e74db12 100644
--- a/cif/org.eclipse.escet.cif.cif2cif/src/org/eclipse/escet/cif/cif2cif/MergeEnums.java
+++ b/cif/org.eclipse.escet.cif.cif2cif/src/org/eclipse/escet/cif/cif2cif/MergeEnums.java
@@ -16,6 +16,7 @@ package org.eclipse.escet.cif.cif2cif;
 import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newEnumDecl;
 import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newEnumLiteral;
 import static org.eclipse.escet.common.app.framework.output.OutputProvider.warn;
+import static org.eclipse.escet.common.java.Lists.last;
 import static org.eclipse.escet.common.java.Maps.map;
 import static org.eclipse.escet.common.java.Sets.sortedstrings;
 
@@ -33,6 +34,8 @@ import org.eclipse.escet.cif.metamodel.cif.declarations.Declaration;
 import org.eclipse.escet.cif.metamodel.cif.declarations.EnumDecl;
 import org.eclipse.escet.cif.metamodel.cif.declarations.EnumLiteral;
 import org.eclipse.escet.cif.metamodel.cif.expressions.EnumLiteralExpression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.SwitchCase;
+import org.eclipse.escet.cif.metamodel.cif.expressions.SwitchExpression;
 import org.eclipse.escet.cif.metamodel.cif.types.EnumType;
 import org.eclipse.escet.cif.metamodel.java.CifWalker;
 
@@ -54,6 +57,12 @@ import org.eclipse.escet.cif.metamodel.java.CifWalker;
  * multiple enumerations, and compatibility is thus not an issue.
  * </p>
  *
+ * <p>
+ * All switch expressions that switch over a value that has a type that includes an enumeration type, but do not have an
+ * 'else', may become incomplete by merging enumerations. Therefore, for any such switch expression, its last 'case' is
+ * converted to an 'else'. The key of that last 'case' is thereby removed from the model.
+ * </p>
+ *
  * @see EnumsToInts
  * @see EnumsToConsts
  */
@@ -189,4 +198,17 @@ public class MergeEnums extends CifWalker implements CifToCifTransformation {
         // Replace enumeration declaration reference.
         enumType.setEnum(mergedEnum);
     }
+
+    @Override
+    protected void postprocessSwitchExpression(SwitchExpression switchExpr) {
+        // Make switch expression complete by changing last 'case' into an 'else', in case it may have become
+        // incomplete. Only switch expressions with a value type that includes an enumeration type may have become
+        // incomplete.
+        if (CifTypeUtils.hasEnumType(switchExpr.getValue().getType())) {
+            SwitchCase lastCase = last(switchExpr.getCases());
+            if (lastCase.getKey() != null) {
+                lastCase.setKey(null);
+            }
+        }
+    }
 }
diff --git a/cif/org.eclipse.escet.cif.cif2mcrl2/.settings/org.eclipse.jdt.core.prefs b/cif/org.eclipse.escet.cif.cif2mcrl2/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/cif/org.eclipse.escet.cif.cif2mcrl2/.settings/org.eclipse.jdt.core.prefs
+++ b/cif/org.eclipse.escet.cif.cif2mcrl2/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/cif/org.eclipse.escet.cif.cif2mcrl2/.settings/org.eclipse.jdt.ui.prefs b/cif/org.eclipse.escet.cif.cif2mcrl2/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/cif/org.eclipse.escet.cif.cif2mcrl2/.settings/org.eclipse.jdt.ui.prefs
+++ b/cif/org.eclipse.escet.cif.cif2mcrl2/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/cif/org.eclipse.escet.cif.cif2mcrl2/.settings/org.eclipse.ltk.core.refactoring.prefs b/cif/org.eclipse.escet.cif.cif2mcrl2/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.cif2mcrl2/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/cif/org.eclipse.escet.cif.cif2mcrl2/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.cif2mcrl2/META-INF/MANIFEST.MF
index d8311633ba18222bb5916fa524288e5f82bd2622..36cd4711dab0e041a0150d1cec37067a6d58bd4e 100644
--- a/cif/org.eclipse.escet.cif.cif2mcrl2/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.cif2mcrl2/META-INF/MANIFEST.MF
@@ -2,25 +2,25 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET CIF to mCRL2 Translation (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.cif.cif2mcrl2;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Require-Bundle: org.eclipse.ui;bundle-version="3.115.0",
  org.eclipse.core.runtime;bundle-version="3.17.0",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.cif.io;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
- org.eclipse.escet.cif.parser;bundle-version="0.9.0",
- org.eclipse.escet.cif.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.cif.io;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.cif.parser;bundle-version="0.10.0",
+ org.eclipse.escet.cif.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
  org.eclipse.core.resources;bundle-version="3.13.600",
- org.eclipse.escet.common.eclipse.ui;bundle-version="0.9.0",
- org.eclipse.escet.cif.cif2cif;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel.java;bundle-version="0.9.0",
- org.eclipse.escet.cif.common;bundle-version="0.9.0",
+ org.eclipse.escet.common.eclipse.ui;bundle-version="0.10.0",
+ org.eclipse.escet.cif.cif2cif;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel.java;bundle-version="0.10.0",
+ org.eclipse.escet.cif.common;bundle-version="0.10.0",
  org.apache.commons.lang3;bundle-version="3.1.0",
- org.eclipse.escet.common.box;bundle-version="0.9.0"
+ org.eclipse.escet.common.box;bundle-version="0.10.0"
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
 Export-Package: org.eclipse.escet.cif.cif2mcrl2,
diff --git a/cif/org.eclipse.escet.cif.cif2plc/.settings/org.eclipse.jdt.core.prefs b/cif/org.eclipse.escet.cif.cif2plc/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/cif/org.eclipse.escet.cif.cif2plc/.settings/org.eclipse.jdt.core.prefs
+++ b/cif/org.eclipse.escet.cif.cif2plc/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/cif/org.eclipse.escet.cif.cif2plc/.settings/org.eclipse.jdt.ui.prefs b/cif/org.eclipse.escet.cif.cif2plc/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/cif/org.eclipse.escet.cif.cif2plc/.settings/org.eclipse.jdt.ui.prefs
+++ b/cif/org.eclipse.escet.cif.cif2plc/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/cif/org.eclipse.escet.cif.cif2plc/.settings/org.eclipse.ltk.core.refactoring.prefs b/cif/org.eclipse.escet.cif.cif2plc/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.cif2plc/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/cif/org.eclipse.escet.cif.cif2plc/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.cif2plc/META-INF/MANIFEST.MF
index b22a3f15ad553b1ec40ff772b113b4cd3e0cce86..c0986a442a5aab7e074597be11a58a2ce5465924 100644
--- a/cif/org.eclipse.escet.cif.cif2plc/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.cif2plc/META-INF/MANIFEST.MF
@@ -2,25 +2,25 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET CIF PLC Code Generator (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.cif.cif2plc;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
 Require-Bundle: org.eclipse.core.resources;bundle-version="3.13.600",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.common.eclipse.ui;bundle-version="0.9.0",
- org.eclipse.escet.cif.cif2cif;bundle-version="0.9.0",
- org.eclipse.escet.cif.common;bundle-version="0.9.0",
- org.eclipse.escet.cif.io;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.cif.parser;bundle-version="0.9.0",
- org.eclipse.escet.cif.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel.java;bundle-version="0.9.0",
- org.eclipse.escet.common.box;bundle-version="0.9.0",
- org.eclipse.escet.common.emf;bundle-version="0.9.0",
- org.eclipse.escet.cif.checkers;bundle-version="0.9.0"
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.common.eclipse.ui;bundle-version="0.10.0",
+ org.eclipse.escet.cif.cif2cif;bundle-version="0.10.0",
+ org.eclipse.escet.cif.common;bundle-version="0.10.0",
+ org.eclipse.escet.cif.io;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.cif.parser;bundle-version="0.10.0",
+ org.eclipse.escet.cif.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel.java;bundle-version="0.10.0",
+ org.eclipse.escet.common.box;bundle-version="0.10.0",
+ org.eclipse.escet.common.emf;bundle-version="0.10.0",
+ org.eclipse.escet.cif.checkers;bundle-version="0.10.0"
 Export-Package: org.eclipse.escet.cif.cif2plc,
  org.eclipse.escet.cif.cif2plc.options,
  org.eclipse.escet.cif.cif2plc.plcdata,
diff --git a/cif/org.eclipse.escet.cif.cif2supremica/.settings/org.eclipse.jdt.core.prefs b/cif/org.eclipse.escet.cif.cif2supremica/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/cif/org.eclipse.escet.cif.cif2supremica/.settings/org.eclipse.jdt.core.prefs
+++ b/cif/org.eclipse.escet.cif.cif2supremica/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/cif/org.eclipse.escet.cif.cif2supremica/.settings/org.eclipse.jdt.ui.prefs b/cif/org.eclipse.escet.cif.cif2supremica/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/cif/org.eclipse.escet.cif.cif2supremica/.settings/org.eclipse.jdt.ui.prefs
+++ b/cif/org.eclipse.escet.cif.cif2supremica/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/cif/org.eclipse.escet.cif.cif2supremica/.settings/org.eclipse.ltk.core.refactoring.prefs b/cif/org.eclipse.escet.cif.cif2supremica/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.cif2supremica/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/cif/org.eclipse.escet.cif.cif2supremica/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.cif2supremica/META-INF/MANIFEST.MF
index 684f255683c5f56905e2f34aae2445c3165860dd..adb7bafc7f6260d4879174d523db5b28461795ab 100644
--- a/cif/org.eclipse.escet.cif.cif2supremica/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.cif2supremica/META-INF/MANIFEST.MF
@@ -2,24 +2,24 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET CIF to Supremica Transformation (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.cif.cif2supremica;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
 Bundle-Vendor: Eclipse ESCET
-Require-Bundle: org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.cif.cif2cif;bundle-version="0.9.0",
- org.eclipse.escet.cif.common;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.cif.io;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
- org.eclipse.escet.cif.parser;bundle-version="0.9.0",
- org.eclipse.escet.cif.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel.java;bundle-version="0.9.0",
- org.eclipse.escet.common.emf;bundle-version="0.9.0",
- org.eclipse.escet.common.eclipse.ui;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.cif.cif2cif;bundle-version="0.10.0",
+ org.eclipse.escet.cif.common;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.cif.io;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.cif.parser;bundle-version="0.10.0",
+ org.eclipse.escet.cif.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel.java;bundle-version="0.10.0",
+ org.eclipse.escet.common.emf;bundle-version="0.10.0",
+ org.eclipse.escet.common.eclipse.ui;bundle-version="0.10.0",
  org.eclipse.core.resources;bundle-version="3.13.600",
- org.eclipse.escet.cif.checkers;bundle-version="0.9.0"
+ org.eclipse.escet.cif.checkers;bundle-version="0.10.0"
 Export-Package: org.eclipse.escet.cif.cif2supremica
 Automatic-Module-Name: org.eclipse.escet.cif.cif2supremica
diff --git a/cif/org.eclipse.escet.cif.cif2uppaal/.settings/org.eclipse.jdt.core.prefs b/cif/org.eclipse.escet.cif.cif2uppaal/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/cif/org.eclipse.escet.cif.cif2uppaal/.settings/org.eclipse.jdt.core.prefs
+++ b/cif/org.eclipse.escet.cif.cif2uppaal/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/cif/org.eclipse.escet.cif.cif2uppaal/.settings/org.eclipse.jdt.ui.prefs b/cif/org.eclipse.escet.cif.cif2uppaal/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/cif/org.eclipse.escet.cif.cif2uppaal/.settings/org.eclipse.jdt.ui.prefs
+++ b/cif/org.eclipse.escet.cif.cif2uppaal/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/cif/org.eclipse.escet.cif.cif2uppaal/.settings/org.eclipse.ltk.core.refactoring.prefs b/cif/org.eclipse.escet.cif.cif2uppaal/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.cif2uppaal/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/cif/org.eclipse.escet.cif.cif2uppaal/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.cif2uppaal/META-INF/MANIFEST.MF
index 2f5b4195a6ab27927d4afc5bf8e30777812dc891..9b08f10e0b464edc5f5ae5f5b0593878e74d53d5 100644
--- a/cif/org.eclipse.escet.cif.cif2uppaal/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.cif2uppaal/META-INF/MANIFEST.MF
@@ -2,24 +2,24 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET CIF to UPPAAL Transformation (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.cif.cif2uppaal;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.common.eclipse.ui;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.common.eclipse.ui;bundle-version="0.10.0",
  org.eclipse.core.resources;bundle-version="3.13.600",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.cif.io;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
- org.eclipse.escet.cif.parser;bundle-version="0.9.0",
- org.eclipse.escet.cif.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.cif.common;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel.java;bundle-version="0.9.0",
- org.eclipse.escet.cif.cif2cif;bundle-version="0.9.0",
- org.eclipse.escet.common.box;bundle-version="0.9.0",
- org.eclipse.escet.cif.checkers;bundle-version="0.9.0"
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.cif.io;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.cif.parser;bundle-version="0.10.0",
+ org.eclipse.escet.cif.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.cif.common;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel.java;bundle-version="0.10.0",
+ org.eclipse.escet.cif.cif2cif;bundle-version="0.10.0",
+ org.eclipse.escet.common.box;bundle-version="0.10.0",
+ org.eclipse.escet.cif.checkers;bundle-version="0.10.0"
 Automatic-Module-Name: org.eclipse.escet.cif.cif2uppaal
 Export-Package: org.eclipse.escet.cif.cif2uppaal
diff --git a/cif/org.eclipse.escet.cif.cif2yed/.settings/org.eclipse.jdt.core.prefs b/cif/org.eclipse.escet.cif.cif2yed/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/cif/org.eclipse.escet.cif.cif2yed/.settings/org.eclipse.jdt.core.prefs
+++ b/cif/org.eclipse.escet.cif.cif2yed/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/cif/org.eclipse.escet.cif.cif2yed/.settings/org.eclipse.jdt.ui.prefs b/cif/org.eclipse.escet.cif.cif2yed/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/cif/org.eclipse.escet.cif.cif2yed/.settings/org.eclipse.jdt.ui.prefs
+++ b/cif/org.eclipse.escet.cif.cif2yed/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/cif/org.eclipse.escet.cif.cif2yed/.settings/org.eclipse.ltk.core.refactoring.prefs b/cif/org.eclipse.escet.cif.cif2yed/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.cif2yed/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/cif/org.eclipse.escet.cif.cif2yed/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.cif2yed/META-INF/MANIFEST.MF
index 67006c7c3acff09bcea9b8161f560055435afa74..2b6679a36ae537a5968a9e501c6b95137775714f 100644
--- a/cif/org.eclipse.escet.cif.cif2yed/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.cif2yed/META-INF/MANIFEST.MF
@@ -2,28 +2,28 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET CIF to yEd Transformer (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.cif.cif2yed;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
 Bundle-Vendor: Eclipse ESCET
 Require-Bundle: org.eclipse.core.resources;bundle-version="3.13.600",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.cif.io;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.cif.parser;bundle-version="0.9.0",
- org.eclipse.escet.cif.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.common.eclipse.ui;bundle-version="0.9.0",
- org.eclipse.escet.cif.common;bundle-version="0.9.0",
- org.eclipse.escet.common.box;bundle-version="0.9.0",
- org.eclipse.escet.cif.prettyprinter;bundle-version="0.9.0",
- org.eclipse.escet.cif.texteditor;bundle-version="0.9.0",
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.cif.io;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.cif.parser;bundle-version="0.10.0",
+ org.eclipse.escet.cif.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.common.eclipse.ui;bundle-version="0.10.0",
+ org.eclipse.escet.cif.common;bundle-version="0.10.0",
+ org.eclipse.escet.common.box;bundle-version="0.10.0",
+ org.eclipse.escet.cif.prettyprinter;bundle-version="0.10.0",
+ org.eclipse.escet.cif.texteditor;bundle-version="0.10.0",
  org.eclipse.jface.text;bundle-version="3.16.100",
- org.eclipse.escet.setext.texteditorbase;bundle-version="0.9.0",
+ org.eclipse.escet.setext.texteditorbase;bundle-version="0.10.0",
  org.apache.commons.lang3;bundle-version="3.1.0",
- org.eclipse.escet.cif.metamodel.java;bundle-version="0.9.0"
+ org.eclipse.escet.cif.metamodel.java;bundle-version="0.10.0"
 Automatic-Module-Name: org.eclipse.escet.cif.cif2yed
 Export-Package: org.eclipse.escet.cif.cif2yed,
  org.eclipse.escet.cif.cif2yed.options
diff --git a/cif/org.eclipse.escet.cif.codegen/.settings/org.eclipse.jdt.core.prefs b/cif/org.eclipse.escet.cif.codegen/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/cif/org.eclipse.escet.cif.codegen/.settings/org.eclipse.jdt.core.prefs
+++ b/cif/org.eclipse.escet.cif.codegen/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/cif/org.eclipse.escet.cif.codegen/.settings/org.eclipse.jdt.ui.prefs b/cif/org.eclipse.escet.cif.codegen/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/cif/org.eclipse.escet.cif.codegen/.settings/org.eclipse.jdt.ui.prefs
+++ b/cif/org.eclipse.escet.cif.codegen/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/cif/org.eclipse.escet.cif.codegen/.settings/org.eclipse.ltk.core.refactoring.prefs b/cif/org.eclipse.escet.cif.codegen/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.codegen/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/cif/org.eclipse.escet.cif.codegen/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.codegen/META-INF/MANIFEST.MF
index e927e9b332cf026b590bb190e3c52994d8b5c1ee..d2117b764b39e6033b868e2d13b5d982687fbed6 100644
--- a/cif/org.eclipse.escet.cif.codegen/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.codegen/META-INF/MANIFEST.MF
@@ -2,25 +2,25 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET CIF Code Generator (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.cif.codegen;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.cif.common;bundle-version="0.9.0",
- org.eclipse.escet.cif.io;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.cif.parser;bundle-version="0.9.0",
- org.eclipse.escet.cif.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.common.eclipse.ui;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.cif.common;bundle-version="0.10.0",
+ org.eclipse.escet.cif.io;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.cif.parser;bundle-version="0.10.0",
+ org.eclipse.escet.cif.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.common.eclipse.ui;bundle-version="0.10.0",
  org.eclipse.core.resources;bundle-version="3.13.600",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.cif.cif2cif;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel.java;bundle-version="0.9.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.cif.cif2cif;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel.java;bundle-version="0.10.0",
  org.apache.commons.io;bundle-version="2.6.0",
- org.eclipse.escet.common.box;bundle-version="0.9.0",
- org.eclipse.escet.common.emf;bundle-version="0.9.0"
+ org.eclipse.escet.common.box;bundle-version="0.10.0",
+ org.eclipse.escet.common.emf;bundle-version="0.10.0"
 Bundle-Vendor: Eclipse ESCET
 Export-Package: org.eclipse.escet.cif.codegen,
  org.eclipse.escet.cif.codegen.assignments,
diff --git a/cif/org.eclipse.escet.cif.common/.settings/org.eclipse.jdt.core.prefs b/cif/org.eclipse.escet.cif.common/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/cif/org.eclipse.escet.cif.common/.settings/org.eclipse.jdt.core.prefs
+++ b/cif/org.eclipse.escet.cif.common/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/cif/org.eclipse.escet.cif.common/.settings/org.eclipse.jdt.ui.prefs b/cif/org.eclipse.escet.cif.common/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/cif/org.eclipse.escet.cif.common/.settings/org.eclipse.jdt.ui.prefs
+++ b/cif/org.eclipse.escet.cif.common/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/cif/org.eclipse.escet.cif.common/.settings/org.eclipse.ltk.core.refactoring.prefs b/cif/org.eclipse.escet.cif.common/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.common/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/cif/org.eclipse.escet.cif.common/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.common/META-INF/MANIFEST.MF
index b0dbf1c097f83aac3fb19cd608294c13a2f22691..ca167fa9f4fbfe91325b8ccac16451d7b309c13f 100644
--- a/cif/org.eclipse.escet.cif.common/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.common/META-INF/MANIFEST.MF
@@ -2,18 +2,18 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET CIF Common (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.cif.common;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
 Export-Package: org.eclipse.escet.cif.common
-Require-Bundle: org.eclipse.escet.cif.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel.java;bundle-version="0.9.0",
- org.eclipse.escet.cif.parser;bundle-version="0.9.0",
- org.eclipse.escet.common.emf;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.cif.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel.java;bundle-version="0.10.0",
+ org.eclipse.escet.cif.parser;bundle-version="0.10.0",
+ org.eclipse.escet.common.emf;bundle-version="0.10.0",
  org.apache.commons.lang3;bundle-version="3.1.0",
  org.apache.commons.math3;bundle-version="3.5.0",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.common.position.common;bundle-version="0.9.0"
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.common.position.common;bundle-version="0.10.0"
 Automatic-Module-Name: org.eclipse.escet.cif.common
diff --git a/cif/org.eclipse.escet.cif.common/src/org/eclipse/escet/cif/common/CifTypeUtils.java b/cif/org.eclipse.escet.cif.common/src/org/eclipse/escet/cif/common/CifTypeUtils.java
index 0686a2f4857e75b56a3dfcc0063f40007f1ba2b2..4915b8afe8ed0d48a003380bdb09c9ba8f37159a 100644
--- a/cif/org.eclipse.escet.cif.common/src/org/eclipse/escet/cif/common/CifTypeUtils.java
+++ b/cif/org.eclipse.escet.cif.common/src/org/eclipse/escet/cif/common/CifTypeUtils.java
@@ -932,6 +932,102 @@ public class CifTypeUtils {
         throw new RuntimeException("Unknown type: " + type);
     }
 
+    /**
+     * Does the given type have an enumeration type, either directly, or indirectly?
+     *
+     * @param type The CIF type to check.
+     * @return {@code true} if the CIF type has an enumeration type, {@code false} otherwise.
+     */
+    public static boolean hasEnumType(CifType type) {
+        if (type instanceof BoolType) {
+            return false;
+        }
+        if (type instanceof IntType) {
+            return false;
+        }
+
+        if (type instanceof TypeRef) {
+            return hasEnumType(((TypeRef)type).getType().getType());
+        }
+
+        if (type instanceof EnumType) {
+            return true;
+        }
+        if (type instanceof RealType) {
+            return false;
+        }
+        if (type instanceof StringType) {
+            return false;
+        }
+
+        if (type instanceof ListType) {
+            return hasEnumType(((ListType)type).getElementType());
+        }
+
+        if (type instanceof SetType) {
+            return hasEnumType(((SetType)type).getElementType());
+        }
+
+        if (type instanceof FuncType) {
+            FuncType ftype = (FuncType)type;
+            if (hasEnumType(ftype.getReturnType())) {
+                return true;
+            }
+            for (CifType paramType: ftype.getParamTypes()) {
+                if (hasEnumType(paramType)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        if (type instanceof DictType) {
+            DictType dtype = (DictType)type;
+            return hasEnumType(dtype.getKeyType()) || hasEnumType(dtype.getValueType());
+        }
+
+        if (type instanceof TupleType) {
+            TupleType ttype = (TupleType)type;
+            for (Field field: ttype.getFields()) {
+                if (hasEnumType(field.getType())) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        if (type instanceof DistType) {
+            return false;
+        }
+
+        if (type instanceof ComponentDefType) {
+            return false;
+        }
+        if (type instanceof ComponentType) {
+            return false;
+        }
+
+        if (type instanceof CompInstWrapType) {
+            // Just peel of the wrapper. We don't care about how we reach a
+            // type, but only what type we reach.
+            CompInstWrapType wrapper = (CompInstWrapType)type;
+            return hasEnumType(wrapper.getReference());
+        }
+
+        if (type instanceof CompParamWrapType) {
+            // Just peel of the wrapper. We don't care about how we reach a
+            // type, but only what type we reach.
+            CompParamWrapType wrapper = (CompParamWrapType)type;
+            return hasEnumType(wrapper.getReference());
+        }
+
+        if (type instanceof VoidType) {
+            return false;
+        }
+
+        throw new RuntimeException("Unknown type: " + type);
+    }
+
     /**
      * Merges two compatible types to get the union of both types. Note that:
      * <ul>
diff --git a/cif/org.eclipse.escet.cif.common/src/org/eclipse/escet/cif/common/CifValueUtils.java b/cif/org.eclipse.escet.cif.common/src/org/eclipse/escet/cif/common/CifValueUtils.java
index d95eadd52f0da7a28f1964d953460b142e034607..ff5a9a636c69b3098af0664d49d3db2c5499c712 100644
--- a/cif/org.eclipse.escet.cif.common/src/org/eclipse/escet/cif/common/CifValueUtils.java
+++ b/cif/org.eclipse.escet.cif.common/src/org/eclipse/escet/cif/common/CifValueUtils.java
@@ -264,9 +264,9 @@ public class CifValueUtils {
      * depending on the run-time state of the system.
      *
      * <p>
-     * Note that this method is more liberal than the {@code CifTypeChecker.checkStaticEvaluable} method, as the type
-     * checker does not allow static evaluation of algebraic variables, while this method allows it if the algebraic
-     * variable has a single value.
+     * Note that this method is more liberal than the {@code CifExprsTypeChecker.checkStaticEvaluable} method, as the
+     * type checker does not allow static evaluation of algebraic variables, while this method allows it if the
+     * algebraic variable has a single value.
      * </p>
      *
      * <p>
@@ -2342,8 +2342,7 @@ public class CifValueUtils {
             try {
                 idx = (Integer)CifEvalUtils.eval(iexpr, false);
             } catch (CifEvalException e) {
-                // This expression should be statically evaluable, as
-                // checked by the type checker.
+                // This expression should be statically evaluable, as checked by the type checker.
                 throw new RuntimeException(e);
             }
 
@@ -2353,6 +2352,29 @@ public class CifValueUtils {
         }
     }
 
+    /**
+     * Returns the index of the field being projected in a tuple projection.
+     *
+     * @param pexpr The tuple projection expression.
+     * @return The index of the field being projected.
+     */
+    public static int getTupleProjIndex(ProjectionExpression pexpr) {
+        TupleType tupType = (TupleType)normalizeType(pexpr.getChild().getType());
+        Expression indexExpr = pexpr.getIndex();
+
+        if (indexExpr instanceof FieldExpression fe) {
+            return tupType.getFields().indexOf(fe.getField());
+        } else {
+            // Evaluate index.
+            try {
+                return (int)CifEvalUtils.eval(indexExpr, false);
+            } catch (CifEvalException e) {
+                // This expression should be statically evaluable, as checked by the type checker.
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
     /**
      * Returns the possible number of unique values for the given type.
      *
diff --git a/cif/org.eclipse.escet.cif.controllercheck/.settings/org.eclipse.jdt.core.prefs b/cif/org.eclipse.escet.cif.controllercheck/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/cif/org.eclipse.escet.cif.controllercheck/.settings/org.eclipse.jdt.core.prefs
+++ b/cif/org.eclipse.escet.cif.controllercheck/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/cif/org.eclipse.escet.cif.controllercheck/.settings/org.eclipse.jdt.ui.prefs b/cif/org.eclipse.escet.cif.controllercheck/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/cif/org.eclipse.escet.cif.controllercheck/.settings/org.eclipse.jdt.ui.prefs
+++ b/cif/org.eclipse.escet.cif.controllercheck/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/cif/org.eclipse.escet.cif.controllercheck/.settings/org.eclipse.ltk.core.refactoring.prefs b/cif/org.eclipse.escet.cif.controllercheck/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.controllercheck/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/cif/org.eclipse.escet.cif.controllercheck/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.controllercheck/META-INF/MANIFEST.MF
index c86e579ec4c31010aa99b7ce84578cc1c42876bb..590b4f87870dcbc5eb0c59c76b21de48d281f8c7 100644
--- a/cif/org.eclipse.escet.cif.controllercheck/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.controllercheck/META-INF/MANIFEST.MF
@@ -2,26 +2,26 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Controller Checker (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.cif.controllercheck;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.cif.cif2cif;bundle-version="0.9.0",
- org.eclipse.escet.cif.io;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
- org.eclipse.escet.cif.parser;bundle-version="0.9.0",
- org.eclipse.escet.cif.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.cif.cif2cif;bundle-version="0.10.0",
+ org.eclipse.escet.cif.io;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.cif.parser;bundle-version="0.10.0",
+ org.eclipse.escet.cif.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
  org.eclipse.core.resources;bundle-version="3.14.0",
- org.eclipse.escet.common.eclipse.ui;bundle-version="0.9.0",
- org.eclipse.escet.cif.common;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel.java;bundle-version="0.9.0",
- org.eclipse.escet.common.position.common;bundle-version="0.9.0",
- org.eclipse.escet.common.multivaluetrees;bundle-version="0.9.0",
- org.eclipse.escet.common.emf;bundle-version="0.9.0"
+ org.eclipse.escet.common.eclipse.ui;bundle-version="0.10.0",
+ org.eclipse.escet.cif.common;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel.java;bundle-version="0.10.0",
+ org.eclipse.escet.common.position.common;bundle-version="0.10.0",
+ org.eclipse.escet.common.multivaluetrees;bundle-version="0.10.0",
+ org.eclipse.escet.common.emf;bundle-version="0.10.0"
 Export-Package: org.eclipse.escet.cif.controllercheck,
  org.eclipse.escet.cif.controllercheck.confluence,
  org.eclipse.escet.cif.controllercheck.finiteresponse,
diff --git a/cif/org.eclipse.escet.cif.controllercheck/src/org/eclipse/escet/cif/controllercheck/finiteresponse/EventLoopSearch.java b/cif/org.eclipse.escet.cif.controllercheck/src/org/eclipse/escet/cif/controllercheck/finiteresponse/EventLoopSearch.java
index a9e4c6ec8a59fe7415cf7c84e2afb2cfd7c45a2d..7e428f37b5165197836a7ace66c38e674708b350 100644
--- a/cif/org.eclipse.escet.cif.controllercheck/src/org/eclipse/escet/cif/controllercheck/finiteresponse/EventLoopSearch.java
+++ b/cif/org.eclipse.escet.cif.controllercheck/src/org/eclipse/escet/cif/controllercheck/finiteresponse/EventLoopSearch.java
@@ -14,15 +14,13 @@
 package org.eclipse.escet.cif.controllercheck.finiteresponse;
 
 import static org.eclipse.escet.cif.common.CifEventUtils.getEvents;
+import static org.eclipse.escet.common.java.Lists.list;
 import static org.eclipse.escet.common.java.Lists.listc;
-import static org.eclipse.escet.common.java.Maps.mapc;
 import static org.eclipse.escet.common.java.Sets.isEmptyIntersection;
-import static org.eclipse.escet.common.java.Sets.set;
-import static org.eclipse.escet.common.java.Sets.setc;
 
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
+import java.util.function.BooleanSupplier;
 
 import org.eclipse.escet.cif.common.CifEdgeUtils;
 import org.eclipse.escet.cif.metamodel.cif.automata.Automaton;
@@ -30,8 +28,11 @@ import org.eclipse.escet.cif.metamodel.cif.automata.Edge;
 import org.eclipse.escet.cif.metamodel.cif.automata.Location;
 import org.eclipse.escet.cif.metamodel.cif.declarations.Event;
 import org.eclipse.escet.common.app.framework.AppEnvData;
+import org.eclipse.escet.common.java.DirectedGraphCycleFinder;
+import org.eclipse.escet.common.java.DirectedGraphCycleFinder.GraphEdge;
+import org.eclipse.escet.common.java.ListProductIterator;
 
-/** Static class with loop finding functions, based on Tarjan's strongly connected component algorithm. */
+/** Static class for finding event loops. */
 public class EventLoopSearch {
     /** Constructor of the static {@link EventLoopSearch} class. */
     private EventLoopSearch() {
@@ -49,105 +50,87 @@ public class EventLoopSearch {
      * @return The event loops in the specified automaton.
      */
     public static Set<EventLoop> searchEventLoops(Automaton aut, Set<Event> loopEvents, AppEnvData env) {
-        // Stack stores all the edges that we traverse, when searching for loops.
-        List<Event> stack = listc(aut.getLocations().size() + 1);
-
-        // Every location that is visited is stored together with its position in the stack, such
-        // that we can determine if a location is already visited.
-        Map<Location, Integer> stackIndex = mapc(aut.getLocations().size());
-
-        // Store which locations have been visited. If a location can only be reached from the initial location
-        // with non-loop events, we have to do multiple searchLoopFromLocation.
-        Set<Location> visitedLocations = setc(aut.getLocations().size());
-
-        // Store which loops are found.
-        Set<EventLoop> eventLoops = set();
-        for (Location loc: aut.getLocations()) {
-            if (visitedLocations.contains(loc)) {
-                continue;
-            }
-            searchEventLoops(loc, loopEvents, stackIndex, stack, eventLoops, visitedLocations, env);
-
-            if (env.isTerminationRequested()) {
-                return null;
-            }
-        }
-        return eventLoops;
+        BooleanSupplier isTerminationRequested = () -> env.isTerminationRequested();
+        EventLoopFinder finder = new EventLoopFinder(loopEvents, isTerminationRequested);
+        return finder.findSimpleCycles(aut);
     }
 
-    /**
-     * Searches all event loops reachable from a given location, and saves these in {@code eventLoops}. The events to
-     * search for in the loops can be specified. Warning: only the loops that can be reached by the specified events are
-     * returned.
-     *
-     * @param rootLoc The root location for searching.
-     * @param loopEvents The events that can form a loop (e.g., the controllable events).
-     * @param stackIndex Provides the index for a location on the stack. Modified in place.
-     * @param stack The stack on which the path from the root location to the current location is saved. Modified in
-     *     place.
-     * @param eventLoops The event loops that have been found in the specified automaton. Modified in place.
-     * @param visitedLocations The locations that have been visited at least once when searching for loops. Modified in
-     *     place.
-     * @param env The application context to use.
-     */
-    private static void searchEventLoops(Location rootLoc, Set<Event> loopEvents, Map<Location, Integer> stackIndex,
-            List<Event> stack, Set<EventLoop> eventLoops, Set<Location> visitedLocations, AppEnvData env)
+    /** Cycle finder for finding event loops in an automaton. */
+    public static class EventLoopFinder
+            extends DirectedGraphCycleFinder<Automaton, Location, EventLoopEdge, EventLoop>
     {
-        if (env.isTerminationRequested()) {
-            return;
+        /** The events that can form an event loop. */
+        private final Set<Event> loopEvents;
+
+        /**
+         * Constructor of the {@link EventLoopFinder} class.
+         *
+         * @param loopEvents The events that can form an event loop.
+         * @param isTerminationRequested Test function to detect a user abort request. If {@code null}, termination
+         *     detection is disabled.
+         */
+        public EventLoopFinder(Set<Event> loopEvents, BooleanSupplier isTerminationRequested) {
+            super(isTerminationRequested);
+            this.loopEvents = loopEvents;
         }
 
-        visitedLocations.add(rootLoc);
-
-        // Put the root location on top of the stack.
-        stackIndex.put(rootLoc, stack.size());
+        @Override
+        protected List<Location> getVertices(Automaton graph) {
+            return graph.getLocations();
+        }
 
-        // Consider successors of rootLoc.
-        for (Edge edge: rootLoc.getEdges()) {
-            // Only consider successor reachable via the loop events.
-            if (isEmptyIntersection(loopEvents, getEvents(edge))) {
-                continue;
+        @Override
+        protected void addCycle(List<EventLoopEdge> edges, Set<EventLoop> foundCycles) {
+            // Collect the events of each edge in the cycle.
+            List<List<Event>> eventCollections = listc(edges.size());
+            for (EventLoopEdge edge: edges) {
+                eventCollections.add(edge.events);
             }
 
-            Location edgeTargetLoc = CifEdgeUtils.getTarget(edge);
-            Integer loopStartIndex = stackIndex.get(edgeTargetLoc);
+            // And expand to all combinations of one event for each edge.
+            ListProductIterator<Event> iter = new ListProductIterator<>(eventCollections);
+            while (iter.hasNext()) {
+                List<Event> selectedEvents = iter.next();
+                foundCycles.add(new EventLoop(selectedEvents));
+            }
+        }
 
-            for (Event event: getEvents(edge)) {
-                if (!loopEvents.contains(event)) {
+        @Override
+        protected List<EventLoopEdge> getOutgoingEdges(Location vertex) {
+            List<EventLoopEdge> edges = list();
+            for (Edge edge: vertex.getEdges()) {
+                if (isEmptyIntersection(loopEvents, getEvents(edge))) {
                     continue;
                 }
 
-                if (loopStartIndex == null) {
-                    // A new location has been found.
-                    stack.add(event);
-                    searchEventLoops(edgeTargetLoc, loopEvents, stackIndex, stack, eventLoops, visitedLocations, env);
-                    stack.remove(stack.size() - 1);
-                } else {
-                    // A previously visited location has been found. Thus, we found a loop.
-                    stack.add(event);
-                    eventLoops.add(retrieveLoopFromStack(loopStartIndex, stack));
-                    stack.remove(stack.size() - 1);
-                }
-
-                if (env.isTerminationRequested()) {
-                    return;
+                Location edgeTargetLoc = CifEdgeUtils.getTarget(edge);
+                List<Event> edgeEvents = list();
+                for (Event event: getEvents(edge)) {
+                    if (loopEvents.contains(event)) {
+                        edgeEvents.add(event);
+                    }
+                    edges.add(new EventLoopEdge(vertex, edgeTargetLoc, edgeEvents));
                 }
             }
+            return edges;
         }
-        // Remove the root location from the stack, as we are finished.
-        stackIndex.remove(rootLoc);
     }
 
-    /**
-     * Retrieve the event loop between the specified fromIndex and the top of the supplied stack.
-     *
-     * @param fromIndex The start index of the loop in the stack.
-     * @param stack The stack where the event loop is saved.
-     * @return The event loop on top of the stack.
-     */
-    private static EventLoop retrieveLoopFromStack(Integer fromIndex, List<Event> stack) {
-        List<Event> events = listc(stack.size() - fromIndex);
-        events.addAll(stack.subList(fromIndex, stack.size()));
-        return new EventLoop(events);
+    /** Edge class for finding event loops in an automaton. */
+    private static class EventLoopEdge extends GraphEdge<Location> {
+        /** The events of the edge. */
+        public final List<Event> events;
+
+        /**
+         * Constructor of the {@link EventLoopEdge} class.
+         *
+         * @param startVertex Vertex where the edge leaves.
+         * @param destinationVertex Vertex where the edge arrives.
+         * @param events The events of the edge.
+         */
+        public EventLoopEdge(Location startVertex, Location destinationVertex, List<Event> events) {
+            super(startVertex, destinationVertex);
+            this.events = events;
+        }
     }
 }
diff --git a/cif/org.eclipse.escet.cif.datasynth/.settings/org.eclipse.jdt.core.prefs b/cif/org.eclipse.escet.cif.datasynth/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/cif/org.eclipse.escet.cif.datasynth/.settings/org.eclipse.jdt.core.prefs
+++ b/cif/org.eclipse.escet.cif.datasynth/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/cif/org.eclipse.escet.cif.datasynth/.settings/org.eclipse.jdt.ui.prefs b/cif/org.eclipse.escet.cif.datasynth/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/cif/org.eclipse.escet.cif.datasynth/.settings/org.eclipse.jdt.ui.prefs
+++ b/cif/org.eclipse.escet.cif.datasynth/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/cif/org.eclipse.escet.cif.datasynth/.settings/org.eclipse.ltk.core.refactoring.prefs b/cif/org.eclipse.escet.cif.datasynth/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.datasynth/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/cif/org.eclipse.escet.cif.datasynth/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.datasynth/META-INF/MANIFEST.MF
index b07d500c7bf158f5b047ecfdf6e7107dcb6f5813..3506d0dd4dd59e499d6fd18fceff7a2a81ca004b 100644
--- a/cif/org.eclipse.escet.cif.datasynth/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.datasynth/META-INF/MANIFEST.MF
@@ -2,28 +2,28 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET CIF Data-based Synthesis (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.cif.datasynth;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.cif.io;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
- org.eclipse.escet.cif.parser;bundle-version="0.9.0",
- org.eclipse.escet.cif.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.common.eclipse.ui;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.cif.io;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.cif.parser;bundle-version="0.10.0",
+ org.eclipse.escet.cif.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.common.eclipse.ui;bundle-version="0.10.0",
  org.eclipse.core.resources;bundle-version="3.13.600",
- org.eclipse.escet.cif.metamodel.java;bundle-version="0.9.0",
+ org.eclipse.escet.cif.metamodel.java;bundle-version="0.10.0",
  org.apache.commons.lang3;bundle-version="3.1.0",
- org.eclipse.escet.cif.common;bundle-version="0.9.0",
- org.eclipse.escet.common.emf;bundle-version="0.9.0",
- org.eclipse.escet.cif.cif2cif;bundle-version="0.9.0",
- org.eclipse.escet.common.box;bundle-version="0.9.0",
- com.github.javabdd;bundle-version="4.0.0",
- org.eclipse.jface.text;bundle-version="3.20.100"
+ org.eclipse.escet.cif.common;bundle-version="0.10.0",
+ org.eclipse.escet.common.emf;bundle-version="0.10.0",
+ org.eclipse.escet.cif.cif2cif;bundle-version="0.10.0",
+ org.eclipse.escet.common.box;bundle-version="0.10.0",
+ org.eclipse.jface.text;bundle-version="3.20.100",
+ com.github.com-github-javabdd.com.github.javabdd;bundle-version="5.0.0"
 Export-Package: org.eclipse.escet.cif.datasynth,
  org.eclipse.escet.cif.datasynth.bdd,
  org.eclipse.escet.cif.datasynth.conversion,
diff --git a/cif/org.eclipse.escet.cif.datasynth/src/org/eclipse/escet/cif/datasynth/CifDataSynthesis.java b/cif/org.eclipse.escet.cif.datasynth/src/org/eclipse/escet/cif/datasynth/CifDataSynthesis.java
index 9d3bf0c1ea4dcc51b4aa5b1235ee1be817eb2916..74185df9ba8bac5f3a597799223322725844dc3c 100644
--- a/cif/org.eclipse.escet.cif.datasynth/src/org/eclipse/escet/cif/datasynth/CifDataSynthesis.java
+++ b/cif/org.eclipse.escet.cif.datasynth/src/org/eclipse/escet/cif/datasynth/CifDataSynthesis.java
@@ -1278,7 +1278,9 @@ public class CifDataSynthesis {
                 dbg("Round %d: started.", round);
             }
 
-            // Compute non-blocking predicate from marking (fixed point).
+            // Operation 1: Compute non-blocking predicate from marking.
+
+            // 1a: Perform backward reachability computation (fixed point).
             BDD nonBlock;
             if (doTiming) {
                 timing.mainBwMarked.start();
@@ -1300,7 +1302,7 @@ public class CifDataSynthesis {
                 return;
             }
 
-            // Detect change in controlled behavior.
+            // 1b: Detect change in controlled behavior.
             if (aut.ctrlBeh.equals(nonBlock)) {
                 nonBlock.free();
                 unchanged++;
@@ -1313,7 +1315,7 @@ public class CifDataSynthesis {
                 unchanged = 0;
             }
 
-            // Detect fixed point for main loop.
+            // 1c: Detect fixed point for main loop.
             BDD ctrlStates = aut.ctrlBeh.and(aut.plantInv);
             boolean noCtrlStates = ctrlStates.isZero();
             ctrlStates.free();
@@ -1347,7 +1349,9 @@ public class CifDataSynthesis {
                 return;
             }
 
-            // Compute bad-state predicate from blocking (fixed point).
+            // Operation 2: Compute bad-state predicate from blocking predicate.
+
+            // 2a: Perform backward reachability computation (fixed point).
             BDD badState = aut.ctrlBeh.not();
             if (aut.env.isTerminationRequested()) {
                 return;
@@ -1379,7 +1383,7 @@ public class CifDataSynthesis {
                 return;
             }
 
-            // Detect change in controlled behavior.
+            // 2b: Detect change in controlled behavior.
             if (aut.ctrlBeh.equals(newCtrlBeh)) {
                 newCtrlBeh.free();
                 unchanged++;
@@ -1392,44 +1396,44 @@ public class CifDataSynthesis {
                 unchanged = 0;
             }
 
-            // Optional forward reachability.
-            if (doForward) {
-                // Detect fixed point for main loop.
-                ctrlStates = aut.ctrlBeh.and(aut.plantInv);
-                noCtrlStates = ctrlStates.isZero();
-                ctrlStates.free();
-                if (noCtrlStates) {
-                    if (dbgEnabled) {
-                        dbg();
-                        dbg("Round %d: finished, all states are bad.", round);
-                    }
-                    break;
+            // 2c: Detect fixed point for main loop.
+            ctrlStates = aut.ctrlBeh.and(aut.plantInv);
+            noCtrlStates = ctrlStates.isZero();
+            ctrlStates.free();
+            if (noCtrlStates) {
+                if (dbgEnabled) {
+                    dbg();
+                    dbg("Round %d: finished, all states are bad.", round);
+                }
+                break;
+            }
+            if ((!doForward || round > 1) && unchanged >= stableCount) {
+                if (dbgEnabled) {
+                    dbg();
+                    dbg("Round %d: finished, controlled behavior is stable.", round);
                 }
-                if (round > 1 && unchanged >= stableCount) {
+                break;
+            }
+            if (unchanged == 0) {
+                BDD init = aut.initialCtrl.and(aut.ctrlBeh);
+                boolean noInit = init.isZero();
+                init.free();
+                if (noInit) {
                     if (dbgEnabled) {
                         dbg();
-                        dbg("Round %d: finished, controlled behavior is stable.", round);
+                        dbg("Round %d: finished, no initialization possible.", round);
                     }
                     break;
                 }
-                if (unchanged == 0) {
-                    BDD init = aut.initialCtrl.and(aut.ctrlBeh);
-                    boolean noInit = init.isZero();
-                    init.free();
-                    if (noInit) {
-                        if (dbgEnabled) {
-                            dbg();
-                            dbg("Round %d: finished, no initialization possible.", round);
-                        }
-                        break;
-                    }
-                }
-                if (aut.env.isTerminationRequested()) {
-                    return;
-                }
+            }
+            if (aut.env.isTerminationRequested()) {
+                return;
+            }
 
-                // Compute controlled-behavior predicate from initialization of the controlled system as determined so
-                // far (fixed point).
+            // Operation 3: Optional forward reachability: compute controlled-behavior predicate from initialization of
+            // the controlled system as determined so far.
+            if (doForward) {
+                // 3a: Perform forward reachability computation (fixed point).
                 if (doTiming) {
                     timing.mainFwInit.start();
                 }
@@ -1450,7 +1454,7 @@ public class CifDataSynthesis {
                     return;
                 }
 
-                // Detect change in controlled behavior.
+                // 3b: Detect change in controlled behavior.
                 if (aut.ctrlBeh.equals(newCtrlBeh)) {
                     newCtrlBeh.free();
                     unchanged++;
@@ -1462,40 +1466,29 @@ public class CifDataSynthesis {
                     aut.ctrlBeh = newCtrlBeh;
                     unchanged = 0;
                 }
-            }
 
-            // Detect fixed point for main loop.
-            ctrlStates = aut.ctrlBeh.and(aut.plantInv);
-            noCtrlStates = ctrlStates.isZero();
-            ctrlStates.free();
-            if (noCtrlStates) {
-                if (dbgEnabled) {
-                    dbg();
-                    dbg("Round %d: finished, all states are bad.", round);
-                }
-                break;
-            }
-            if (unchanged >= stableCount) {
-                if (dbgEnabled) {
-                    dbg();
-                    dbg("Round %d: finished, controlled behavior is stable.", round);
+                // 3c: Detect fixed point for main loop.
+                // No need to check the controlled behavior with initialization, as forward reachability starts there.
+                ctrlStates = aut.ctrlBeh.and(aut.plantInv);
+                noCtrlStates = ctrlStates.isZero();
+                ctrlStates.free();
+                if (noCtrlStates) {
+                    if (dbgEnabled) {
+                        dbg();
+                        dbg("Round %d: finished, all states are bad.", round);
+                    }
+                    break;
                 }
-                break;
-            }
-            if (!doForward && unchanged == 0) {
-                BDD init = aut.initialCtrl.and(aut.ctrlBeh);
-                boolean noInit = init.isZero();
-                init.free();
-                if (noInit) {
+                if (unchanged >= stableCount) {
                     if (dbgEnabled) {
                         dbg();
-                        dbg("Round %d: finished, no initialization possible.", round);
+                        dbg("Round %d: finished, controlled behavior is stable.", round);
                     }
                     break;
                 }
-            }
-            if (aut.env.isTerminationRequested()) {
-                return;
+                if (aut.env.isTerminationRequested()) {
+                    return;
+                }
             }
 
             // Finished round.
diff --git a/cif/org.eclipse.escet.cif.datasynth/src/org/eclipse/escet/cif/datasynth/CifDataSynthesisApp.java b/cif/org.eclipse.escet.cif.datasynth/src/org/eclipse/escet/cif/datasynth/CifDataSynthesisApp.java
index 546fe14774cce621bf216162d4e577ec74970342..b322d3090d6b494226ac4fe678177bb7eee67310 100644
--- a/cif/org.eclipse.escet.cif.datasynth/src/org/eclipse/escet/cif/datasynth/CifDataSynthesisApp.java
+++ b/cif/org.eclipse.escet.cif.datasynth/src/org/eclipse/escet/cif/datasynth/CifDataSynthesisApp.java
@@ -44,6 +44,7 @@ import org.eclipse.escet.cif.datasynth.options.BddSlidingWindowSizeOption;
 import org.eclipse.escet.cif.datasynth.options.BddSlidingWindowVarOrderOption;
 import org.eclipse.escet.cif.datasynth.options.BddVariableOrderOption;
 import org.eclipse.escet.cif.datasynth.options.ContinuousPerformanceStatisticsFileOption;
+import org.eclipse.escet.cif.datasynth.options.EdgeGranularityOption;
 import org.eclipse.escet.cif.datasynth.options.EdgeOrderBackwardOption;
 import org.eclipse.escet.cif.datasynth.options.EdgeOrderDuplicateEventsOption;
 import org.eclipse.escet.cif.datasynth.options.EdgeOrderForwardOption;
@@ -459,6 +460,7 @@ public class CifDataSynthesisApp extends Application<IOutputComponent> {
         synthOpts.add(Options.getInstance(SupervisorNameOption.class));
         synthOpts.add(Options.getInstance(SupervisorNamespaceOption.class));
         synthOpts.add(Options.getInstance(ForwardReachOption.class));
+        synthOpts.add(Options.getInstance(EdgeGranularityOption.class));
         synthOpts.add(Options.getInstance(EdgeOrderOption.class)); // No longer supported.
         synthOpts.add(Options.getInstance(EdgeOrderBackwardOption.class));
         synthOpts.add(Options.getInstance(EdgeOrderForwardOption.class));
diff --git a/cif/org.eclipse.escet.cif.datasynth/src/org/eclipse/escet/cif/datasynth/conversion/CifToSynthesisConverter.java b/cif/org.eclipse.escet.cif.datasynth/src/org/eclipse/escet/cif/datasynth/conversion/CifToSynthesisConverter.java
index 650159422a818f196356b4f49b1c9390072b8d92..105d41c3091e8249e3e9456fdbd66cc35945cf8e 100644
--- a/cif/org.eclipse.escet.cif.datasynth/src/org/eclipse/escet/cif/datasynth/conversion/CifToSynthesisConverter.java
+++ b/cif/org.eclipse.escet.cif.datasynth/src/org/eclipse/escet/cif/datasynth/conversion/CifToSynthesisConverter.java
@@ -83,6 +83,8 @@ import org.eclipse.escet.cif.datasynth.bdd.CifBddBitVectorAndCarry;
 import org.eclipse.escet.cif.datasynth.options.BddAdvancedVariableOrderOption;
 import org.eclipse.escet.cif.datasynth.options.BddDebugMaxNodesOption;
 import org.eclipse.escet.cif.datasynth.options.BddDebugMaxPathsOption;
+import org.eclipse.escet.cif.datasynth.options.EdgeGranularityOption;
+import org.eclipse.escet.cif.datasynth.options.EdgeGranularityOption.EdgeGranularity;
 import org.eclipse.escet.cif.datasynth.options.EdgeOrderBackwardOption;
 import org.eclipse.escet.cif.datasynth.options.EdgeOrderDuplicateEventsOption;
 import org.eclipse.escet.cif.datasynth.options.EdgeOrderDuplicateEventsOption.EdgeOrderDuplicateEvents;
@@ -540,6 +542,12 @@ public class CifToSynthesisConverter {
             return synthAut;
         }
 
+        // Merge edges to the desired granularity.
+        mergeEdges(synthAut);
+        if (synthAut.env.isTerminationRequested()) {
+            return synthAut;
+        }
+
         // Order the synthesis edges.
         orderEdges(synthAut);
         if (synthAut.env.isTerminationRequested()) {
@@ -1771,7 +1779,7 @@ public class CifToSynthesisConverter {
 
                 // Create edge.
                 SynthesisEdge synthEdge = new SynthesisEdge(synthAut);
-                synthEdge.edge = cifEdge;
+                synthEdge.edges = list(cifEdge);
 
                 // Set event.
                 Assert.check(cifEdge.getEvents().size() == 1);
@@ -1935,7 +1943,8 @@ public class CifToSynthesisConverter {
                 // Add guards text for this group.
                 List<String> guardTxts = list();
                 for (SynthesisEdge edge: group) {
-                    List<Expression> guards = edge.edge.getGuards();
+                    Assert.check(edge.edges.size() == 1); // No synthesis edges have been merged yet.
+                    List<Expression> guards = first(edge.edges).getGuards();
                     String guardsTxt;
                     if (guards.isEmpty()) {
                         guardsTxt = "true";
@@ -2062,7 +2071,11 @@ public class CifToSynthesisConverter {
         }
 
         // Add relations to assure variables not being assigned don't change, i.e. won't jump arbitrarily.
-        for (int i = 0; i < assigned.length; i++) {
+        //
+        // We go through the variables in the reverse order of the variable order. This generally ensures the best
+        // performance, as new updates are added 'on top' of existing updates, allowing reuse of the existing BDDs,
+        // rather than needing to recreate them.
+        for (int i = assigned.length - 1; i >= 0; i--) {
             // If assigned, skip variable.
             if (assigned[i]) {
                 continue;
@@ -2084,8 +2097,7 @@ public class CifToSynthesisConverter {
         }
 
         // Store data for the updates.
-        int asgnCnt = assignments.size();
-        synthEdge.assignments = assignments.toArray(new Assignment[asgnCnt]);
+        synthEdge.assignments = list(assignments);
         synthEdge.update = relation;
         synthEdge.error = error;
     }
@@ -2300,12 +2312,13 @@ public class CifToSynthesisConverter {
 
             // Add edge that allows input variable to change to any other value.
             SynthesisEdge edge = new SynthesisEdge(synthAut);
-            edge.edge = null;
+            edge.edges = list((Edge)null);
             edge.event = event;
             edge.origGuard = synthAut.factory.one();
             edge.guard = synthAut.factory.one();
             edge.error = synthAut.factory.zero();
             synthAut.edges.add(edge);
+            synthAut.eventEdges.put(event, list(edge));
 
             // Add CIF assignment to edge. Right hand side not filled, as it is not a 'normal' assignment. Also,
             // technically in CIF an input variable can not be assigned.
@@ -2313,7 +2326,7 @@ public class CifToSynthesisConverter {
             addr.setVariable(synthInputVar.var);
             Assignment asgn = newAssignment();
             asgn.setAddressable(addr);
-            edge.assignments = new Assignment[] {asgn};
+            edge.assignments = list(list(asgn));
 
             // Add update relation.
             edge.update = synthAut.factory.one();
@@ -2349,6 +2362,38 @@ public class CifToSynthesisConverter {
         }
     }
 
+    /**
+     * Merges synthesis edges to the desired granularity.
+     *
+     * @param synthAut The synthesis automaton. Is modified in-place.
+     */
+    private void mergeEdges(SynthesisAutomaton synthAut) {
+        // Skip in case of conversion failure.
+        if (synthAut.eventEdges == null) {
+            return;
+        }
+
+        // Merge the edges, if needed.
+        EdgeGranularity granularity = EdgeGranularityOption.getGranularity();
+        switch (granularity) {
+            case PER_EDGE:
+                // Nothing to do, as already at per-edge granularity.
+                return;
+            case PER_EVENT: {
+                // Merge edges per event.
+                int eventCount = synthAut.eventEdges.size();
+                synthAut.edges = listc(eventCount);
+                for (Entry<Event, List<SynthesisEdge>> entry: synthAut.eventEdges.entrySet()) {
+                    SynthesisEdge mergedEdge = entry.getValue().stream().reduce(SynthesisEdge::mergeEdges).get();
+                    synthAut.edges.add(mergedEdge);
+                    entry.setValue(list(mergedEdge));
+                }
+                return;
+            }
+        }
+        throw new RuntimeException("Unknown granularity: " + granularity);
+    }
+
     /**
      * Orders the synthesis edges, for reachability computations.
      *
diff --git a/cif/org.eclipse.escet.cif.datasynth/src/org/eclipse/escet/cif/datasynth/options/EdgeGranularityOption.java b/cif/org.eclipse.escet.cif.datasynth/src/org/eclipse/escet/cif/datasynth/options/EdgeGranularityOption.java
new file mode 100644
index 0000000000000000000000000000000000000000..7373bbca637f2512bee7fbc1e00484e356b127b6
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.datasynth/src/org/eclipse/escet/cif/datasynth/options/EdgeGranularityOption.java
@@ -0,0 +1,80 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.datasynth.options;
+
+import org.eclipse.escet.cif.datasynth.options.EdgeGranularityOption.EdgeGranularity;
+import org.eclipse.escet.common.app.framework.options.EnumOption;
+import org.eclipse.escet.common.app.framework.options.Options;
+
+/** Option to specify the granularity of edges. */
+public class EdgeGranularityOption extends EnumOption<EdgeGranularity> {
+    /** Constructor for the {@link EdgeGranularityOption} class. */
+    public EdgeGranularityOption() {
+        super(
+                // name
+                "Edge granularity",
+
+                // description
+                "Specify the granularity of edges to use during synthesis."
+                        + "Specify \"per-edge\" to allow each event to have multiple edges, "
+                        + "or \"per-event\" (default) to merge for each event the edges into a single edge.",
+
+                // cmdShort
+                null,
+
+                // cmdLong
+                "edge-granularity",
+
+                // cmdValue
+                "GRAN",
+
+                // defaultValue
+                EdgeGranularity.PER_EVENT,
+
+                // showInDialog
+                true,
+
+                // optDialogDescr
+                "Specify the granularity of edges to use during synthesis.");
+    }
+
+    @Override
+    protected String getDialogText(EdgeGranularity granularity) {
+        switch (granularity) {
+            case PER_EDGE:
+                return "Per edge (allow each event to have multiple edges)";
+            case PER_EVENT:
+                return "Per event (merge for each event the edges into a single edge)";
+        }
+        throw new RuntimeException("Unknown granularity: " + granularity);
+    }
+
+    /**
+     * Returns the value of the {@link EdgeGranularityOption} option.
+     *
+     * @return The value of the {@link EdgeGranularityOption} option.
+     */
+    public static EdgeGranularity getGranularity() {
+        return Options.get(EdgeGranularityOption.class);
+    }
+
+    /** Edge granularity. */
+    public static enum EdgeGranularity {
+        /** Allow each event to have multiple edges. */
+        PER_EDGE,
+
+        /** Merge for each event the edges into a single edge. */
+        PER_EVENT;
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.datasynth/src/org/eclipse/escet/cif/datasynth/spec/SynthesisAutomaton.java b/cif/org.eclipse.escet.cif.datasynth/src/org/eclipse/escet/cif/datasynth/spec/SynthesisAutomaton.java
index 198eb00e193648c058dfec974c7f17a551eddcdd..6e3bd4dea6a497a8ea3a35f7e82fb3f19fb71597 100644
--- a/cif/org.eclipse.escet.cif.datasynth/src/org/eclipse/escet/cif/datasynth/spec/SynthesisAutomaton.java
+++ b/cif/org.eclipse.escet.cif.datasynth/src/org/eclipse/escet/cif/datasynth/spec/SynthesisAutomaton.java
@@ -65,22 +65,22 @@ public class SynthesisAutomaton {
      */
     public SynthesisVariable[] variables;
 
-    /** The linearized edges. */
+    /** The synthesis edges. */
     public List<SynthesisEdge> edges;
 
     /**
-     * The linearized edges, ordered for backward reachability computations. Contains all edges from {@link #edges} at
+     * The synthesis edges, ordered for backward reachability computations. Contains all edges from {@link #edges} at
      * least once.
      */
     public List<SynthesisEdge> orderedEdgesBackward;
 
     /**
-     * The linearized edges, ordered for forward reachability computations. Contains all edges from {@link #edges} at
+     * The synthesis edges, ordered for forward reachability computations. Contains all edges from {@link #edges} at
      * least once.
      */
     public List<SynthesisEdge> orderedEdgesForward;
 
-    /** Mapping from events to their corresponding linearized edges. */
+    /** Mapping from events to their synthesis edges. */
     public Map<Event, List<SynthesisEdge>> eventEdges;
 
     /** The events that are disabled before synthesis. */
diff --git a/cif/org.eclipse.escet.cif.datasynth/src/org/eclipse/escet/cif/datasynth/spec/SynthesisEdge.java b/cif/org.eclipse.escet.cif.datasynth/src/org/eclipse/escet/cif/datasynth/spec/SynthesisEdge.java
index 6599b19401c4c9c2641601cba50937259e3aeb2f..9bfa9514daf5b92cea1a0d059804fa21799780fc 100644
--- a/cif/org.eclipse.escet.cif.datasynth/src/org/eclipse/escet/cif/datasynth/spec/SynthesisEdge.java
+++ b/cif/org.eclipse.escet.cif.datasynth/src/org/eclipse/escet/cif/datasynth/spec/SynthesisEdge.java
@@ -14,8 +14,11 @@
 package org.eclipse.escet.cif.datasynth.spec;
 
 import static org.eclipse.escet.cif.datasynth.bdd.BddUtils.bddToStr;
+import static org.eclipse.escet.common.java.Lists.concat;
 import static org.eclipse.escet.common.java.Strings.fmt;
 
+import java.util.List;
+
 import org.eclipse.escet.cif.common.CifScopeUtils;
 import org.eclipse.escet.cif.common.CifTextUtils;
 import org.eclipse.escet.cif.datasynth.CifDataSynthesis;
@@ -37,8 +40,12 @@ public class SynthesisEdge {
     /** The synthesis automaton that contains this edge. */
     public final SynthesisAutomaton aut;
 
-    /** The CIF edge that corresponds to this synthesis edge. Is {@code null} for edges created for input variables. */
-    public Edge edge;
+    /**
+     * The linearized CIF edges that corresponds to this synthesis edge. Contains a {@code null} value for edges created
+     * for input variables. There is always at least one edge (or {@code null}). If there are multiple edges, then this
+     * synthesis edge represents the disjunction of multiple linearized edges.
+     */
+    public List<Edge> edges;
 
     /** The event on the edge. */
     public Event event;
@@ -52,8 +59,8 @@ public class SynthesisEdge {
     /** Precomputed '{@link #guard} and {@link #error}'. Is {@code null} if not available. */
     public BDD guardError;
 
-    /** The CIF assignments that correspond to these synthesis assignments. */
-    public Assignment[] assignments;
+    /** Per {@link #edges edge}, the CIF assignments that are applied by this synthesis edge. */
+    public List<List<Assignment>> assignments;
 
     /**
      * The update predicate that relates old and new values of variables, indicating which combinations of old and new
@@ -80,7 +87,7 @@ public class SynthesisEdge {
      * <p>
      * Runtime errors include assignments leading to values outside of the BDD representable ranges, division by zero,
      * etc. Runtime errors may or may not include assignments leading to values that are outside of the valid CIF range,
-     * which that can still be represented by BDDs, as those situations are also taken care of by the range invariants.
+     * which can still be represented by BDDs, as those situations are also taken care of by the range invariants.
      * </p>
      */
     public BDD error;
@@ -325,14 +332,24 @@ public class SynthesisEdge {
             guardsTxt = fmt("%s -> %s", origGuardTxt, guardTxt);
         }
         txt.append(fmt(" (guard: %s)", guardsTxt));
-        if (assignments.length > 0) {
+        if (assignments.stream().anyMatch(as -> !as.isEmpty())) {
             txt.append(" (assignments: ");
-            for (int i = 0; i < assignments.length; i++) {
+            for (int i = 0; i < assignments.size(); i++) {
                 if (i > 0) {
-                    txt.append(", ");
+                    txt.append(" / ");
+                }
+                List<Assignment> edgeAssignments = assignments.get(i);
+                if (edgeAssignments.isEmpty()) {
+                    txt.append("none");
+                } else {
+                    for (int j = 0; j < edgeAssignments.size(); j++) {
+                        if (j > 0) {
+                            txt.append(", ");
+                        }
+                        Assignment asgn = edgeAssignments.get(j);
+                        txt.append(assignmentToString(asgn));
+                    }
                 }
-                Assignment asgn = assignments[i];
-                txt.append(assignmentToString(asgn));
             }
             txt.append(")");
         }
@@ -345,7 +362,7 @@ public class SynthesisEdge {
      * @param asgn The assignment.
      * @return The end user readable textual representation.
      */
-    private Object assignmentToString(Assignment asgn) {
+    private String assignmentToString(Assignment asgn) {
         Expression addr = asgn.getAddressable();
         Declaration addrVar = (Declaration)CifScopeUtils.getRefObjFromRef(addr);
         Expression rhs = asgn.getValue();
@@ -395,4 +412,50 @@ public class SynthesisEdge {
         }
         throw new RuntimeException("No synthesis variable found for addressable: " + addrVar);
     }
+
+    /**
+     * Merges two synthesis edges for the same event, from the same synthesis automaton. The result is a single merged
+     * edge that is the disjunction of the two edges. The edges being merged are no longer valid edges afterwards, and
+     * any BDD instances they held will have been freed.
+     *
+     * @param edge1 The first edge to merge. Is modified in-place.
+     * @param edge2 The second edge to merge. Is modified in-place.
+     * @return The merged edge.
+     */
+    public static SynthesisEdge mergeEdges(SynthesisEdge edge1, SynthesisEdge edge2) {
+        // Ensure we merge edges for the same event, in the same synthesis automaton.
+        Assert.areEqual(edge1.aut, edge2.aut);
+        Assert.areEqual(edge1.event, edge2.event);
+        Assert.check(!edge1.edges.contains(null)); // Input variables only have one edge, so they can't be merged.
+        Assert.check(!edge2.edges.contains(null)); // Input variables only have one edge, so they can't be merged.
+
+        // Create new synthesis edge.
+        SynthesisEdge mergedEdge = new SynthesisEdge(edge1.aut);
+        mergedEdge.event = edge1.event;
+
+        // Merged the edges and assignments.
+        mergedEdge.edges = concat(edge1.edges, edge2.edges);
+        mergedEdge.assignments = concat(edge1.assignments, edge2.assignments);
+
+        // Merge updates. The updates need to be made conditional on their original guards, to ensure that the updates
+        // of the correct original edge are applied when the guard of that original edge holds. To support
+        // non-determinism, if both guards hold, either of the updates may be applied. If neither of the guards holds,
+        // we do not care what the update is, as the guard and update predicates are always combined before the edge is
+        // applied. So, create: '(guard1 and update1) or (guard2 and update2)'.
+        BDD update1 = edge1.guard.id().andWith(edge1.update);
+        BDD update2 = edge2.guard.id().andWith(edge2.update);
+        mergedEdge.update = update1.orWith(update2);
+
+        // Merge errors. The errors are combined in a similar way as the updates.
+        BDD error1 = edge1.guard.id().andWith(edge1.error);
+        BDD error2 = edge2.guard.id().andWith(edge2.error);
+        mergedEdge.error = error1.orWith(error2);
+
+        // Merge guards.
+        mergedEdge.origGuard = edge1.origGuard.orWith(edge2.origGuard);
+        mergedEdge.guard = edge1.guard.orWith(edge2.guard);
+
+        // Return the merged edge.
+        return mergedEdge;
+    }
 }
diff --git a/cif/org.eclipse.escet.cif.datasynth/src/org/eclipse/escet/cif/datasynth/varorder/hyperedges/LegacyHyperEdgeCreator.java b/cif/org.eclipse.escet.cif.datasynth/src/org/eclipse/escet/cif/datasynth/varorder/hyperedges/LegacyHyperEdgeCreator.java
index d2afaf28cab47518a2a35ffdec80aaced79cb679..e34e7739a677c39c561d5770779aa437cbd88b74 100644
--- a/cif/org.eclipse.escet.cif.datasynth/src/org/eclipse/escet/cif/datasynth/varorder/hyperedges/LegacyHyperEdgeCreator.java
+++ b/cif/org.eclipse.escet.cif.datasynth/src/org/eclipse/escet/cif/datasynth/varorder/hyperedges/LegacyHyperEdgeCreator.java
@@ -112,7 +112,7 @@ public class LegacyHyperEdgeCreator extends HyperEdgeCreator {
             Automaton aut = (Automaton)comp;
             for (Location loc: aut.getLocations()) {
                 // Add a hyper-edge per invariant of the location.
-                for (Invariant inv: comp.getInvariants()) {
+                for (Invariant inv: loc.getInvariants()) {
                     Expression pred = inv.getPredicate();
                     VariableCollector varCollector = new VariableCollector();
                     Set<PositionObject> vars = set();
diff --git a/cif/org.eclipse.escet.cif.documentation.utils/.settings/org.eclipse.jdt.core.prefs b/cif/org.eclipse.escet.cif.documentation.utils/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/cif/org.eclipse.escet.cif.documentation.utils/.settings/org.eclipse.jdt.core.prefs
+++ b/cif/org.eclipse.escet.cif.documentation.utils/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/cif/org.eclipse.escet.cif.documentation.utils/.settings/org.eclipse.jdt.ui.prefs b/cif/org.eclipse.escet.cif.documentation.utils/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/cif/org.eclipse.escet.cif.documentation.utils/.settings/org.eclipse.jdt.ui.prefs
+++ b/cif/org.eclipse.escet.cif.documentation.utils/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/cif/org.eclipse.escet.cif.documentation.utils/.settings/org.eclipse.ltk.core.refactoring.prefs b/cif/org.eclipse.escet.cif.documentation.utils/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.documentation.utils/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/cif/org.eclipse.escet.cif.documentation.utils/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.documentation.utils/META-INF/MANIFEST.MF
index a4d4856d2b08101a2a8957ea0081b5427e32e68e..d34a9f81facd55021c9c3924368a2ec4c110a074 100644
--- a/cif/org.eclipse.escet.cif.documentation.utils/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.documentation.utils/META-INF/MANIFEST.MF
@@ -2,13 +2,13 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET CIF Documentation Utils (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.cif.documentation.utils;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Automatic-Module-Name: org.eclipse.escet.cif.documentation.utils
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
 Export-Package: org.eclipse.escet.cif.documentation.utils
-Require-Bundle: org.eclipse.escet.cif.simulator;bundle-version="0.9.0",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.cif.simulator;bundle-version="0.10.0",
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
  org.apache.commons.math3;bundle-version="3.5.0"
diff --git a/cif/org.eclipse.escet.cif.documentation/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.documentation/META-INF/MANIFEST.MF
index ce56c82bff8280d7d0084c9775dea647f4d5d2fe..20f8c785bd6342bef6ce1d805a00757df6d30615 100644
--- a/cif/org.eclipse.escet.cif.documentation/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.documentation/META-INF/MANIFEST.MF
@@ -2,6 +2,6 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET CIF Documentation (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.cif.documentation;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Require-Bundle: org.eclipse.help
diff --git a/cif/org.eclipse.escet.cif.documentation/asciidoc/documentation.asciidoc b/cif/org.eclipse.escet.cif.documentation/asciidoc/documentation.asciidoc
index fa924e746c09d3ad1c06123889208ffeb477cd86..311d1128e51251faa7aff2e5c7de595b0c5ed149 100644
--- a/cif/org.eclipse.escet.cif.documentation/asciidoc/documentation.asciidoc
+++ b/cif/org.eclipse.escet.cif.documentation/asciidoc/documentation.asciidoc
@@ -30,7 +30,7 @@ The CIF tooling supports the entire development process of controllers, includin
 Combined they enable a synthesis-based engineering approach to efficiently and cost-effectively design and implement high-quality controllers.
 
 CIF is one of the tools of the Eclipse ESCET(TM) project.
-Visit the link:https://eclipse.org/escet/{escet-website-version}[project website] for downloads, installation instructions, source code, general tool usage information, information on how to contribute, and more.
+Visit the link:https://eclipse.dev/escet/{escet-website-version}[project website] for downloads, installation instructions, source code, general tool usage information, information on how to contribute, and more.
 
 [WARNING]
 ====
@@ -376,6 +376,8 @@ include::tools/datasynth/initialization.asciidoc[]
 
 include::tools/datasynth/performance.asciidoc[]
 
+include::tools/datasynth/edge-granularity.asciidoc[]
+
 include::tools/datasynth/edge-order.asciidoc[]
 
 include::tools/datasynth/variable-order/index.asciidoc[]
diff --git a/cif/org.eclipse.escet.cif.documentation/asciidoc/release-notes.asciidoc b/cif/org.eclipse.escet.cif.documentation/asciidoc/release-notes.asciidoc
index 39bd5787d1b08997edac46037ea732687cb8ff0e..6b495804607edaa1b6a68021485110912d945d91 100644
--- a/cif/org.eclipse.escet.cif.documentation/asciidoc/release-notes.asciidoc
+++ b/cif/org.eclipse.escet.cif.documentation/asciidoc/release-notes.asciidoc
@@ -20,7 +20,46 @@ indexterm:[release, notes]
 
 The release notes for the versions of CIF and the associated tools, as part of the Eclipse ESCET project, are listed below in reverse chronological order.
 
-See also the Eclipse ESCET link:https://eclipse.org/escet/{escet-website-version}/release-notes.html[toolkit release notes] covering those aspects that are common to the various Eclipse ESCET tools.
+See also the Eclipse ESCET link:https://eclipse.dev/escet/{escet-website-version}/release-notes.html[toolkit release notes] covering those aspects that are common to the various Eclipse ESCET tools.
+
+=== Version 0.10
+
+TBD
+
+Language changes:
+
+* The CIF type checker now allows omitting the `else` part of `switch` expressions in more situations, when it can be statically determined that the `switch` expression is complete without it.
+The type checker has also been improved, regarding detection of duplicate and missing switch cases, and superfluous ``else``s (issue {escet-issue}548[#548]).
+
+New features:
+
+* The CIF data-based synthesis tool has a new _Edge granularity_ option to configure the granularity of edges to use during synthesis.
+Previously, the linearized edges were used 'as is'.
+Now, they are merged per event, to obtain a single edge per event.
+The option can be used to restore the old behavior.
+The new edge granularity has been shown to reduce both the memory usage and time required to perform synthesis.
+For more information, see the documentation of the new option (issue {escet-issue}586[#586]).
+
+Improvements and fixes:
+
+* The CIF simulator's command line script has been fixed for handling dark theme detection, preventing crashes and improving dark theme support, when using the simulator's plot visualizer or interactive GUI input component (issue {escet-issue}567[#567]).
+* The CIF simulator's SVG visualizer _Save as_ dialog now properly starts in the directory that contains the SVG file, also on Windows.
+And it now properly handles paths with spaces and other special characters in them (issue {escet-issue}221[#221]).
+* The CIF explorer now warns about exploring specifications with requirements (issue {escet-issue}585[#585]).
+* The CIF event-based synthesis toolset's command line scripts now have correct information to start the tools, where previously they always crashed (issue {escet-issue}567[#567]).
+* The CIF event-based synthesis analysis tool's command line script has been fixed for handling dark theme detection, preventing crashes and improving dark theme support (issue {escet-issue}567[#567]).
+* The CIF event-based synthesis analysis tool's command line script has been fixed to not immediately terminate after starting the tool (issue {escet-issue}567[#567]).
+* The CIF event-based synthesis tool now warns about synthesizing specifications without requirement automata (issue {escet-issue}553[#553]).
+* The CIF data-based synthesis tool now has better performance for converting updates of the CIF specification to their internal BDD representations (issue {escet-issue}580[#580]).
+* The CIF data-based synthesis benchmarking scripts no longer produce debug output when performing synthesis, making benchmarking faster and producing less output, while still producing the same values for platform-independent metrics (issue {escet-issue}564[#564]).
+* The CIF data-based synthesis legacy hyper-edge creation algorithm now properly considers invariants in locations for variable ordering, rather than considering invariants in the automaton twice.
+This could affect synthesis performance (issue {escet-issue}377[#377]).
+* The CIF controller property checker's finite response check may now have improved performance (issue {escet-issue}583[#583]).
+* The CIF to CIF transformation to merge all enumerations of the specification into a single enumeration has been changed.
+It now converts the last case of all `switch` expressions to an `else`, for switch expressions that switch over a value that has a type that includes an enumeration type.
+Hereby, the keys of these last cases are removed from the model (issue {escet-issue}548[#548]).
+* The website has been fixed to ensure all version-specific URLs are now properly replaced by non-version-specific ones when a version-specific website is promoted to become the main website.
+Previously, a few URLs remained version-specific (issue {escet-issue}577[#577]).
 
 === Version 0.9 (2023-03-31)
 
diff --git a/cif/org.eclipse.escet.cif.documentation/asciidoc/synthesis-based-engineering/in-practice/advanced/synthesis-performance.asciidoc b/cif/org.eclipse.escet.cif.documentation/asciidoc/synthesis-based-engineering/in-practice/advanced/synthesis-performance.asciidoc
index 572b3a30c1cd77ccca03ee45d6f0ec785c693266..7099d194664cb9bbbb679cadc09cb9fc06137151 100644
--- a/cif/org.eclipse.escet.cif.documentation/asciidoc/synthesis-based-engineering/in-practice/advanced/synthesis-performance.asciidoc
+++ b/cif/org.eclipse.escet.cif.documentation/asciidoc/synthesis-based-engineering/in-practice/advanced/synthesis-performance.asciidoc
@@ -28,7 +28,7 @@ However, if you still suffer such issues, consider the following to resolve them
 
 indexterm:[synthesis, memory]
 
-* See the page of the Eclipse ESCET general toolkit documentation on link:https://www.eclipse.org/escet/{escet-website-version}/performance/index.html[resolving performance and memory problems].
+* See the page of the Eclipse ESCET general toolkit documentation on link:https://eclipse.dev/escet/{escet-website-version}/performance/index.html[resolving performance and memory problems].
 In particular, make sure to give Java more memory.
 This should be the first thing you check.
 
diff --git a/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/cif2cif/merge-enums.asciidoc b/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/cif2cif/merge-enums.asciidoc
index e2bc00aea8da29913a038f64079171d58681ed4a..f384588e9e26b2c2559c1e8de68df321a561fcf4 100644
--- a/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/cif2cif/merge-enums.asciidoc
+++ b/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/cif2cif/merge-enums.asciidoc
@@ -149,6 +149,41 @@ After the merging of the enumerations, both `v1` and `v2` have implicit initial
 Thus, they had different initial values beforehand, and the same initial values afterward.
 To solve this problem, the <<tools-cif2cif-chapter-add-default-init-values>> CIF to CIF transformation is automatically applied as preprocessing before the actual elimination of the enumerations, to ensure that the explicit initial values are properly transformed.
 
+indexterm:[merge enumerations,switch expressions]
+
+=== Switch expressions
+
+Consider the following specification:
+
+[source, cif]
+----
+enum E1 = A, B;
+enum E2 = C, D;
+
+input E1 i;
+invariant switch i:
+            case A: true
+            case B: false
+          end;
+----
+
+After merging the enumerations, the single merged enumeration has four literals (`A`, `B`, `C` and `D`).
+The `switch` expression is then incomplete, as it does not cover the extra literals from `E2` (`C` and `D`) that got merged with `E1`.
+To ensure that `switch` expressions remain complete and valid, all `switch` expressions that switch over a value that has a type that includes an enumeration type, but do not have an `else`, are modified.
+Their last `case` is converted to an `else`, removing the key of the `case` in the process.
+For the example above, this results in:
+
+[source, cif]
+----
+enum E = A, B, C, D;
+
+input E i;
+invariant switch i:
+            case A: true
+            else    false
+          end;
+----
+
 indexterm:[merge enumerations,size considerations]
 
 === Size considerations
@@ -158,6 +193,8 @@ Therefore, this transformation may decrease the size of the specification.
 
 The added default initial values may significantly increase the size of the specification.
 
+Removing the key of the last `case` of a `switch` expressions may slightly decrease the size of the specification.
+
 === Optimality
 
 n/a
diff --git a/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/datasynth/edge-granularity.asciidoc b/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/datasynth/edge-granularity.asciidoc
new file mode 100644
index 0000000000000000000000000000000000000000..fa9d3b0dfc0a7ff0b8f8b610513d6b636a2a7131
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/datasynth/edge-granularity.asciidoc
@@ -0,0 +1,78 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+indexterm:[data-based supervisory controller synthesis,edge granularity]
+
+[[tools-datasynth-edge-granularity]]
+== Edge granularity
+
+To prepare for synthesis, the data-based synthesis tool first <<tools-cif2cif-chapter-linearize-product,linearizes>> the specification.
+This essentially combines the edges of the various automata in different ways, to form new self-loop edges that are then part of a single location of a single automaton.
+After that, each such linearized edge is converted to a Binary Decision Diagram (BDD) representation, a symbolic representation of the edge that allows efficient computations.
+The BDD representations of the edges are then used to perform the actual synthesis.
+
+However, using the linearized edges 'as is' doesn't always give the best synthesis performance.
+It may be beneficial to combine some linearized edges together, to form a single combined edge.
+This combined edge may have a smaller BDD representation than the original edges from which it was combined, reducing memory usage during synthesis.
+The combined edge may also lead to faster convergence for link:https://en.wikipedia.org/wiki/Reachability[reachability] computations, reducing both memory usage and synthesis time.
+However, the effect depends on the particular model being synthesized, and combining edges can also lead to an increase in memory usage and synthesis time.
+Furthermore, the synthesis performance may also be affected by the <<tools-datasynth-edge-order,order>> in which the edges are considered during reachability computations, and whether or not <<tools-datasynth-forward-reach,forward>> reachability is used.
+
+The edge representation to use for synthesis can thus be more granular (more edges) or less granular (less edges).
+The following granularities are supported:
+
+* _Per edge_: Allow each event to have multiple edges.
+Essentially, the linearized edges are used 'as is'.
+
+* _Per event_: Ensure each event has exactly one edge.
+Essentially, for each event, the linearized edges are merged together to form a single edge for that event.
+
+The granularity can be configured using the _Edge granularity_ option (see the <<tools-datasynth-options,options section>>).
+By default, the 'per event' edge granularity is used.
+
+=== Linearization and non-determinism
+
+The CIF data-based synthesis tool uses the <<tools-cif2cif-chapter-linearize-product,linearize-product>> variant of linearization, as this variant ensures that all behavior of the specification is preserved.
+After having merged the edges for a certain event together into a single event, one may wonder whether the result is then the same as would have been obtained by the <<tools-cif2cif-chapter-linearize-merge,linearize-merge>> variant of linearization.
+This is indeed the case in many situations, but there are exceptions.
+
+If two linearized edges (as obtained by linearize-product) have overlapping guards, they can be enabled at the same time, and we therefore have to deal with this non-determinism.
+If the edges then have different updates, we get to the exceptional case.
+In such cases, linearize-merge will choose one of the updates, while the approach for merging edges on BDD representation as is used for 'per event' edge granularity will allow both updates.
+Note that there is no way in CIF to represent such merged edges as a single CIF edge, but such edges can be represented using BDDs.
+
+=== Example
+
+As an example, consider two linearized edges, obtained by linearize-product:
+
+* `+when x <= 4 do x := x + 1+`
+* `+when x >= 4 do x := x - 1+`
+
+When we combine them, we first combine their guards using `or`.
+This gives us `+x <= 4 or x >= 4+`, which can be simplified to `true`.
+This is a good example of how combining edges may simplify them, reducing their memory usage.
+
+We then also combine their updates, where we distinguish 3 cases:
+
+* Case 1 (the first guard holds, the second one doesn't):
+Here `+x <= 4 and not x >= 4+`, which is `+x <= 4 and x < 4+`, which is just `x < 4`.
+As only the first edge is enabled, we get that if guard `x < 4` holds, then update `x := x + 1` should be applied.
+* Case 2 (the second guard holds, the first one doesn't):
+Here `+not x <= 4 and x >= 4+`, which is `+x > 4 and x >= 4+`, which is just `x > 4`.
+As only the second edge is enabled, we get that if guard `x > 4` holds, then update `x := x - 1` should be applied.
+* Case 3 (both guards hold):
+Here `+x <= 4 and x >= 4+`, which is just `x = 4`.
+As both edges are enabled, we get that if guard `x = 4` holds, then either of the updates may be applied.
+
+Case 3 can not be directly represented as an update of a single edge of a CIF model, as on a single edge, even using `if` updates, we can not perform two different updates on the same variable.
+This is a good example of how the updates can become more complex, as we need to distinguish various cases, and relate the updates to the guards and combinations of guards, which may be more complex then the original edges that were combined.
diff --git a/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/datasynth/edge-order.asciidoc b/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/datasynth/edge-order.asciidoc
index d813104aa4dbf7f280a662dd4df02fb7bbb68737..99c47a46f7a92857b258f8362dab39730467ac7d 100644
--- a/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/datasynth/edge-order.asciidoc
+++ b/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/datasynth/edge-order.asciidoc
@@ -38,6 +38,7 @@ See the <<tools-datasynth-var-order,section about BDD variable order>> for more
 Synthesis does not directly use the edges from the model.
 It applies <<tools-cif2cif-chapter-linearize-product,linearization>> and then uses the edges from the linearized model.
 Edges are internally also added to <<tools-datasynth-input-vars,support input variables>> during synthesis.
+Furthermore, edges may be combined to form <<tools-datasynth-edge-granularity,less granular>> edges, before they are used for reachability computations.
 
 The order in which the edges are considered for reachability computations is determined by the _Edge order for backward reachability_ and _Edge order for forward reachability_ options (see the <<tools-datasynth-options,options section>>).
 Several predefined orders exist, and it is also possible to define a custom order.
diff --git a/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/datasynth/forward-reachability.asciidoc b/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/datasynth/forward-reachability.asciidoc
index 0332018c849c4b733e42daeeb4a107b3bff909b6..2dfa255f5049862db37cba76109a3fcc7d200991 100644
--- a/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/datasynth/forward-reachability.asciidoc
+++ b/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/datasynth/forward-reachability.asciidoc
@@ -65,4 +65,4 @@ It depends on the specification being synthesized whether enabling forward reach
 It also depends on the specification whether there is any benefit to using forward reachability for the guards of the supervisor.
 Forward reachability is disabled by default.
 It can be enabled using the _Forward reachability_ option (see the <<tools-datasynth-options,options section>>).
-The order in which the edges of the specification are considered also influences the performance (see the <<tools-datasynth-edge-order,edge order section>>).
+The order in which the edges of the specification are considered during reachability computations also influences the performance (see the <<tools-datasynth-edge-order,edge order section>>), as does the <<tools-datasynth-edge-granularity,edge granularity>>.
diff --git a/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/datasynth/index.asciidoc b/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/datasynth/index.asciidoc
index b55a839ff5eaf46de2a23ab100f725540b0dfab1..55369bf2430d679677bd5f0345c1ef5981c5266e 100644
--- a/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/datasynth/index.asciidoc
+++ b/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/datasynth/index.asciidoc
@@ -55,6 +55,7 @@ The following additional information is available:
 * <<tools-datasynth-input-vars>>
 * <<tools-datasynth-init>>
 * <<tools-datasynth-performance>>
+* <<tools-datasynth-edge-granularity>>
 * <<tools-datasynth-edge-order>>
 * <<tools-datasynth-var-order>>
 * <<tools-datasynth-op-cache>>
diff --git a/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/datasynth/options.asciidoc b/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/datasynth/options.asciidoc
index e3ffd5ca55acad07c4ac3cab1352772ddf681500..fdaef725fc312d9b3dba36ae51364d2bf57f88fd 100644
--- a/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/datasynth/options.asciidoc
+++ b/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/datasynth/options.asciidoc
@@ -37,6 +37,9 @@ For more information, see the <<tools-datasynth-supervisor-namespace,section abo
 Is disabled by default.
 For more information, see the <<tools-datasynth-forward-reach,section about forward reachability>>.
 
+* _Edge granularity_: Specify the granularity of edges to use during synthesis.
+For more information, see the <<tools-datasynth-edge-granularity,section about edge granularity>>.
+
 * _Edge order_: This option is no longer supported.
 Use the _Edge order for backward reachability_ and _Edge order for forward reachability_ options instead.
 
diff --git a/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/datasynth/performance.asciidoc b/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/datasynth/performance.asciidoc
index b400a0f6dde62c5dd1396821af7b713a64ea2b78..3a5575257b916300b4092e1088d67a9e425ea37f 100644
--- a/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/datasynth/performance.asciidoc
+++ b/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/datasynth/performance.asciidoc
@@ -32,6 +32,12 @@ The following <<tools-datasynth-options,options>> have an effect on the performa
 | Impacts the up-front effort, size of the controlled behavior, number of iterations to reach fixed points, and the post-synthesis effort
 | Complex trade-off between different effects, depends on the model
 
+| Input
+| Edge granularity
+| <<tools-datasynth-edge-granularity>>
+| Impacts the size of the edge representations, size of the controlled behavior, number of iterations to reach fixed points, and the post-synthesis effort
+| Choose the best representation, depends on the model
+
 | Output
 | BDD output mode
 | <<tools-datasynth-supervisor-bdd>>
diff --git a/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/datasynth/statistics.asciidoc b/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/datasynth/statistics.asciidoc
index 75460ed27fe28eafb5a549f66d36593079269125..c39d6f38926549063eac00b7c2cbf7bc93fc94eb 100644
--- a/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/datasynth/statistics.asciidoc
+++ b/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/datasynth/statistics.asciidoc
@@ -155,7 +155,7 @@ It prints the maximum amount of memory used during synthesis, in number of bytes
 +
 Note that collecting this metric may make synthesis take longer than without collecting it.
 +
-The CIF data-based synthesis tool is written in Java, a link:https://www.eclipse.org/escet/{escet-website-version}/performance/tweak-perf-settings.html#managed-memory-and-garbage-collection[managed language with a garbage collector].
+The CIF data-based synthesis tool is written in Java, a link:https://eclipse.dev/escet/{escet-website-version}/performance/tweak-perf-settings.html#managed-memory-and-garbage-collection[managed language with a garbage collector].
 Hence, the measured memory usage is a best-effort approximation, and may not be correct.
 +
 When measuring memory usage, always perform multiple measurements, and take the average.
@@ -164,7 +164,7 @@ If memory usage is measured using the Eclipse ESCET IDE, make sure not to perfor
 However, when measuring the memory usage in the Eclipse ESCET IDE, the IDE itself, as well as editor content, console content, and so on, are also included in the memory usage.
 It is therefore highly recommended to use the Eclipse ESCET command line scripts rather than the Eclipse ESCET IDE to perform memory usage measurements.
 +
-To ensure the best result, let Java link:https://www.eclipse.org/escet/{escet-website-version}/performance/tweak-perf-settings.html#monitoring-eclipse-heap-status[perform a garbage collection] before starting the data-based synthesis tool.
+To ensure the best result, let Java link:https://eclipse.dev/escet/{escet-website-version}/performance/tweak-perf-settings.html#monitoring-eclipse-heap-status[perform a garbage collection] before starting the data-based synthesis tool.
 This ensures that synthesis starts with 'clean' memory.
 This is particularly relevant if multiple syntheses are performed one after the other, to ensure that any previous syntheses do not affect subsequent measurements.
 Both synthesis and garbage collection may conveniently be executed via a <<tools-scripting-chapter-intro,ToolDef script>>.
@@ -178,7 +178,7 @@ cifdatasynth(...);
 ```
 +
 The maximum used memory statistics obtained in this way are an easy way to get an approximation of the memory used during synthesis.
-For a more comprehensive way to measure memory usage, use a tool like link:https://www.eclipse.org/escet/{escet-website-version}/performance/tweak-perf-settings.html#monitoring-with-visualvm[VisualVM].
+For a more comprehensive way to measure memory usage, use a tool like link:https://eclipse.dev/escet/{escet-website-version}/performance/tweak-perf-settings.html#monitoring-with-visualvm[VisualVM].
 
 In the option dialog, each of the different kinds of statistics can be enabled and disabled individually, using a checkbox.
 
diff --git a/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/eventbased/supervisorsynthesis.asciidoc b/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/eventbased/supervisorsynthesis.asciidoc
index 8d9ce5b08914b8e555042acf7c85641e21d95634..20a7e7256ade7872d1e5a95c9ad44a8ec10e1df2 100644
--- a/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/eventbased/supervisorsynthesis.asciidoc
+++ b/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/eventbased/supervisorsynthesis.asciidoc
@@ -44,6 +44,8 @@ In addition, it warns about common mistakes:
 
 * Non-<<tools-eventbased-chapter-trim-check,trim>> automata.
 
+* Specifications without any `requirement` automata.
+
 Finally, it can also perform checks about correct constructs that may not be the intention of its author.
 Each of these checks has to be enabled with an option:
 
diff --git a/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/explorer.asciidoc b/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/explorer.asciidoc
index 1e0a1283db3d2f988501d121d939f0fa91725dea..200557c14f8b414793b2bb31def3b2d2bd99de67 100644
--- a/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/explorer.asciidoc
+++ b/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/explorer.asciidoc
@@ -121,6 +121,7 @@ The following restrictions apply:
 The following information from the specification is ignored:
 
 * Automaton and invariant supervisory kinds.
+A warning is printed if a requirement automaton or requirement invariant is encountered.
 
 * Controllability of events.
 
diff --git a/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/scripting/intro.asciidoc b/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/scripting/intro.asciidoc
index 8dd82ad8cc758fad85564d6f7b7255898b7a421e..5753ab46416c0a6d15966000a729fcb43b60f484 100644
--- a/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/scripting/intro.asciidoc
+++ b/cif/org.eclipse.escet.cif.documentation/asciidoc/tools/scripting/intro.asciidoc
@@ -16,10 +16,9 @@ include::../_part_attributes.asciidoc[]
 [[tools-scripting-chapter-intro]]
 == Introduction to scripting
 
-// Removed the previously present link to documentation about 'ToolDef'.
 All CIF <<tools-chapter-index,tools>> can be used in ToolDef scripts.
 ToolDef is a cross-platform and machine-independent scripting language that supports command line execution, but is also available as plug-in for link:https://eclipse.org[Eclipse], providing an integrated development experience.
-See the link:https://eclipse.org/escet/{escet-website-version}/tooldef[ToolDef website] for more information on ToolDef.
+See the link:https://eclipse.dev/escet/{escet-website-version}/tooldef[ToolDef website] for more information on ToolDef.
 
 === Scenarios
 
diff --git a/cif/org.eclipse.escet.cif.documentation/build-docs-cif.launch b/cif/org.eclipse.escet.cif.documentation/build-docs-cif.launch
index ecca1ff87fe15807810acb26f5b2f09e47a24eef..c699663413000fcec5584d08220d93f846d73363 100644
--- a/cif/org.eclipse.escet.cif.documentation/build-docs-cif.launch
+++ b/cif/org.eclipse.escet.cif.documentation/build-docs-cif.launch
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <launchConfiguration type="org.eclipse.m2e.Maven2LaunchConfigurationType">
+    <intAttribute key="M2_COLORS" value="0"/>
     <booleanAttribute key="M2_DEBUG_OUTPUT" value="false"/>
     <stringAttribute key="M2_GOALS" value="clean package --projects releng/org.eclipse.escet.releng.target,cif/org.eclipse.escet.cif.documentation --also-make"/>
     <booleanAttribute key="M2_NON_RECURSIVE" value="false"/>
@@ -15,6 +16,7 @@
     <booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="true"/>
     <stringAttribute key="M2_USER_SETTINGS" value=""/>
     <booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="false"/>
+    <booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
     <stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${workspace}"/>
     <mapAttribute key="org.eclipse.debug.core.environmentVariables">
         <mapEntry key="JAVA_HOME" value="${system_property:java.home}"/>
diff --git a/cif/org.eclipse.escet.cif.documentation/pom.xml b/cif/org.eclipse.escet.cif.documentation/pom.xml
index acfd28e9958dfc66a4834fbad49acdd14ea50f07..65a63b3cf320a7de530ce83a913de0d5fcec2772 100644
--- a/cif/org.eclipse.escet.cif.documentation/pom.xml
+++ b/cif/org.eclipse.escet.cif.documentation/pom.xml
@@ -16,7 +16,7 @@
     <parent>
         <groupId>org.eclipse.escet</groupId>
         <artifactId>org.eclipse.escet.root</artifactId>
-        <version>0.9.0-SNAPSHOT</version>
+        <version>0.10.0-SNAPSHOT</version>
         <relativePath>../../</relativePath>
     </parent>
 
diff --git a/cif/org.eclipse.escet.cif.eventbased/.settings/org.eclipse.jdt.core.prefs b/cif/org.eclipse.escet.cif.eventbased/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/cif/org.eclipse.escet.cif.eventbased/.settings/org.eclipse.jdt.core.prefs
+++ b/cif/org.eclipse.escet.cif.eventbased/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/cif/org.eclipse.escet.cif.eventbased/.settings/org.eclipse.jdt.ui.prefs b/cif/org.eclipse.escet.cif.eventbased/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/cif/org.eclipse.escet.cif.eventbased/.settings/org.eclipse.jdt.ui.prefs
+++ b/cif/org.eclipse.escet.cif.eventbased/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/cif/org.eclipse.escet.cif.eventbased/.settings/org.eclipse.ltk.core.refactoring.prefs b/cif/org.eclipse.escet.cif.eventbased/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.eventbased/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/cif/org.eclipse.escet.cif.eventbased/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.eventbased/META-INF/MANIFEST.MF
index 7f8209c9971d5c7c0c3b0d3f555df7f5a44cc636..b3842f785997805fccd9bae4f16a2c10859e9e7b 100644
--- a/cif/org.eclipse.escet.cif.eventbased/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.eventbased/META-INF/MANIFEST.MF
@@ -2,23 +2,23 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET CIF Event-based Synthesis (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.cif.eventbased;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
  org.apache.commons.lang3;bundle-version="3.1.0",
- org.eclipse.escet.cif.common;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel.java;bundle-version="0.9.0",
- org.eclipse.escet.cif.cif2cif;bundle-version="0.9.0",
- org.eclipse.escet.cif.io;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
- org.eclipse.escet.cif.parser;bundle-version="0.9.0",
- org.eclipse.escet.cif.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.common.eclipse.ui;bundle-version="0.9.0",
+ org.eclipse.escet.cif.common;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel.java;bundle-version="0.10.0",
+ org.eclipse.escet.cif.cif2cif;bundle-version="0.10.0",
+ org.eclipse.escet.cif.io;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.cif.parser;bundle-version="0.10.0",
+ org.eclipse.escet.cif.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.common.eclipse.ui;bundle-version="0.10.0",
  org.eclipse.core.resources;bundle-version="3.13.600",
  org.eclipse.swt;bundle-version="3.113.0",
  org.eclipse.core.runtime;bundle-version="3.17.0",
diff --git a/cif/org.eclipse.escet.cif.eventbased/src/org/eclipse/escet/cif/eventbased/SupervisorSynthesis.java b/cif/org.eclipse.escet.cif.eventbased/src/org/eclipse/escet/cif/eventbased/SupervisorSynthesis.java
index 5f38df9fb2bf492f3cba1a5e34d75478ce4d6ae0..b819205a4d805e8146d6d39fa182128f2b99f80d 100644
--- a/cif/org.eclipse.escet.cif.eventbased/src/org/eclipse/escet/cif/eventbased/SupervisorSynthesis.java
+++ b/cif/org.eclipse.escet.cif.eventbased/src/org/eclipse/escet/cif/eventbased/SupervisorSynthesis.java
@@ -85,7 +85,7 @@ public class SupervisorSynthesis {
      *
      * <p>
      * Note that some checks produce warning messages rather than rejecting the input. Such checks are technically not a
-     * requirement for performing synthesis. but if such a check fails (and produces a warning), the synthesis result is
+     * requirement for performing synthesis, but if such a check fails (and produces a warning), the synthesis result is
      * unlikely to be useful.
      * </p>
      *
@@ -140,10 +140,20 @@ public class SupervisorSynthesis {
             }
         }
 
+        // Warn for no requirements.
+        if (reqs.isEmpty()) {
+            String msg = "The specification has no requirement automata.";
+            OutputProvider.warn(msg);
+            warnCount++;
+        }
+
+        // Check for at least one plant.
         if (plants.isEmpty()) {
             String msg = "Supervisor synthesis needs at least one plant automaton.";
             throw new InvalidInputException(msg);
         }
+
+        // Check for no marker state.
         if (unmarked) {
             String msg = "Supervisor is empty (no marker states).";
             throw new InvalidModelException(msg);
@@ -170,7 +180,6 @@ public class SupervisorSynthesis {
         }
 
         // Extra non-fatal checks for things that are probably not right.
-
         if (warnEmpty || warnDeadlock) {
             for (Automaton aut: automs) {
                 // Automaton should have a non-empty alphabet.
diff --git a/cif/org.eclipse.escet.cif.eventbased/src/org/eclipse/escet/cif/eventbased/apps/SynthesisAnalysisApplication.java b/cif/org.eclipse.escet.cif.eventbased/src/org/eclipse/escet/cif/eventbased/apps/SynthesisAnalysisApplication.java
index 8a5f6261f16740fa506bf5241d5451bbaa8ea94e..8cdb22206ce91bdc9ec9986344df60c3f157e821 100644
--- a/cif/org.eclipse.escet.cif.eventbased/src/org/eclipse/escet/cif/eventbased/apps/SynthesisAnalysisApplication.java
+++ b/cif/org.eclipse.escet.cif.eventbased/src/org/eclipse/escet/cif/eventbased/apps/SynthesisAnalysisApplication.java
@@ -89,8 +89,10 @@ public class SynthesisAnalysisApplication extends Application<IOutputComponent>
 
     @Override
     protected int runInternal() {
-        ControlEditor.show(InputFileOption.getPath(), SynthesisAnalysisEditor.class,
+        ControlEditor editor = ControlEditor.show(InputFileOption.getPath(), SynthesisAnalysisEditor.class,
                 "show the event-based synthesis analysis tool");
+
+        editor.waitUntilClosed();
         return 0;
     }
 
diff --git a/cif/org.eclipse.escet.cif.eventdisabler/.settings/org.eclipse.jdt.core.prefs b/cif/org.eclipse.escet.cif.eventdisabler/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/cif/org.eclipse.escet.cif.eventdisabler/.settings/org.eclipse.jdt.core.prefs
+++ b/cif/org.eclipse.escet.cif.eventdisabler/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/cif/org.eclipse.escet.cif.eventdisabler/.settings/org.eclipse.jdt.ui.prefs b/cif/org.eclipse.escet.cif.eventdisabler/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/cif/org.eclipse.escet.cif.eventdisabler/.settings/org.eclipse.jdt.ui.prefs
+++ b/cif/org.eclipse.escet.cif.eventdisabler/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/cif/org.eclipse.escet.cif.eventdisabler/.settings/org.eclipse.ltk.core.refactoring.prefs b/cif/org.eclipse.escet.cif.eventdisabler/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.eventdisabler/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/cif/org.eclipse.escet.cif.eventdisabler/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.eventdisabler/META-INF/MANIFEST.MF
index 34444a76c9cd9d0a54d716094e741ac515957320..a094d7c71ff6a52d125b11ab3d52b70367bf325e 100644
--- a/cif/org.eclipse.escet.cif.eventdisabler/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.eventdisabler/META-INF/MANIFEST.MF
@@ -2,23 +2,23 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET CIF Event Disabler (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.cif.eventdisabler;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.common.eclipse.ui;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.common.eclipse.ui;bundle-version="0.10.0",
  org.eclipse.core.resources;bundle-version="3.13.600",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.cif.io;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
- org.eclipse.escet.cif.parser;bundle-version="0.9.0",
- org.eclipse.escet.cif.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.cif.common;bundle-version="0.9.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.cif.io;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.cif.parser;bundle-version="0.10.0",
+ org.eclipse.escet.cif.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.cif.common;bundle-version="0.10.0",
  org.apache.commons.lang3;bundle-version="3.1.0",
  org.apache.commons.io;bundle-version="2.6.0",
- org.eclipse.escet.cif.metamodel.java;bundle-version="0.9.0"
+ org.eclipse.escet.cif.metamodel.java;bundle-version="0.10.0"
 Bundle-Vendor: Eclipse ESCET
 Automatic-Module-Name: org.eclipse.escet.cif.eventdisabler
 Export-Package: org.eclipse.escet.cif.eventdisabler,
diff --git a/cif/org.eclipse.escet.cif.examples/.settings/org.eclipse.jdt.core.prefs b/cif/org.eclipse.escet.cif.examples/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/cif/org.eclipse.escet.cif.examples/.settings/org.eclipse.jdt.core.prefs
+++ b/cif/org.eclipse.escet.cif.examples/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/cif/org.eclipse.escet.cif.examples/.settings/org.eclipse.jdt.ui.prefs b/cif/org.eclipse.escet.cif.examples/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/cif/org.eclipse.escet.cif.examples/.settings/org.eclipse.jdt.ui.prefs
+++ b/cif/org.eclipse.escet.cif.examples/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/cif/org.eclipse.escet.cif.examples/.settings/org.eclipse.ltk.core.refactoring.prefs b/cif/org.eclipse.escet.cif.examples/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.examples/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/cif/org.eclipse.escet.cif.examples/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.examples/META-INF/MANIFEST.MF
index e92471cc2574d4160798406a48af77d5b3627141..6b6f4be4883160700b21924b148aeef28e7d27c1 100644
--- a/cif/org.eclipse.escet.cif.examples/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.examples/META-INF/MANIFEST.MF
@@ -2,11 +2,11 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET CIF Examples (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.cif.examples;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
-Require-Bundle: org.eclipse.escet.cif.examples;bundle-version="0.9.0",
- org.eclipse.escet.common.eclipse.ui;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0"
+Require-Bundle: org.eclipse.escet.cif.examples;bundle-version="0.10.0",
+ org.eclipse.escet.common.eclipse.ui;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0"
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
 Export-Package: org.eclipse.escet.cif.examples
diff --git a/cif/org.eclipse.escet.cif.examples/benchmarks/benchmark__base.tooldef b/cif/org.eclipse.escet.cif.examples/benchmarks/benchmark__base.tooldef
index 1a02c39abfb2d5f90d0922b1bd6146650308df48..453c8b22d1fd4b7fbb5ab8098c90285324fd521d 100644
--- a/cif/org.eclipse.escet.cif.examples/benchmarks/benchmark__base.tooldef
+++ b/cif/org.eclipse.escet.cif.examples/benchmarks/benchmark__base.tooldef
@@ -105,7 +105,7 @@ tool benchmark(string benchmark_name, string folder, string model_file_name):
 
         // Perform synthesis, measuring the performance.
         long time_pre = currentTimeMillis();
-        cifdatasynth(fmt("%s/%s", folder, model_file_name), "-m debug", "--event-warn=no", "-o " + result_file,
+        cifdatasynth(fmt("%s/%s", folder, model_file_name), "--event-warn=no", "-o " + result_file,
                      "--stats=bdd-perf-max-nodes,bdd-perf-cache -t nodes", config,
                      stdout=stdout_file, stderr=stderr_file, ignoreNonZeroExitCode=true);
         long time_post = currentTimeMillis();
diff --git a/cif/org.eclipse.escet.cif.explorer/.settings/org.eclipse.jdt.core.prefs b/cif/org.eclipse.escet.cif.explorer/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/cif/org.eclipse.escet.cif.explorer/.settings/org.eclipse.jdt.core.prefs
+++ b/cif/org.eclipse.escet.cif.explorer/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/cif/org.eclipse.escet.cif.explorer/.settings/org.eclipse.jdt.ui.prefs b/cif/org.eclipse.escet.cif.explorer/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/cif/org.eclipse.escet.cif.explorer/.settings/org.eclipse.jdt.ui.prefs
+++ b/cif/org.eclipse.escet.cif.explorer/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/cif/org.eclipse.escet.cif.explorer/.settings/org.eclipse.ltk.core.refactoring.prefs b/cif/org.eclipse.escet.cif.explorer/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.explorer/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/cif/org.eclipse.escet.cif.explorer/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.explorer/META-INF/MANIFEST.MF
index 75702bfe08ef315e98263b62c8b358464a09a062..7bad64e4dbe04e67d3c5273e65fb883a5af9956b 100644
--- a/cif/org.eclipse.escet.cif.explorer/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.explorer/META-INF/MANIFEST.MF
@@ -2,26 +2,27 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET CIF State Space Explorer (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.cif.explorer;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-Vendor: Eclipse ESCET
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.cif.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel.java;bundle-version="0.9.0",
- org.eclipse.escet.common.emf;bundle-version="0.9.0",
- org.eclipse.escet.cif.common;bundle-version="0.9.0",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.common.eclipse.ui;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.cif.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel.java;bundle-version="0.10.0",
+ org.eclipse.escet.common.emf;bundle-version="0.10.0",
+ org.eclipse.escet.cif.common;bundle-version="0.10.0",
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.common.eclipse.ui;bundle-version="0.10.0",
  org.eclipse.core.resources;bundle-version="3.13.600",
- org.eclipse.escet.cif.io;bundle-version="0.9.0",
- org.eclipse.escet.cif.cif2cif;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
- org.eclipse.escet.cif.parser;bundle-version="0.9.0",
- org.eclipse.escet.cif.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
+ org.eclipse.escet.cif.io;bundle-version="0.10.0",
+ org.eclipse.escet.cif.cif2cif;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.cif.parser;bundle-version="0.10.0",
+ org.eclipse.escet.cif.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
  org.apache.commons.lang3;bundle-version="3.1.0",
- org.eclipse.escet.common.box;bundle-version="0.9.0"
+ org.eclipse.escet.common.box;bundle-version="0.10.0",
+ org.eclipse.escet.cif.checkers;bundle-version="0.10.0"
 Export-Package: org.eclipse.escet.cif.explorer,
  org.eclipse.escet.cif.explorer.app,
  org.eclipse.escet.cif.explorer.app.common,
diff --git a/cif/org.eclipse.escet.cif.explorer/src/org/eclipse/escet/cif/explorer/RequirementAsPlantChecker.java b/cif/org.eclipse.escet.cif.explorer/src/org/eclipse/escet/cif/explorer/RequirementAsPlantChecker.java
new file mode 100644
index 0000000000000000000000000000000000000000..c0e4a2ddc5f2d01d82ce25d77dfe3c1fc8fa603b
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.explorer/src/org/eclipse/escet/cif/explorer/RequirementAsPlantChecker.java
@@ -0,0 +1,37 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.explorer;
+
+import org.eclipse.escet.cif.common.checkers.CifCheck;
+import org.eclipse.escet.cif.common.checkers.CifCheckViolations;
+import org.eclipse.escet.cif.metamodel.cif.Invariant;
+import org.eclipse.escet.cif.metamodel.cif.SupKind;
+import org.eclipse.escet.cif.metamodel.cif.automata.Automaton;
+
+/** CIF check for requirements that will be explored as plants. */
+public class RequirementAsPlantChecker extends CifCheck {
+    @Override
+    protected void preprocessAutomaton(Automaton aut, CifCheckViolations violations) {
+        if (aut.getKind() == SupKind.REQUIREMENT) {
+            violations.add(aut, "Automaton is a requirement, but will be explored as a plant");
+        }
+    }
+
+    @Override
+    protected void preprocessInvariant(Invariant inv, CifCheckViolations violations) {
+        if (inv.getSupKind() == SupKind.REQUIREMENT) {
+            violations.add(inv, "Invariant is a requirement, but will be explored as a plant");
+        }
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.explorer/src/org/eclipse/escet/cif/explorer/app/ExplorerApplication.java b/cif/org.eclipse.escet.cif.explorer/src/org/eclipse/escet/cif/explorer/app/ExplorerApplication.java
index 3b60f7d8687361f8ba61f3f9a8decfc2a0c5f35d..ed85e4a196ae7fc464ca688d9cb54a2829538ecb 100644
--- a/cif/org.eclipse.escet.cif.explorer/src/org/eclipse/escet/cif/explorer/app/ExplorerApplication.java
+++ b/cif/org.eclipse.escet.cif.explorer/src/org/eclipse/escet/cif/explorer/app/ExplorerApplication.java
@@ -15,6 +15,7 @@ package org.eclipse.escet.cif.explorer.app;
 
 import static org.eclipse.escet.common.app.framework.output.OutputProvider.out;
 import static org.eclipse.escet.common.app.framework.output.OutputProvider.warn;
+import static org.eclipse.escet.common.java.Lists.concat;
 import static org.eclipse.escet.common.java.Lists.list;
 
 import java.util.ArrayDeque;
@@ -26,10 +27,13 @@ import org.eclipse.escet.cif.cif2cif.ElimComponentDefInst;
 import org.eclipse.escet.cif.cif2cif.ElimSelf;
 import org.eclipse.escet.cif.cif2cif.RemoveIoDecls;
 import org.eclipse.escet.cif.cif2cif.SimplifyValuesNoRefsOptimized;
+import org.eclipse.escet.cif.common.checkers.CifCheckViolations;
+import org.eclipse.escet.cif.common.checkers.CifChecker;
 import org.eclipse.escet.cif.explorer.CifAutomatonBuilder;
 import org.eclipse.escet.cif.explorer.ExplorerPreChecker;
 import org.eclipse.escet.cif.explorer.ExplorerPreChecker.CheckParameters;
 import org.eclipse.escet.cif.explorer.ExplorerStateFactory;
+import org.eclipse.escet.cif.explorer.RequirementAsPlantChecker;
 import org.eclipse.escet.cif.explorer.app.common.EnableCifOutputOption;
 import org.eclipse.escet.cif.explorer.app.common.EnableReportOption;
 import org.eclipse.escet.cif.explorer.app.common.ReportFileOption;
@@ -249,6 +253,7 @@ public class ExplorerApplication extends Application<IOutputComponent> {
         // Read CIF file.
         CifReader cifReader = new CifReader().init();
         Specification spec = cifReader.read();
+        String absSpecPath = Paths.resolve(InputFileOption.getPath());
         if (isTerminationRequested()) {
             return 0;
         }
@@ -270,7 +275,7 @@ public class ExplorerApplication extends Application<IOutputComponent> {
             return 0;
         }
 
-        // Check specification.
+        // Check specification for being supported.
         EnumSet<CheckParameters> params = EnumSet.allOf(CheckParameters.class);
         ExplorerPreChecker checker = new ExplorerPreChecker(params);
         checker.checkSpec(spec);
@@ -278,6 +283,17 @@ public class ExplorerApplication extends Application<IOutputComponent> {
             return 0;
         }
 
+        // Warn about features of the specification that may lead to an unexpected resulting state space.
+        CifCheckViolations warnings = new CifChecker(new RequirementAsPlantChecker()).check(spec, absSpecPath);
+        if (warnings.hasViolations()) {
+            warn(String.join("\n",
+                    concat("The CIF specification has features that may cause an unexpected resulting state space:",
+                            warnings.createReport())));
+        }
+        if (isTerminationRequested()) {
+            return 0;
+        }
+
         // Explore the state space.
         Explorer e;
         try {
diff --git a/cif/org.eclipse.escet.cif.feature/feature.xml b/cif/org.eclipse.escet.cif.feature/feature.xml
index 92cb26e2f1ddf1027f7956ce616d6a615c5098dd..8a3512b690372da12878df7ac7308be18af8e3a7 100644
--- a/cif/org.eclipse.escet.cif.feature/feature.xml
+++ b/cif/org.eclipse.escet.cif.feature/feature.xml
@@ -13,11 +13,11 @@
 <feature
       id="org.eclipse.escet.cif.feature"
       label="ESCET CIF (Incubation)"
-      version="0.9.0.qualifier"
+      version="0.10.0.qualifier"
       provider-name="Eclipse ESCET"
       plugin="org.eclipse.escet.product.branding"
       license-feature="org.eclipse.escet.releng.license.mit"
-      license-feature-version="0.9.0.qualifier">
+      license-feature-version="0.10.0.qualifier">
 
    <description>
       Eclipse ESCET tooling for the CIF language.
@@ -32,9 +32,8 @@
    </license>
 
    <requires>
-      <import feature="org.eclipse.escet.common.feature" version="0.9.0.qualifier"/>
-      <import feature="org.eclipse.escet.setext.feature" version="0.9.0.qualifier"/>
-      <import feature="com.github.javabdd.feature" version="4.0.0.qualifier"/>
+      <import feature="org.eclipse.escet.common.feature" version="0.10.0.qualifier"/>
+      <import feature="org.eclipse.escet.setext.feature" version="0.10.0.qualifier"/>
       <import plugin="org.apache.commons.io"/>
       <import plugin="org.apache.commons.math3"/>
       <import plugin="org.knowm.xchart"/>
diff --git a/cif/org.eclipse.escet.cif.io/.settings/org.eclipse.jdt.core.prefs b/cif/org.eclipse.escet.cif.io/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/cif/org.eclipse.escet.cif.io/.settings/org.eclipse.jdt.core.prefs
+++ b/cif/org.eclipse.escet.cif.io/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/cif/org.eclipse.escet.cif.io/.settings/org.eclipse.jdt.ui.prefs b/cif/org.eclipse.escet.cif.io/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/cif/org.eclipse.escet.cif.io/.settings/org.eclipse.jdt.ui.prefs
+++ b/cif/org.eclipse.escet.cif.io/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/cif/org.eclipse.escet.cif.io/.settings/org.eclipse.ltk.core.refactoring.prefs b/cif/org.eclipse.escet.cif.io/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.io/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/cif/org.eclipse.escet.cif.io/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.io/META-INF/MANIFEST.MF
index 7dfe9da56d5195f10056e4124e053feb0c940ecb..b0456abbe82231ecf3144694351232f93d56facd 100644
--- a/cif/org.eclipse.escet.cif.io/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.io/META-INF/MANIFEST.MF
@@ -2,20 +2,20 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET CIF I/O (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.cif.io;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.cif.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.cif.parser;bundle-version="0.9.0",
- org.eclipse.escet.common.box;bundle-version="0.9.0",
- org.eclipse.escet.cif.prettyprinter;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.cif.common;bundle-version="0.9.0"
+Require-Bundle: org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.cif.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.cif.parser;bundle-version="0.10.0",
+ org.eclipse.escet.common.box;bundle-version="0.10.0",
+ org.eclipse.escet.cif.prettyprinter;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.cif.common;bundle-version="0.10.0"
 Export-Package: org.eclipse.escet.cif.io,
  org.eclipse.escet.cif.io.emf
 Automatic-Module-Name: org.eclipse.escet.cif.io
diff --git a/cif/org.eclipse.escet.cif.merger/.settings/org.eclipse.jdt.core.prefs b/cif/org.eclipse.escet.cif.merger/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/cif/org.eclipse.escet.cif.merger/.settings/org.eclipse.jdt.core.prefs
+++ b/cif/org.eclipse.escet.cif.merger/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/cif/org.eclipse.escet.cif.merger/.settings/org.eclipse.jdt.ui.prefs b/cif/org.eclipse.escet.cif.merger/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/cif/org.eclipse.escet.cif.merger/.settings/org.eclipse.jdt.ui.prefs
+++ b/cif/org.eclipse.escet.cif.merger/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/cif/org.eclipse.escet.cif.merger/.settings/org.eclipse.ltk.core.refactoring.prefs b/cif/org.eclipse.escet.cif.merger/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.merger/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/cif/org.eclipse.escet.cif.merger/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.merger/META-INF/MANIFEST.MF
index 6dbcbf792a4462761c1625beca7b7d6fbc725e14..7744c866d421f03a0f1987e8805bee361475b585 100644
--- a/cif/org.eclipse.escet.cif.merger/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.merger/META-INF/MANIFEST.MF
@@ -2,25 +2,25 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET CIF Merger (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.cif.merger;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
 Require-Bundle: org.eclipse.core.resources;bundle-version="3.13.600",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.common.eclipse.ui;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.cif.io;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
- org.eclipse.escet.cif.parser;bundle-version="0.9.0",
- org.eclipse.escet.cif.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.cif.prettyprinter;bundle-version="0.9.0",
- org.eclipse.escet.common.box;bundle-version="0.9.0",
- org.eclipse.escet.cif.cif2cif;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel.java;bundle-version="0.9.0",
- org.eclipse.escet.cif.common;bundle-version="0.9.0",
- org.eclipse.escet.common.emf;bundle-version="0.9.0"
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.common.eclipse.ui;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.cif.io;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.cif.parser;bundle-version="0.10.0",
+ org.eclipse.escet.cif.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.cif.prettyprinter;bundle-version="0.10.0",
+ org.eclipse.escet.common.box;bundle-version="0.10.0",
+ org.eclipse.escet.cif.cif2cif;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel.java;bundle-version="0.10.0",
+ org.eclipse.escet.cif.common;bundle-version="0.10.0",
+ org.eclipse.escet.common.emf;bundle-version="0.10.0"
 Automatic-Module-Name: org.eclipse.escet.cif.merger
 Export-Package: org.eclipse.escet.cif.merger
diff --git a/cif/org.eclipse.escet.cif.metamodel.java/.settings/org.eclipse.jdt.core.prefs b/cif/org.eclipse.escet.cif.metamodel.java/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/cif/org.eclipse.escet.cif.metamodel.java/.settings/org.eclipse.jdt.core.prefs
+++ b/cif/org.eclipse.escet.cif.metamodel.java/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/cif/org.eclipse.escet.cif.metamodel.java/.settings/org.eclipse.jdt.ui.prefs b/cif/org.eclipse.escet.cif.metamodel.java/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/cif/org.eclipse.escet.cif.metamodel.java/.settings/org.eclipse.jdt.ui.prefs
+++ b/cif/org.eclipse.escet.cif.metamodel.java/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/cif/org.eclipse.escet.cif.metamodel.java/.settings/org.eclipse.ltk.core.refactoring.prefs b/cif/org.eclipse.escet.cif.metamodel.java/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.metamodel.java/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/cif/org.eclipse.escet.cif.metamodel.java/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.metamodel.java/META-INF/MANIFEST.MF
index 66d9be41a790587970ae49356653fe5c96186b43..1b6c4d3d5ad86e70929ad6091a1a5b7c86db2ca3 100644
--- a/cif/org.eclipse.escet.cif.metamodel.java/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.metamodel.java/META-INF/MANIFEST.MF
@@ -2,12 +2,12 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET CIF Metamodel Java Support (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.cif.metamodel.java;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.common.position.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0"
+Require-Bundle: org.eclipse.escet.common.position.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0"
 Export-Package: org.eclipse.escet.cif.metamodel.java
 Automatic-Module-Name: org.eclipse.escet.cif.metamodel.java
diff --git a/cif/org.eclipse.escet.cif.metamodel/.settings/org.eclipse.jdt.core.prefs b/cif/org.eclipse.escet.cif.metamodel/.settings/org.eclipse.jdt.core.prefs
index a39882dc615f390c7a829a2c18eb7f17ffd8668b..eabbae9d848583c4a9412f97a7c7b9c9b344ef90 100644
--- a/cif/org.eclipse.escet.cif.metamodel/.settings/org.eclipse.jdt.core.prefs
+++ b/cif/org.eclipse.escet.cif.metamodel/.settings/org.eclipse.jdt.core.prefs
@@ -126,6 +126,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/cif/org.eclipse.escet.cif.metamodel/.settings/org.eclipse.ltk.core.refactoring.prefs b/cif/org.eclipse.escet.cif.metamodel/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.metamodel/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/cif/org.eclipse.escet.cif.metamodel/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.metamodel/META-INF/MANIFEST.MF
index 564add635f6fc606d3db6e48ab9ffc27618f54cd..152cae71d13c493fc621af5dc4dd3222a77e0b55 100644
--- a/cif/org.eclipse.escet.cif.metamodel/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.metamodel/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.escet.cif.metamodel;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-ClassPath: .
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
@@ -33,8 +33,8 @@ Export-Package: org.eclipse.escet.cif.metamodel.cif,
  org.eclipse.escet.cif.metamodel.cif.util
 Require-Bundle: org.eclipse.core.runtime;bundle-version="3.17.0",
  org.eclipse.emf.ecore;bundle-version="2.20.0";visibility:=reexport,
- org.eclipse.escet.common.position.metamodel;bundle-version="0.9.0";visibility:=reexport,
- org.eclipse.escet.common.emf.ecore.xmi;bundle-version="0.9.0",
+ org.eclipse.escet.common.position.metamodel;bundle-version="0.10.0";visibility:=reexport,
+ org.eclipse.escet.common.emf.ecore.xmi;bundle-version="0.10.0",
  org.eclipse.emf.common;bundle-version="2.17.0"
 Bundle-ActivationPolicy: lazy
 Automatic-Module-Name: org.eclipse.escet.cif.metamodel
diff --git a/cif/org.eclipse.escet.cif.metamodel/docs/cif_ecore_doc.bib b/cif/org.eclipse.escet.cif.metamodel/docs/cif_ecore_doc.bib
index 596e3581aba98c879558b701f1be64d0db51e74f..406245078b42c50d8a7b42671ed215f5c75c0364 100644
--- a/cif/org.eclipse.escet.cif.metamodel/docs/cif_ecore_doc.bib
+++ b/cif/org.eclipse.escet.cif.metamodel/docs/cif_ecore_doc.bib
@@ -1,7 +1,7 @@
 @misc{Eclipse:ESCET,
   author = {Contributors to the Eclipse Foundation},
   title = {{Eclipse Supervisory Control Engineering Toolkit (Eclipse ESCET)}},
-  howpublished = {\url{https://eclipse.org/escet}}
+  howpublished = {\url{https://eclipse.dev/escet}}
 }
 
 @misc{Eclipse:Incubation,
diff --git a/cif/org.eclipse.escet.cif.metamodel/docs/cif_ecore_doc.pdf b/cif/org.eclipse.escet.cif.metamodel/docs/cif_ecore_doc.pdf
index cc8cdd800e9de53d2039b21adae478de8eb5dc14..c43d919fe2ba62e0d17ba6005b9ffa193285c66e 100644
Binary files a/cif/org.eclipse.escet.cif.metamodel/docs/cif_ecore_doc.pdf and b/cif/org.eclipse.escet.cif.metamodel/docs/cif_ecore_doc.pdf differ
diff --git a/cif/org.eclipse.escet.cif.metamodel/docs/cif_ecore_doc.tex b/cif/org.eclipse.escet.cif.metamodel/docs/cif_ecore_doc.tex
index 5b7a47428ff133145e5d8fa6a9478e1b277a73eb..450f15a84e31b444950b97ced92cf2250ed03978 100644
--- a/cif/org.eclipse.escet.cif.metamodel/docs/cif_ecore_doc.tex
+++ b/cif/org.eclipse.escet.cif.metamodel/docs/cif_ecore_doc.tex
@@ -103,7 +103,7 @@
 % Document settings.
 \title{Compositional Interchange Format (CIF) Metamodel Reference Documentation (Incubation)}
 \author{Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation}
-\date{Version 2023-02-27}
+\date{Version 2023-05-08}
 \titlepic{\includegraphics[width=0.5\textwidth]{figures/eclipse-incubation.png}}
 
 % Start of document.
diff --git a/cif/org.eclipse.escet.cif.metamodel/docs/cif_ecore_doc_details.tex b/cif/org.eclipse.escet.cif.metamodel/docs/cif_ecore_doc_details.tex
index f26da608378969b736edd8ba8bcb8189962a678c..42e6a3e04045e4efafbe8838eee7f18f59914811 100644
--- a/cif/org.eclipse.escet.cif.metamodel/docs/cif_ecore_doc_details.tex
+++ b/cif/org.eclipse.escet.cif.metamodel/docs/cif_ecore_doc_details.tex
@@ -3575,15 +3575,15 @@ A switch expression.
   `value' expressions of the `cases'. This implies that those expressions must
   be type compatible (ignoring ranges).
 \citem{SwitchExpression.complete}
-  If the `value' refers to an automaton, the `cases' must be complete for all
-  locations of the automaton.
+  The `cases', possibly including an `else`, must be complete for all locations
+  of the automaton, or all possible values of the type of the switch value
+  otherwise.
 \citem{SwitchExpression.overspecified}
-  If the `value' refers to an automaton, the `cases' must not be overspecified
-  (same location multiple times as \emph{key} of one of a case).
+  The `cases' must not be overspecified (same location or value multiple times
+  as \emph{key} of one of the cases).
 \citemnf{SwitchExpression.superfluousElse}
-  If the `value' refers to an automaton, the `cases' must not be overspecified
-  (an `else' is present while all locations are already specified as `key' of
-  a case).
+  The `cases' must not be overspecified (an `else' is present while all
+  locations or values are already specified as `key' of a case).
 \end{constraints}
 }
 
diff --git a/cif/org.eclipse.escet.cif.multilevel/.settings/org.eclipse.jdt.core.prefs b/cif/org.eclipse.escet.cif.multilevel/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/cif/org.eclipse.escet.cif.multilevel/.settings/org.eclipse.jdt.core.prefs
+++ b/cif/org.eclipse.escet.cif.multilevel/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/cif/org.eclipse.escet.cif.multilevel/.settings/org.eclipse.jdt.ui.prefs b/cif/org.eclipse.escet.cif.multilevel/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/cif/org.eclipse.escet.cif.multilevel/.settings/org.eclipse.jdt.ui.prefs
+++ b/cif/org.eclipse.escet.cif.multilevel/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/cif/org.eclipse.escet.cif.multilevel/.settings/org.eclipse.ltk.core.refactoring.prefs b/cif/org.eclipse.escet.cif.multilevel/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.multilevel/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/cif/org.eclipse.escet.cif.multilevel/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.multilevel/META-INF/MANIFEST.MF
index 1e74300bd53fb0ddb07d9c54f603bfe886f66d49..4ece18a9a3b48053d35a166bed9fee71760327e7 100644
--- a/cif/org.eclipse.escet.cif.multilevel/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.multilevel/META-INF/MANIFEST.MF
@@ -2,24 +2,24 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET CIF Multi-level Synthesis (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.cif.multilevel;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.cif.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
- org.eclipse.escet.cif.cif2cif;bundle-version="0.9.0",
- org.eclipse.escet.cif.io;bundle-version="0.9.0",
- org.eclipse.escet.cif.parser;bundle-version="0.9.0",
- org.eclipse.escet.cif.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel.java;bundle-version="0.9.0",
- org.eclipse.escet.common.dsm;bundle-version="0.9.0",
- org.eclipse.escet.cif.common;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.cif.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.cif.cif2cif;bundle-version="0.10.0",
+ org.eclipse.escet.cif.io;bundle-version="0.10.0",
+ org.eclipse.escet.cif.parser;bundle-version="0.10.0",
+ org.eclipse.escet.cif.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel.java;bundle-version="0.10.0",
+ org.eclipse.escet.common.dsm;bundle-version="0.10.0",
+ org.eclipse.escet.cif.common;bundle-version="0.10.0",
  org.apache.commons.math3;bundle-version="3.6.1",
- org.eclipse.escet.cif.checkers;bundle-version="0.9.0"
+ org.eclipse.escet.cif.checkers;bundle-version="0.10.0"
 Automatic-Module-Name: org.eclipse.escet.cif.multilevel
 Export-Package: org.eclipse.escet.cif.multilevel,
  org.eclipse.escet.cif.multilevel.ciftodmm
diff --git a/cif/org.eclipse.escet.cif.parser/.settings/org.eclipse.jdt.core.prefs b/cif/org.eclipse.escet.cif.parser/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/cif/org.eclipse.escet.cif.parser/.settings/org.eclipse.jdt.core.prefs
+++ b/cif/org.eclipse.escet.cif.parser/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/cif/org.eclipse.escet.cif.parser/.settings/org.eclipse.jdt.ui.prefs b/cif/org.eclipse.escet.cif.parser/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/cif/org.eclipse.escet.cif.parser/.settings/org.eclipse.jdt.ui.prefs
+++ b/cif/org.eclipse.escet.cif.parser/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/cif/org.eclipse.escet.cif.parser/.settings/org.eclipse.ltk.core.refactoring.prefs b/cif/org.eclipse.escet.cif.parser/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.parser/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/cif/org.eclipse.escet.cif.parser/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.parser/META-INF/MANIFEST.MF
index 874d49694353b3cc1d907c9ab827acaa688f02b8..5568a0d4cffa42ab2683ac7395d1ec54263a80d3 100644
--- a/cif/org.eclipse.escet.cif.parser/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.parser/META-INF/MANIFEST.MF
@@ -2,17 +2,17 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET CIF Parser (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.cif.parser;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.common.position.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.common.emf;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
- org.eclipse.escet.common.position.common;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.common.position.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.common.emf;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.common.position.common;bundle-version="0.10.0",
  org.eclipse.jface.text;bundle-version="3.16.100",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0"
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0"
 Export-Package: org.eclipse.escet.cif.parser,
  org.eclipse.escet.cif.parser.ast,
  org.eclipse.escet.cif.parser.ast.automata,
diff --git a/cif/org.eclipse.escet.cif.plcgen/.settings/org.eclipse.jdt.core.prefs b/cif/org.eclipse.escet.cif.plcgen/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/cif/org.eclipse.escet.cif.plcgen/.settings/org.eclipse.jdt.core.prefs
+++ b/cif/org.eclipse.escet.cif.plcgen/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/cif/org.eclipse.escet.cif.plcgen/.settings/org.eclipse.jdt.ui.prefs b/cif/org.eclipse.escet.cif.plcgen/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/cif/org.eclipse.escet.cif.plcgen/.settings/org.eclipse.jdt.ui.prefs
+++ b/cif/org.eclipse.escet.cif.plcgen/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/cif/org.eclipse.escet.cif.plcgen/.settings/org.eclipse.ltk.core.refactoring.prefs b/cif/org.eclipse.escet.cif.plcgen/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/cif/org.eclipse.escet.cif.plcgen/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.plcgen/META-INF/MANIFEST.MF
index 6378c321f386df7b182848e755eb8e69617495cc..737570b1074c4aa5df015084741bb7aa9002ca00 100644
--- a/cif/org.eclipse.escet.cif.plcgen/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.plcgen/META-INF/MANIFEST.MF
@@ -2,31 +2,34 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET CIF PLC Code Generator v2 (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.cif.plcgen;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.cif.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
- org.eclipse.escet.cif.cif2cif;bundle-version="0.9.0",
- org.eclipse.escet.cif.io;bundle-version="0.9.0",
- org.eclipse.escet.cif.parser;bundle-version="0.9.0",
- org.eclipse.escet.cif.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.cif.common;bundle-version="0.9.0",
- org.eclipse.escet.common.box;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel.java;bundle-version="0.9.0",
- org.eclipse.escet.cif.cif2plc;bundle-version="0.9.0",
- org.eclipse.escet.cif.checkers;bundle-version="0.9.0"
+Require-Bundle: org.eclipse.escet.cif.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.cif.cif2cif;bundle-version="0.10.0",
+ org.eclipse.escet.cif.io;bundle-version="0.10.0",
+ org.eclipse.escet.cif.parser;bundle-version="0.10.0",
+ org.eclipse.escet.cif.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.cif.common;bundle-version="0.10.0",
+ org.eclipse.escet.common.box;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel.java;bundle-version="0.10.0",
+ org.eclipse.escet.cif.checkers;bundle-version="0.10.0"
 Automatic-Module-Name: org.eclipse.escet.cif.plcgen
 Export-Package: org.eclipse.escet.cif.plcgen,
  org.eclipse.escet.cif.plcgen.conversion,
+ org.eclipse.escet.cif.plcgen.conversion.expressions,
  org.eclipse.escet.cif.plcgen.generators,
+ org.eclipse.escet.cif.plcgen.model,
+ org.eclipse.escet.cif.plcgen.model.declarations,
  org.eclipse.escet.cif.plcgen.model.expressions,
  org.eclipse.escet.cif.plcgen.model.functions,
  org.eclipse.escet.cif.plcgen.model.statements,
+ org.eclipse.escet.cif.plcgen.model.types,
  org.eclipse.escet.cif.plcgen.options,
  org.eclipse.escet.cif.plcgen.targets,
  org.eclipse.escet.cif.plcgen.writers
diff --git a/cif/org.eclipse.escet.cif.plcgen/src-test/org/eclipse/escet/cif/plcgen/conversions/FuncApplsTest.java b/cif/org.eclipse.escet.cif.plcgen/src-test/org/eclipse/escet/cif/plcgen/conversion/FuncApplsTest.java
similarity index 93%
rename from cif/org.eclipse.escet.cif.plcgen/src-test/org/eclipse/escet/cif/plcgen/conversions/FuncApplsTest.java
rename to cif/org.eclipse.escet.cif.plcgen/src-test/org/eclipse/escet/cif/plcgen/conversion/FuncApplsTest.java
index 066a353d50e216919e2fc74675ab8a1c8fdef4a9..5911d28fc5d9e9c5941291a49d623e9b14b5d58d 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src-test/org/eclipse/escet/cif/plcgen/conversions/FuncApplsTest.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src-test/org/eclipse/escet/cif/plcgen/conversion/FuncApplsTest.java
@@ -11,18 +11,17 @@
 // SPDX-License-Identifier: MIT
 //////////////////////////////////////////////////////////////////////////////
 
-package org.eclipse.escet.cif.plcgen.conversions;
+package org.eclipse.escet.cif.plcgen.conversion;
 
 import static org.junit.Assert.assertEquals;
 
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcElementaryType;
-import org.eclipse.escet.cif.plcgen.conversion.ModelTextGenerator;
-import org.eclipse.escet.cif.plcgen.conversion.PlcFunctionAppls;
 import org.eclipse.escet.cif.plcgen.model.expressions.PlcBoolLiteral;
 import org.eclipse.escet.cif.plcgen.model.expressions.PlcExpression;
 import org.eclipse.escet.cif.plcgen.model.expressions.PlcFuncAppl;
 import org.eclipse.escet.cif.plcgen.model.expressions.PlcIntLiteral;
 import org.eclipse.escet.cif.plcgen.model.expressions.PlcRealLiteral;
+import org.eclipse.escet.cif.plcgen.model.types.PlcElementaryType;
+import org.eclipse.escet.cif.plcgen.targets.PlcOpenXmlTarget;
 import org.junit.Test;
 
 /** Pretty-print function applications test. */
@@ -50,7 +49,7 @@ public class FuncApplsTest {
     private final PlcExpression real2 = new PlcRealLiteral("2.0");
 
     /** Function application generator. */
-    private final PlcFunctionAppls funcAppls = new PlcFunctionAppls();
+    private final PlcFunctionAppls funcAppls = new PlcFunctionAppls(new PlcOpenXmlTarget());
 
     /** Converter of expressions and statements to text. */
     private final ModelTextGenerator textGen = new ModelTextGenerator();
@@ -76,8 +75,8 @@ public class FuncApplsTest {
     }
 
     @Test
-    public void exptFuncApplTest() {
-        assertEquals("1 ** 1.0", toStr(funcAppls.exptFuncAppl(num1, real1)));
+    public void powerFuncApplTest() {
+        assertEquals("1 ** 1.0", toStr(funcAppls.powerFuncAppl(num1, real1)));
     }
 
     @Test(expected = AssertionError.class)
@@ -212,7 +211,7 @@ public class FuncApplsTest {
     @Test
     public void parenthesesTest() {
         PlcFuncAppl negate = funcAppls.negateFuncAppl(num3);
-        PlcFuncAppl expt = funcAppls.exptFuncAppl(num1, real1);
+        PlcFuncAppl power = funcAppls.powerFuncAppl(num1, real1);
         PlcFuncAppl mul = funcAppls.multiplyFuncAppl(num1, num2);
         PlcFuncAppl add = funcAppls.addFuncAppl(num1, num2);
         PlcFuncAppl order = funcAppls.greaterThanFuncAppl(num1, num2);
@@ -222,13 +221,13 @@ public class FuncApplsTest {
         PlcFuncAppl or = funcAppls.orFuncAppl(bool0, bool1);
 
         assertEquals("--3", toStr(funcAppls.negateFuncAppl(negate))); // Same strength.
-        assertEquals("-(1 ** 1.0)", toStr(funcAppls.negateFuncAppl(expt))); // Root first.
+        assertEquals("-(1 ** 1.0)", toStr(funcAppls.negateFuncAppl(power))); // Root first.
 
-        assertEquals("-3 ** -3", toStr(funcAppls.exptFuncAppl(negate, negate))); // Children first.
-        assertEquals("(1 ** 1.0) ** (1 ** 1.0)", toStr(funcAppls.exptFuncAppl(expt, expt))); // Same strength.
-        assertEquals("(1 * 2) ** (1 * 2)", toStr(funcAppls.exptFuncAppl(mul, mul))); // Root first.
+        assertEquals("-3 ** -3", toStr(funcAppls.powerFuncAppl(negate, negate))); // Children first.
+        assertEquals("(1 ** 1.0) ** (1 ** 1.0)", toStr(funcAppls.powerFuncAppl(power, power))); // Same strength.
+        assertEquals("(1 * 2) ** (1 * 2)", toStr(funcAppls.powerFuncAppl(mul, mul))); // Root first.
 
-        assertEquals("1 ** 1.0 * 1 ** 1.0", toStr(funcAppls.multiplyFuncAppl(expt, expt))); // Children first.
+        assertEquals("1 ** 1.0 * 1 ** 1.0", toStr(funcAppls.multiplyFuncAppl(power, power))); // Children first.
         assertEquals("1 * 2 * (1 * 2)", toStr(funcAppls.multiplyFuncAppl(mul, mul))); // Same strength.
         assertEquals("(1 + 2) * (1 + 2)", toStr(funcAppls.multiplyFuncAppl(add, add))); // Root first.
 
diff --git a/cif/org.eclipse.escet.cif.plcgen/src-test/org/eclipse/escet/cif/plcgen/conversion/expressions/ExprGeneratorTest.java b/cif/org.eclipse.escet.cif.plcgen/src-test/org/eclipse/escet/cif/plcgen/conversion/expressions/ExprGeneratorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..d5e83b29e6a3fa4c69269a2faab76fafc8ecd085
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src-test/org/eclipse/escet/cif/plcgen/conversion/expressions/ExprGeneratorTest.java
@@ -0,0 +1,902 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.conversion.expressions;
+
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newBinaryExpression;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newBoolExpression;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newBoolType;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newCastExpression;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newConstant;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newConstantExpression;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newContVariable;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newContVariableExpression;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newDictExpression;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newDiscVariable;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newDiscVariableExpression;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newElifExpression;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newEnumLiteral;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newEnumLiteralExpression;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newField;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newFieldExpression;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newFuncType;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newFunctionCallExpression;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newFunctionExpression;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newIfExpression;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newInputVariable;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newInputVariableExpression;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newIntExpression;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newIntType;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newListExpression;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newListType;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newLocation;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newLocationExpression;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newProjectionExpression;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newRealExpression;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newRealType;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newSliceExpression;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newStdLibFunctionExpression;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newStringExpression;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newTimeExpression;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newTupleExpression;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newTupleType;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newUnaryExpression;
+import static org.eclipse.escet.common.java.Lists.listc;
+import static org.eclipse.escet.common.java.Strings.fmt;
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.eclipse.escet.cif.metamodel.cif.automata.Location;
+import org.eclipse.escet.cif.metamodel.cif.declarations.Constant;
+import org.eclipse.escet.cif.metamodel.cif.declarations.ContVariable;
+import org.eclipse.escet.cif.metamodel.cif.declarations.DiscVariable;
+import org.eclipse.escet.cif.metamodel.cif.declarations.EnumDecl;
+import org.eclipse.escet.cif.metamodel.cif.declarations.EnumLiteral;
+import org.eclipse.escet.cif.metamodel.cif.declarations.InputVariable;
+import org.eclipse.escet.cif.metamodel.cif.expressions.BinaryOperator;
+import org.eclipse.escet.cif.metamodel.cif.expressions.DiscVariableExpression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.ElifExpression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.Expression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.FieldExpression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.ListExpression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.StdLibFunction;
+import org.eclipse.escet.cif.metamodel.cif.expressions.TupleExpression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.UnaryOperator;
+import org.eclipse.escet.cif.metamodel.cif.types.BoolType;
+import org.eclipse.escet.cif.metamodel.cif.types.CifType;
+import org.eclipse.escet.cif.metamodel.cif.types.Field;
+import org.eclipse.escet.cif.metamodel.cif.types.IntType;
+import org.eclipse.escet.cif.metamodel.cif.types.ListType;
+import org.eclipse.escet.cif.metamodel.cif.types.RealType;
+import org.eclipse.escet.cif.metamodel.cif.types.TupleType;
+import org.eclipse.escet.cif.plcgen.PlcGenSettings;
+import org.eclipse.escet.cif.plcgen.WarnOutput;
+import org.eclipse.escet.cif.plcgen.conversion.ModelTextGenerator;
+import org.eclipse.escet.cif.plcgen.generators.CifProcessor;
+import org.eclipse.escet.cif.plcgen.generators.NameGenerator;
+import org.eclipse.escet.cif.plcgen.generators.PlcCodeStorage;
+import org.eclipse.escet.cif.plcgen.generators.TypeGenerator;
+import org.eclipse.escet.cif.plcgen.generators.VariableStorage;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcVariable;
+import org.eclipse.escet.cif.plcgen.model.expressions.PlcEnumLiteral;
+import org.eclipse.escet.cif.plcgen.model.expressions.PlcExpression;
+import org.eclipse.escet.cif.plcgen.model.expressions.PlcVarExpression;
+import org.eclipse.escet.cif.plcgen.model.expressions.PlcVarExpression.PlcProjection;
+import org.eclipse.escet.cif.plcgen.model.expressions.PlcVarExpression.PlcStructProjection;
+import org.eclipse.escet.cif.plcgen.model.functions.PlcFuncOperation;
+import org.eclipse.escet.cif.plcgen.model.types.PlcArrayType;
+import org.eclipse.escet.cif.plcgen.model.types.PlcDerivedType;
+import org.eclipse.escet.cif.plcgen.model.types.PlcElementaryType;
+import org.eclipse.escet.cif.plcgen.model.types.PlcStructType;
+import org.eclipse.escet.cif.plcgen.model.types.PlcType;
+import org.eclipse.escet.cif.plcgen.options.ConvertEnums;
+import org.eclipse.escet.cif.plcgen.options.PlcNumberBits;
+import org.eclipse.escet.cif.plcgen.targets.PlcBaseTarget;
+import org.eclipse.escet.cif.plcgen.targets.PlcTargetType;
+import org.eclipse.escet.cif.plcgen.writers.OutputTypeWriter;
+import org.eclipse.escet.common.java.Assert;
+import org.eclipse.escet.common.position.metamodel.position.PositionObject;
+import org.junit.Before;
+import org.junit.Test;
+
+/** Tests for the expression generator. */
+@SuppressWarnings("javadoc")
+public class ExprGeneratorTest {
+    private static ModelTextGenerator modelToText = new ModelTextGenerator();
+
+    private TestPlcTarget target;
+
+    private ExprGenerator exprGen;
+
+    // in CIF:
+    // - const bool fixed = false;
+    // - input int theInput;
+    // - disc real flatDisc;
+    // - cont timer der 1.0;
+    // - automaton *: location here; end [[only the location is created]]
+    // - disc tuple(real field1, field2, field3) tupVar;
+
+    private static Constant constantVar = newConstant("fixed", null, newBoolType(),
+            newBoolExpression(null, newBoolType(), false));
+
+    private static InputVariable inputVar = newInputVariable("theInput", null, newIntType());
+
+    private static DiscVariable discVar = newDiscVariable("flatDisc", null, newRealType(), null);
+
+    private static ContVariable contVar = newContVariable(newRealExpression(null, newRealType(), "1.0"), "timer", null,
+            null);
+
+    private static Location loc = newLocation(null, null, null, null, null, "here", null, false);
+
+    private static DiscVariable tupVar = newDiscVariable("tupVar", null, makeTupleType(3), null);
+
+    private static TupleType makeTupleType(int length) {
+        List<Field> fields = listc(length);
+        while (fields.size() < length) {
+            fields.add(newField("field" + (fields.size() + 1), null, newRealType()));
+        }
+        return newTupleType(fields, null);
+    }
+
+    private static DiscVariableExpression makeDiscVarExpr() {
+        return newDiscVariableExpression(null, newRealType(), discVar);
+    }
+
+    @Before
+    public void setup() {
+        target = new TestPlcTarget();
+        CifDataProvider cifDataProvider = new TestCifDataProvider();
+        exprGen = new ExprGenerator(target, cifDataProvider);
+    }
+
+    /** PLC target for testing the expression generator. */
+    private static class TestPlcTarget extends PlcBaseTarget {
+        public boolean supportsLog = true;
+
+        private TypeGenerator typeGenerator = new TestTypeGenerator();
+
+        private NameGenerator nameGenerator = new TestNameGenerator();
+
+        public TestPlcTarget() {
+            super(PlcTargetType.IEC_61131_3);
+
+            // Configure the target.
+            String projectName = "projName";
+            String configurationName = "confName";
+            String resourceName = "resName";
+            String plcTaskName = "taskName";
+            int taskCyceTime = 1;
+            int priority = 1;
+            String inputPath = "input/path";
+            String outputPath = "/output/path";
+            PlcNumberBits intSize = PlcNumberBits.BITS_32;
+            PlcNumberBits realSize = PlcNumberBits.BITS_64;
+            boolean simplifyValues = false;
+            ConvertEnums enumConversion = ConvertEnums.NO;
+            Supplier<Boolean> shouldTerminate = () -> false;
+            boolean warnOnRename = false;
+            WarnOutput warnOutput = message -> { /* Do nothing. */ };
+
+            PlcGenSettings settings = new PlcGenSettings(projectName, configurationName, resourceName, plcTaskName,
+                    taskCyceTime, priority, inputPath, "/" + inputPath, outputPath, intSize, realSize, simplifyValues,
+                    enumConversion, shouldTerminate, warnOnRename, warnOutput);
+            setup(settings);
+        }
+
+        @Override
+        public boolean supportsOperation(PlcFuncOperation funcOper) {
+            // LOG support follows the 'supportsLog' variable.
+            if (funcOper.equals(PlcFuncOperation.STDLIB_LOG)) {
+                return supportsLog;
+            }
+            return super.supportsOperation(funcOper);
+        }
+
+        @Override
+        public CifProcessor getCifProcessor() {
+            throw new UnsupportedOperationException("Not needed for the test.");
+        }
+
+        @Override
+        public VariableStorage getVarStorage() {
+            throw new UnsupportedOperationException("Not needed for the test.");
+        }
+
+        @Override
+        public TypeGenerator getTypeGenerator() {
+            return typeGenerator;
+        }
+
+        @Override
+        public PlcCodeStorage getCodeStorage() {
+            throw new UnsupportedOperationException("Not needed for the test.");
+        }
+
+        @Override
+        public NameGenerator getNameGenerator() {
+            return nameGenerator;
+        }
+
+        @Override
+        public boolean supportsArrays() {
+            throw new UnsupportedOperationException("Not needed for the test.");
+        }
+
+        @Override
+        public boolean supportsConstants() {
+            throw new UnsupportedOperationException("Not needed for the test.");
+        }
+
+        @Override
+        public boolean supportsEnumerations() {
+            throw new UnsupportedOperationException("Not needed for the test.");
+        }
+
+        @Override
+        protected int getMaxIntegerTypeSize() {
+            return 32;
+        }
+
+        @Override
+        protected int getMaxRealTypeSize() {
+            return 64;
+        }
+
+        @Override
+        public String getPathSuffixReplacement() {
+            throw new UnsupportedOperationException("Not needed for the test.");
+        }
+
+        @Override
+        protected OutputTypeWriter getPlcCodeWriter() {
+            throw new UnsupportedOperationException("Not needed for the test.");
+        }
+    }
+
+    /**
+     * CIF data provider for testing the expression generator.
+     *
+     * <p>
+     * <ul>
+     * <li>CIF constant {@code X} becomes PLC {@code bool X} (works because the only constant that we have has type
+     * {@code bool}).</li>
+     * <li>CIF discrete variables are stored in a {@code StateStruct state} structure, although the structure itself is
+     * not defined.</li>
+     * <li>CIF {@code cont X} becomes variables {@code X} and {@code X_der}.</li>
+     * <li>CIF location {@code X} becomes a boolean variable {@code X}.</li>
+     * <li>CIF input variable becomes PLC {@code int X} (works because the only input variable that we have has type
+     * {@code int}).</li>
+     * </ul>
+     * </p>
+     */
+    private static class TestCifDataProvider extends CifDataProvider {
+        @Override
+        protected PlcExpression getExprForConstant(Constant constant) {
+            return new PlcVarExpression(new PlcVariable(constant.getName(), PlcElementaryType.BOOL_TYPE));
+        }
+
+        @Override
+        protected PlcExpression getExprForDiscVar(DiscVariable variable) {
+            // state.discvar_name
+            PlcProjection fieldProj = new PlcStructProjection(variable.getName());
+            return new PlcVarExpression(new PlcVariable("state", new PlcDerivedType("StateStruct")), fieldProj);
+        }
+
+        @Override
+        protected PlcExpression getExprForContvar(ContVariable variable, boolean getDerivative) {
+            String name = variable.getName() + (getDerivative ? "_der" : "");
+            return new PlcVarExpression(new PlcVariable(name, PlcElementaryType.LREAL_TYPE));
+        }
+
+        @Override
+        protected PlcExpression getExprForLocation(Location location) {
+            return new PlcVarExpression(new PlcVariable(location.getName(), PlcElementaryType.BOOL_TYPE));
+        }
+
+        @Override
+        protected PlcExpression getExprForInputVar(InputVariable variable) {
+            return new PlcVarExpression(new PlcVariable(variable.getName(), PlcElementaryType.DINT_TYPE));
+        }
+    }
+
+    /**
+     * Name generator for testing the expression generator.
+     *
+     * <p>
+     * Generator appends a unique number after the name.
+     * </p>
+     */
+    private static class TestNameGenerator implements NameGenerator {
+        private int nextNameSuffix = 100;
+
+        @Override
+        public String generateGlobalName(PositionObject posObject) {
+            throw new UnsupportedOperationException("Not needed for the test.");
+        }
+
+        @Override
+        public String generateGlobalName(String initialName, boolean initialIsCifName) {
+            throw new UnsupportedOperationException("Not needed for the test.");
+        }
+
+        @Override
+        public String generateLocalName(String initialName, Map<String, Integer> localSuffixes) {
+            nextNameSuffix++;
+            return initialName + String.valueOf(nextNameSuffix);
+        }
+    }
+
+    /** Type generator for testing the expression generator. */
+    private static class TestTypeGenerator implements TypeGenerator {
+        @Override
+        public PlcType convertType(CifType type) {
+            if (type instanceof BoolType) {
+                return PlcElementaryType.BOOL_TYPE;
+            } else if (type instanceof IntType) {
+                return PlcElementaryType.DINT_TYPE;
+            } else if (type instanceof RealType) {
+                return PlcElementaryType.LREAL_TYPE;
+            } else if (type instanceof ListType lt) {
+                return new PlcArrayType(0, lt.getUpper() - 1, convertType(lt.getElementType()));
+            } else if (type instanceof TupleType tt) {
+                return new PlcDerivedType("tupType_" + tt.getFields().size());
+            }
+            Assert.fail("Implement me: " + type.getClass());
+            return null;
+        }
+
+        @Override
+        public PlcStructType getStructureType(PlcType type) {
+            if (type instanceof PlcDerivedType dt && dt.name.startsWith("tupType_")) {
+                int length = Integer.valueOf(dt.name.charAt(dt.name.length() - 1));
+                PlcStructType structType = new PlcStructType();
+                for (int idx = 1; idx <= length; idx++) {
+                    structType.fields.add(new PlcVariable("field" + idx, PlcElementaryType.LREAL_TYPE));
+                }
+                return structType;
+            }
+            throw new UnsupportedOperationException("Not needed for the test.");
+        }
+
+        @Override
+        public PlcType convertEnumDecl(EnumDecl enumDecl) {
+            throw new UnsupportedOperationException("Not needed for the test.");
+        }
+
+        @Override
+        public PlcEnumLiteral getPlcEnumLiteral(EnumLiteral enumLit) {
+            return new PlcEnumLiteral(enumLit.getName());
+        }
+    }
+
+    /** Convert a variable to simple text. */
+    private static String varToText(PlcVariable var) {
+        return fmt("%s %s", typeToText(var.type), var.name);
+    }
+
+    private static String typeToText(PlcType type) {
+        if (type instanceof PlcElementaryType et) {
+            return et.name;
+        } else if (type instanceof PlcArrayType at) {
+            return fmt("%s[%d..%d]", typeToText(at.elemType), at.lower, at.upper);
+        } else if (type instanceof PlcDerivedType dt) {
+            return dt.name;
+        }
+        throw new UnsupportedOperationException("Not needed for the test.");
+    }
+
+    /**
+     * Run the expression generator at the given expression, and return a dump of the result.
+     *
+     * @param expr Expression to convert.
+     * @return Human-readable representation of the result.
+     */
+    private String runTest(Expression expr) {
+        ExprGenResult result = exprGen.convertExpr(expr);
+
+        boolean needsEmptyLine = false;
+        StringBuilder sb = new StringBuilder();
+        if (result.hasCodeVariables()) {
+            sb.append("Code variables:\n");
+            for (PlcVariable pcVar: result.codeVariables) {
+                sb.append(" - " + varToText(pcVar) + ";");
+                sb.append('\n');
+            }
+            needsEmptyLine = true;
+        }
+
+        if (result.hasCode()) {
+            if (needsEmptyLine) {
+                sb.append("\n");
+            }
+
+            sb.append("Code:\n");
+            sb.append(modelToText.toString(result.code, "myPou", false));
+            sb.append('\n');
+            needsEmptyLine = true;
+        }
+
+        if (result.hasValueVariables()) {
+            if (needsEmptyLine) {
+                sb.append("\n");
+            }
+
+            sb.append("Value variables:\n");
+            for (PlcVariable pcVar: result.valueVariables) {
+                sb.append(" - " + varToText(pcVar) + ";");
+                sb.append('\n');
+            }
+            needsEmptyLine = true;
+        }
+
+        if (needsEmptyLine) {
+            sb.append("\n");
+        }
+        sb.append("==> " + modelToText.toString(result.value));
+        return sb.toString();
+    }
+
+    @Test
+    public void testBoolExpressionConversion() {
+        // true
+        String realText = runTest(newBoolExpression(null, null, true));
+        String expectedText = "==> TRUE";
+        assertEquals(expectedText, realText);
+    }
+
+    @Test
+    public void testIntExpressionConversion() {
+        // 111
+        String realText = runTest(newIntExpression(null, null, 111));
+        String expectedText = "==> 111";
+        assertEquals(expectedText, realText);
+    }
+
+    @Test
+    public void testRealExpressionConversion() {
+        // 1.31
+        String realText = runTest(newRealExpression(null, null, "1.31"));
+        String expectedText = "==> 1.31";
+        assertEquals(expectedText, realText);
+    }
+
+    @Test(expected = RuntimeException.class)
+    public void testStringExpressionConversion() {
+        runTest(newStringExpression(null, null, "abc"));
+    }
+
+    @Test(expected = RuntimeException.class)
+    public void testTimeExpressionConversion() {
+        runTest(newTimeExpression(null, null));
+    }
+
+    @Test
+    public void testCastExpressionConversion() {
+        // <real>17
+        Expression child = newIntExpression(null, newIntType(), 17);
+        Expression expr = newCastExpression(child, null, newRealType());
+        String realText = runTest(expr);
+        String expectedText = "==> DINT_TO_LREAL(IN := 17)";
+        assertEquals(expectedText, realText);
+
+        // Equal types, do nothing.
+        expr = newCastExpression(child, null, newIntType());
+        realText = runTest(expr);
+        expectedText = "==> 17";
+        assertEquals(expectedText, realText);
+    }
+
+    @Test
+    public void testUnaryExpressionConversion() {
+        // not true
+        Expression child = newBoolExpression(null, newBoolType(), true);
+        Expression expr = newUnaryExpression(child, UnaryOperator.INVERSE, null, newBoolType());
+        String realText = runTest(expr);
+        String expectedText = "==> NOT(IN := TRUE)";
+        assertEquals(expectedText, realText);
+
+        // -(1.58)
+        child = newRealExpression(null, newRealType(), "1.58");
+        expr = newUnaryExpression(child, UnaryOperator.NEGATE, null, newRealType());
+        realText = runTest(expr);
+        expectedText = "==> -1.58";
+        assertEquals(expectedText, realText);
+    }
+
+    @Test
+    public void testBinaryImplicationConversion() {
+        // true => false
+        Expression left = newBoolExpression(null, newBoolType(), true);
+        Expression right = newBoolExpression(null, newBoolType(), false);
+        Expression expr = newBinaryExpression(left, BinaryOperator.IMPLICATION, null, right, newBoolType());
+        String realText = runTest(expr);
+        String expectedText = "==> FALSE OR NOT(IN := TRUE)";
+        assertEquals(expectedText, realText);
+    }
+
+    @Test
+    public void testBinaryDisjunctionConversion() {
+        // true or fixed or false
+        Expression left = newBoolExpression(null, newBoolType(), true);
+        Expression mid = newConstantExpression(constantVar, null, newBoolType());
+        Expression right = newBoolExpression(null, newBoolType(), false);
+        Expression expr = newBinaryExpression(mid, BinaryOperator.DISJUNCTION, null, right, newBoolType());
+        expr = newBinaryExpression(left, BinaryOperator.DISJUNCTION, null, expr, newBoolType());
+        String realText = runTest(expr);
+        String expectedText = "==> TRUE OR fixed OR FALSE";
+        assertEquals(expectedText, realText);
+    }
+
+    @Test
+    public void testBinaryLessEqualConversion() {
+        // 100 <= 200.0
+        Expression left = newIntExpression(null, newIntType(), 100);
+        Expression right = newRealExpression(null, newRealType(), "200.0");
+        Expression expr = newBinaryExpression(left, BinaryOperator.LESS_EQUAL, null, right, newBoolType());
+        String realText = runTest(expr);
+        String expectedText = "==> DINT_TO_LREAL(IN := 100) <= 200.0";
+        assertEquals(expectedText, realText);
+    }
+
+    @Test
+    public void testBinaryUnEqualConversion() {
+        // 100 != 200.0
+        Expression left = newIntExpression(null, newIntType(), 100);
+        Expression right = newRealExpression(null, newRealType(), "200.0");
+        Expression expr = newBinaryExpression(left, BinaryOperator.UNEQUAL, null, right, newBoolType());
+        String realText = runTest(expr);
+        String expectedText = "==> 100 <> 200.0";
+        assertEquals(expectedText, realText);
+    }
+
+    @Test
+    public void testBinaryAdditionConversion() {
+        // 100 + 200.0 + 300.0
+        Expression left = newIntExpression(null, newIntType(), 100);
+        Expression mid = newRealExpression(null, newRealType(), "200.0");
+        Expression right = newRealExpression(null, newRealType(), "300.0");
+        Expression expr = newBinaryExpression(mid, BinaryOperator.ADDITION, null, right, newRealType());
+        expr = newBinaryExpression(left, BinaryOperator.ADDITION, null, expr, newRealType());
+        String realText = runTest(expr);
+        String expectedText = "==> DINT_TO_LREAL(IN := 100) + 200.0 + 300.0";
+        assertEquals(expectedText, realText);
+    }
+
+    @Test
+    public void testBinaryIntDivisionConversion() {
+        // 100 div 200
+        Expression left = newIntExpression(null, newIntType(), 100);
+        Expression right = newIntExpression(null, newIntType(), 200);
+        Expression expr = newBinaryExpression(left, BinaryOperator.INTEGER_DIVISION, null, right, newIntType());
+        String realText = runTest(expr);
+        String expectedText = "==> 100 / 200";
+        assertEquals(expectedText, realText);
+    }
+
+    @Test
+    public void testBinaryDivisionIntIntConversion() {
+        // 100 / 200
+        Expression left = newIntExpression(null, newIntType(), 100);
+        Expression right = newIntExpression(null, newIntType(), 200);
+        Expression expr = newBinaryExpression(left, BinaryOperator.DIVISION, null, right, newIntType());
+        String realText = runTest(expr);
+        String expectedText = "==> DINT_TO_LREAL(IN := 100) / DINT_TO_LREAL(IN := 200)";
+        assertEquals(expectedText, realText);
+    }
+
+    @Test
+    public void testBinaryRealDivisionConversion() {
+        // 100.0 / 200
+        Expression left = newRealExpression(null, newRealType(), "100.0");
+        Expression right = newIntExpression(null, newIntType(), 200);
+        Expression expr = newBinaryExpression(left, BinaryOperator.DIVISION, null, right, newIntType());
+        String realText = runTest(expr);
+        String expectedText = "==> 100.0 / DINT_TO_LREAL(IN := 200)";
+        assertEquals(expectedText, realText);
+    }
+
+    @Test(expected = RuntimeException.class)
+    public void testBinaryElementOfConversion() {
+        runTest(newBinaryExpression(null, BinaryOperator.ELEMENT_OF, null, null, null));
+    }
+
+    @Test
+    public void testIfExpressionConversion() {
+        // if true: 1 elif (if true: true else false end): 2 else 3 end;
+
+        // Inner part: if true: true else false end
+        List<ElifExpression> elifs = List.of();
+        Expression elseVal = newBoolExpression(null, newBoolType(), false);
+        List<Expression> guards = List.of(newBoolExpression(null, newBoolType(), true));
+        Expression then = newBoolExpression(null, newBoolType(), true);
+        CifType resultType = newBoolType();
+        Expression identityFunc = newIfExpression(elifs, elseVal, guards, null, then, resultType);
+
+        // The entire expression.
+        elifs = List.of(newElifExpression(List.of(identityFunc), null, newIntExpression(null, newIntType(), 2)));
+        elseVal = newIntExpression(null, newIntType(), 3);
+        guards = List.of(newBoolExpression(null, newBoolType(), true));
+        then = newIntExpression(null, newIntType(), 1);
+        resultType = newIntType();
+        Expression ifExpr = newIfExpression(elifs, elseVal, guards, null, then, resultType);
+        String realText = runTest(ifExpr);
+        String expectedText = """
+                Code:
+                IF TRUE THEN
+                    ifResult101 := 1;
+                ELSE
+                    IF TRUE THEN
+                        ifResult102 := TRUE;
+                    ELSE
+                        ifResult102 := FALSE;
+                    END_IF;
+                    IF ifResult102 THEN
+                        ifResult101 := 2;
+                    ELSE
+                        ifResult101 := 3;
+                    END_IF;
+                END_IF;
+
+                Value variables:
+                 - DINT ifResult101;
+
+                ==> ifResult101""";
+        assertEquals(expectedText, realText);
+    }
+
+    @Test
+    public void testArrayProjectionExpressionConversion() {
+        // [false, true][1]
+        ListExpression array = newListExpression(
+                List.of(newBoolExpression(null, newBoolType(), false), newBoolExpression(null, newBoolType(), true)),
+                null, newListType(newBoolType(), 2, null, 2));
+        Expression arrProj = newProjectionExpression(array, newIntExpression(null, newIntType(), 1), null,
+                newBoolType());
+        String realText = runTest(arrProj);
+        String expectedText = """
+                Code:
+                litArray101[0] := FALSE;
+                litArray101[1] := TRUE;
+
+                Value variables:
+                 - BOOL[0..1] litArray101;
+
+                ==> litArray101[SEL(G := 1 >= 0, IN0 := 1 + 2, IN1 := 1)]""";
+        assertEquals(expectedText, realText);
+    }
+
+    @Test
+    public void testStructIntProjectionExpressionConversion() {
+        // (flatDisc, 1.2345)[1]
+        List<Expression> fields = List.of(makeDiscVarExpr(), newRealExpression(null, newRealType(), "1.2345"));
+        TupleExpression struct = newTupleExpression(fields, null, makeTupleType(2));
+        Expression structProj = newProjectionExpression(struct, newIntExpression(null, newIntType(), 1), null,
+                newBoolType());
+        String realText = runTest(structProj);
+        String expectedText = """
+                Code:
+                litStruct101.field1 := state.flatDisc;
+                litStruct101.field2 := 1.2345;
+
+                Value variables:
+                 - tupType_2 litStruct101;
+
+                ==> litStruct101.field2""";
+        assertEquals(expectedText, realText);
+    }
+
+    @Test
+    public void testStructFieldProjectionExpressionConversion() {
+        // (flatDisc, 1.2345)[field1]
+        List<Expression> fields = List.of(makeDiscVarExpr(), newRealExpression(null, newRealType(), "1.2345"));
+        TupleType tt = makeTupleType(2);
+        TupleExpression struct = newTupleExpression(fields, null, tt);
+        FieldExpression fe = newFieldExpression(tt.getFields().get(0), null, newRealType());
+        Expression structProj = newProjectionExpression(struct, fe, null, newRealType());
+        String realText = runTest(structProj);
+        String expectedText = """
+                Code:
+                litStruct101.field1 := state.flatDisc;
+                litStruct101.field2 := 1.2345;
+
+                Value variables:
+                 - tupType_2 litStruct101;
+
+                ==> litStruct101.field1""";
+        assertEquals(expectedText, realText);
+    }
+
+    @Test
+    public void testProjectedVarProjectionExpressionConversion() {
+        // tupVar[0]
+        DiscVariableExpression tupVarExpr = newDiscVariableExpression(null, makeTupleType(3), tupVar);
+        Expression tupProj = newProjectionExpression(tupVarExpr, newIntExpression(null, newIntType(), 0), null,
+                newRealType());
+        String realText = runTest(tupProj);
+        String expectedText = "==> state.tupVar.field1";
+        assertEquals(expectedText, realText);
+    }
+
+    @Test(expected = RuntimeException.class)
+    public void testSliceExpressionConversion() {
+        runTest(newSliceExpression());
+    }
+
+    @Test
+    public void testFunctionCallExpressionConversion() {
+        // abs(21)
+        Expression func = newStdLibFunctionExpression(StdLibFunction.ABS, null, null);
+        List<Expression> args = List.of(newIntExpression(null, newIntType(), 21));
+        Expression call = newFunctionCallExpression(func, args, null, null);
+        String realText = runTest(call);
+        String expectedText = "==> ABS(IN := 21)";
+        assertEquals(expectedText, realText);
+
+        // cbrt(17.28)
+        func = newStdLibFunctionExpression(StdLibFunction.CBRT, null, null);
+        args = List.of(newRealExpression(null, newRealType(), "17.28"));
+        call = newFunctionCallExpression(func, args, null, null);
+        realText = runTest(call);
+        expectedText = "==> 17.28 ** (1.0 / 3.0)";
+        assertEquals(expectedText, realText);
+
+        // log(17.28) with target support.
+        target.supportsLog = true;
+        func = newStdLibFunctionExpression(StdLibFunction.LOG, null, null);
+        args = List.of(newRealExpression(null, newRealType(), "17.28"));
+        call = newFunctionCallExpression(func, args, null, null);
+        realText = runTest(call);
+        expectedText = "==> LOG(IN := 17.28)";
+        assertEquals(expectedText, realText);
+
+        // log(17.28) without target support.
+        target.supportsLog = false;
+        func = newStdLibFunctionExpression(StdLibFunction.LOG, null, null);
+        args = List.of(newRealExpression(null, newRealType(), "17.28"));
+        call = newFunctionCallExpression(func, args, null, null);
+        realText = runTest(call);
+        expectedText = "==> LN(IN := 17.28) / LN(IN := 10.0)";
+        assertEquals(expectedText, realText);
+
+        // power(1, 2), both ranged to allow an int result.
+        List<CifType> paramTypes = List.of(newIntType(0, null, 2), newIntType(0, null, 2));
+        func = newStdLibFunctionExpression(StdLibFunction.POWER, null, newFuncType(paramTypes, null, newIntType()));
+        args = List.of(newIntExpression(null, newIntType(0, null, 2), 1),
+                newIntExpression(null, newIntType(0, null, 2), 2));
+        call = newFunctionCallExpression(func, args, null, null);
+        realText = runTest(call);
+        expectedText = "==> LREAL_TO_DINT(IN := DINT_TO_LREAL(IN := 1) ** 2)";
+        assertEquals(expectedText, realText);
+
+        // power(2, 3), both rangeless
+        paramTypes = List.of(newIntType(), newIntType());
+        func = newStdLibFunctionExpression(StdLibFunction.POWER, null, newFuncType(paramTypes, null, newRealType()));
+        args = List.of(newIntExpression(null, newIntType(), 2), newIntExpression(null, newIntType(), 3));
+        call = newFunctionCallExpression(func, args, null, null);
+        realText = runTest(call);
+        expectedText = "==> DINT_TO_LREAL(IN := 2) ** 3";
+        assertEquals(expectedText, realText);
+
+        // power(3, 2.0)
+        paramTypes = List.of(newIntType(0, null, 2), newRealType());
+        func = newStdLibFunctionExpression(StdLibFunction.POWER, null, newRealType());
+        args = List.of(newIntExpression(null, newIntType(), 3), newRealExpression(null, newRealType(), "2.0"));
+        call = newFunctionCallExpression(func, args, null, null);
+        realText = runTest(call);
+        expectedText = "==> DINT_TO_LREAL(IN := 3) ** 2.0";
+        assertEquals(expectedText, realText);
+    }
+
+    @Test
+    public void testListExpressionConversion() {
+        // [false, true]
+        ListExpression array = newListExpression(
+                List.of(newBoolExpression(null, newBoolType(), false), newBoolExpression(null, newBoolType(), true)),
+                null, newListType(newBoolType(), 2, null, 2));
+        String realText = runTest(array);
+        String expectedText = """
+                Code:
+                litArray101[0] := FALSE;
+                litArray101[1] := TRUE;
+
+                Value variables:
+                 - BOOL[0..1] litArray101;
+
+                ==> litArray101""";
+        assertEquals(expectedText, realText);
+    }
+
+    @Test
+    public void testTupleExpressionConversion() {
+        // (flatDisc, 1.2345)
+        List<Expression> fields = List.of(makeDiscVarExpr(), newRealExpression(null, newRealType(), "1.2345"));
+        TupleType tt = makeTupleType(2);
+        TupleExpression struct = newTupleExpression(fields, null, tt);
+        String realText = runTest(struct);
+        String expectedText = """
+                Code:
+                litStruct101.field1 := state.flatDisc;
+                litStruct101.field2 := 1.2345;
+
+                Value variables:
+                 - tupType_2 litStruct101;
+
+                ==> litStruct101""";
+        assertEquals(expectedText, realText);
+    }
+
+    @Test(expected = RuntimeException.class)
+    public void testDictExpressionConversion() {
+        runTest(newDictExpression());
+    }
+
+    @Test
+    public void testContConstantExpressionConversion() {
+        // fixed
+        String realText = runTest(newConstantExpression(constantVar, null, newBoolType()));
+        String expectedText = "==> fixed";
+        assertEquals(expectedText, realText);
+    }
+
+    @Test
+    public void testDiscVariableExpressionConversion() {
+        // flatDisc (which is stored in state.flatDisc by the {@code CifDataProvider}.
+        String realText = runTest(newDiscVariableExpression(null, newRealType(), discVar));
+        String expectedText = "==> state.flatDisc";
+        assertEquals(expectedText, realText);
+    }
+
+    @Test
+    public void testContVariableExpressionConversion() {
+        // timer'
+        String realText = runTest(newContVariableExpression(true, null, null, contVar)); // "timer" derivative.
+        String expectedText = "==> timer_der";
+        assertEquals(expectedText, realText);
+
+        // timer
+        realText = runTest(newContVariableExpression(false, null, null, contVar)); // "timer".
+        expectedText = "==> timer";
+        assertEquals(expectedText, realText);
+    }
+
+    @Test
+    public void testLocationExpressionConversion() {
+        // here (the location)
+        String realText = runTest(newLocationExpression(loc, null, newBoolType()));
+        String expectedText = "==> here";
+        assertEquals(expectedText, realText);
+    }
+
+    @Test
+    public void testEnumLiteralExpressionConversion() {
+        EnumLiteral eLit = newEnumLiteral("value123", null);
+        String realText = runTest(newEnumLiteralExpression(eLit, null, null));
+        String expectedText = "==> value123";
+        assertEquals(expectedText, realText);
+    }
+
+    @Test(expected = RuntimeException.class)
+    public void testFunctionExpressionConversion() {
+        runTest(newFunctionExpression());
+    }
+
+    @Test
+    public void testInputVariableExpressionConversion() {
+        String realText = runTest(newInputVariableExpression(null, newIntType(), inputVar));
+        String expectedText = "==> theInput";
+        assertEquals(expectedText, realText);
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src-test/org/eclipse/escet/cif/plcgen/generators/NameGeneratorTest.java b/cif/org.eclipse.escet.cif.plcgen/src-test/org/eclipse/escet/cif/plcgen/generators/NameGeneratorTest.java
index f81e23b7fe9d86e1b078ece30b3522777c1369a7..e23d09a5a69d9d286ebb6a85d7cfec9c143e087e 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src-test/org/eclipse/escet/cif/plcgen/generators/NameGeneratorTest.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src-test/org/eclipse/escet/cif/plcgen/generators/NameGeneratorTest.java
@@ -13,81 +13,118 @@
 
 package org.eclipse.escet.cif.plcgen.generators;
 
+import static org.eclipse.escet.common.java.Maps.map;
 import static org.junit.Assert.assertEquals;
 
-import org.eclipse.escet.cif.cif2plc.options.PlcNumberBits;
+import java.util.Map;
+
 import org.eclipse.escet.cif.plcgen.PlcGenSettings;
+import org.eclipse.escet.cif.plcgen.options.PlcNumberBits;
 import org.junit.Before;
 import org.junit.Test;
 
-/** Tests for the {@link NameGenerator} class. */
+/** Tests for the {@link DefaultNameGenerator} class. */
 public class NameGeneratorTest {
     /** Generator instance under test. */
-    public NameGenerator nameGenerator;
+    public DefaultNameGenerator nameGenerator;
 
     @SuppressWarnings("javadoc")
     @Before
     public void setup() {
         PlcGenSettings settings = new PlcGenSettings(null, null, null, null, 0, 0, null, null, null, PlcNumberBits.AUTO,
                 PlcNumberBits.AUTO, false, null, null, false, null);
-        nameGenerator = new NameGenerator(settings);
+        nameGenerator = new DefaultNameGenerator(settings);
     }
 
     @SuppressWarnings("javadoc")
     @Test
     public void nonDuplicateNamesTest() {
-        assertEquals("s", nameGenerator.generateName("s", false));
-        assertEquals("sani", nameGenerator.generateName("sani", false));
+        assertEquals("s", nameGenerator.generateGlobalName("s", false));
+        assertEquals("sani", nameGenerator.generateGlobalName("sani", false));
     }
 
     @SuppressWarnings("javadoc")
     @Test
     public void keywordAvoidanceTest() {
-        assertEquals("sint__1", nameGenerator.generateName("sint", false)); // PLC keyword.
-        assertEquals("SInt__2", nameGenerator.generateName("SInt", false)); // Partial upper case.
+        assertEquals("sint__1", nameGenerator.generateGlobalName("sint", false)); // PLC keyword.
+        assertEquals("SInt__2", nameGenerator.generateGlobalName("SInt", false)); // Partial upper case.
     }
 
     @SuppressWarnings("javadoc")
     @Test
     public void duplicateNameTest() {
-        assertEquals("s", nameGenerator.generateName("s", false));
-        assertEquals("s__1", nameGenerator.generateName("s", false));
-        assertEquals("s__2", nameGenerator.generateName("s", false));
+        assertEquals("s", nameGenerator.generateGlobalName("s", false));
+        assertEquals("s__1", nameGenerator.generateGlobalName("s", false));
+        assertEquals("s__2", nameGenerator.generateGlobalName("s", false));
     }
 
     @SuppressWarnings("javadoc")
     @Test
     public void useNumberSuffixTest() {
-        assertEquals("s", nameGenerator.generateName("s", false));
-        assertEquals("s1", nameGenerator.generateName("s1", false)); // Different name, no suffix appended.
+        assertEquals("s", nameGenerator.generateGlobalName("s", false));
+        assertEquals("s1", nameGenerator.generateGlobalName("s1", false)); // Different name, no suffix appended.
     }
 
     @SuppressWarnings("javadoc")
     @Test
     public void clashingSuffixTest() {
-        assertEquals("s1", nameGenerator.generateName("s1", false)); // Unused suffix.
-        assertEquals("s1__1", nameGenerator.generateName("s1", false)); // Duplicate, use next higher suffix.
+        assertEquals("s1", nameGenerator.generateGlobalName("s1", false)); // Unused suffix.
+        assertEquals("s1__1", nameGenerator.generateGlobalName("s1", false)); // Duplicate, use next higher suffix.
     }
 
     @SuppressWarnings("javadoc")
     @Test
     public void garbageTest() {
         // Completely garbage.
-        assertEquals("x", nameGenerator.generateName("", false)); // Empty input.
-        assertEquals("x__1", nameGenerator.generateName(".", false)); // Garbage input.
-        assertEquals("x__2", nameGenerator.generateName("_", false)); // Another garbage input produces a new name.
+        assertEquals("x", nameGenerator.generateGlobalName("", false)); // Empty input.
+        assertEquals("x__1", nameGenerator.generateGlobalName(".", false)); // Garbage input.
+        assertEquals("x__2", nameGenerator.generateGlobalName("_", false)); // Another garbage input produces a new
+                                                                            // name.
 
         // Leading garbage.
-        assertEquals("t5", nameGenerator.generateName(".t5", false)); // Skip garbage before identifier.
-        assertEquals("x55", nameGenerator.generateName(".55", false)); // Insert letter to make it an identifier.
+        assertEquals("t5", nameGenerator.generateGlobalName(".t5", false)); // Skip garbage before identifier.
+        assertEquals("x55", nameGenerator.generateGlobalName(".55", false)); // Insert letter to make it an identifier.
 
-        assertEquals("x55__1", nameGenerator.generateName("x55", false)); // x55 was already generated.
+        assertEquals("x55__1", nameGenerator.generateGlobalName("x55", false)); // x55 was already generated.
 
         // Trailing garbage does not change output.
-        assertEquals("t4", nameGenerator.generateName("t4.", false));
-        assertEquals("x44", nameGenerator.generateName("44.", false));
+        assertEquals("t4", nameGenerator.generateGlobalName("t4.", false));
+        assertEquals("x44", nameGenerator.generateGlobalName("44.", false));
 
         // Internal garbage is compressed to a single underscore.
-        assertEquals("x4_4", nameGenerator.generateName("4._4", false));
+        assertEquals("x4_4", nameGenerator.generateGlobalName("4._4", false));
+    }
+
+    @SuppressWarnings("javadoc")
+    @Test
+    public void oneLocalScopeTest() {
+        // Local names avoid other local names.
+        Map<String, Integer> localSuffixes = map();
+        assertEquals("s", nameGenerator.generateLocalName("s", localSuffixes));
+        assertEquals("s__1", nameGenerator.generateLocalName("s", localSuffixes));
+    }
+
+    @SuppressWarnings("javadoc")
+    @Test
+    public void twoLocalScopesTest() {
+        // Local names in a scope avoid other local names in the same scope.
+        Map<String, Integer> localSuffixes = map();
+        assertEquals("s", nameGenerator.generateLocalName("s", localSuffixes));
+        assertEquals("s__1", nameGenerator.generateLocalName("s", localSuffixes));
+
+        // Local names between different scopes may be duplicate.
+        localSuffixes = map(); // Use a different map for a different scope.
+        assertEquals("s", nameGenerator.generateLocalName("s", localSuffixes));
+        assertEquals("s__1", nameGenerator.generateLocalName("s", localSuffixes));
+    }
+
+    @SuppressWarnings("javadoc")
+    @Test
+    public void globalAndLocalTest() {
+        // Local names avoid pre-existing global names.
+        assertEquals("s", nameGenerator.generateGlobalName("s", false));
+        Map<String, Integer> localSuffixes = map();
+        assertEquals("s__1", nameGenerator.generateLocalName("s", localSuffixes));
+        assertEquals("s__2", nameGenerator.generateLocalName("s", localSuffixes));
     }
 }
diff --git a/cif/org.eclipse.escet.cif.plcgen/src-test/org/eclipse/escet/cif/plcgen/model/ExpressionTextTest.java b/cif/org.eclipse.escet.cif.plcgen/src-test/org/eclipse/escet/cif/plcgen/model/ExpressionTextTest.java
index bd9bad18ce822449339b5018fc27108f7e589cff..bab41d92f73403bd4d89ad838a88e0884d69fd8f 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src-test/org/eclipse/escet/cif/plcgen/model/ExpressionTextTest.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src-test/org/eclipse/escet/cif/plcgen/model/ExpressionTextTest.java
@@ -17,8 +17,8 @@ import static org.junit.Assert.assertEquals;
 
 import java.util.List;
 
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcVariable;
 import org.eclipse.escet.cif.plcgen.conversion.ModelTextGenerator;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcVariable;
 import org.eclipse.escet.cif.plcgen.model.expressions.PlcArrayLiteral;
 import org.eclipse.escet.cif.plcgen.model.expressions.PlcBoolLiteral;
 import org.eclipse.escet.cif.plcgen.model.expressions.PlcExpression;
diff --git a/cif/org.eclipse.escet.cif.plcgen/src-test/org/eclipse/escet/cif/plcgen/model/StatementTextTest.java b/cif/org.eclipse.escet.cif.plcgen/src-test/org/eclipse/escet/cif/plcgen/model/StatementTextTest.java
index dc1f309b0d3934bcc8e2d3702df9f1eb1a79d641..2b71baff471e831fb62dc4ceeaab8abca4dfd68b 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src-test/org/eclipse/escet/cif/plcgen/model/StatementTextTest.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src-test/org/eclipse/escet/cif/plcgen/model/StatementTextTest.java
@@ -17,10 +17,9 @@ import static org.junit.Assert.assertEquals;
 
 import java.util.List;
 
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcElementaryType;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcVariable;
 import org.eclipse.escet.cif.plcgen.conversion.ModelTextGenerator;
 import org.eclipse.escet.cif.plcgen.conversion.PlcFunctionAppls;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcVariable;
 import org.eclipse.escet.cif.plcgen.model.expressions.PlcBoolLiteral;
 import org.eclipse.escet.cif.plcgen.model.expressions.PlcExpression;
 import org.eclipse.escet.cif.plcgen.model.expressions.PlcIntLiteral;
@@ -33,6 +32,8 @@ import org.eclipse.escet.cif.plcgen.model.statements.PlcReturnStatement;
 import org.eclipse.escet.cif.plcgen.model.statements.PlcSelectionStatement;
 import org.eclipse.escet.cif.plcgen.model.statements.PlcSelectionStatement.PlcSelectChoice;
 import org.eclipse.escet.cif.plcgen.model.statements.PlcStatement;
+import org.eclipse.escet.cif.plcgen.model.types.PlcElementaryType;
+import org.eclipse.escet.cif.plcgen.targets.PlcOpenXmlTarget;
 import org.junit.Test;
 
 /** Tests of the conversion of PLC statements to text. */
@@ -41,7 +42,7 @@ public class StatementTextTest {
     private static final String POU_NAME = "testPou";
 
     /** Function application generator. */
-    private final PlcFunctionAppls funcAppls = new PlcFunctionAppls();
+    private final PlcFunctionAppls funcAppls = new PlcFunctionAppls(new PlcOpenXmlTarget());
 
     /** Converter of expressions and statements to text. */
     private final ModelTextGenerator textGen = new ModelTextGenerator();
@@ -110,7 +111,7 @@ public class StatementTextTest {
     @SuppressWarnings("javadoc")
     public void funcApplTest() {
         PlcFuncApplStatement funcApplStat = new PlcFuncApplStatement(
-                funcAppls.exptFuncAppl(new PlcRealLiteral("1.0"), new PlcRealLiteral("3.0")));
+                funcAppls.powerFuncAppl(new PlcRealLiteral("1.0"), new PlcRealLiteral("3.0")));
         assertEquals("EXPT(IN1 := 1.0, IN2 := 3.0);", toStr(funcApplStat));
     }
 
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/CifPlcGenApp.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/CifPlcGenApp.java
index ab7f5ca295010dfaca3b26a09d659a7f3850195d..078ec9d486029a561230e27cdc5fcfc988a0f03f 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/CifPlcGenApp.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/CifPlcGenApp.java
@@ -18,25 +18,26 @@ import static org.eclipse.escet.common.java.Lists.list;
 import java.util.List;
 import java.util.function.Supplier;
 
-import org.eclipse.escet.cif.cif2plc.options.ConvertEnums;
-import org.eclipse.escet.cif.cif2plc.options.ConvertEnumsOption;
-import org.eclipse.escet.cif.cif2plc.options.PlcConfigurationNameOption;
-import org.eclipse.escet.cif.cif2plc.options.PlcFormalFuncInvokeArgOption;
-import org.eclipse.escet.cif.cif2plc.options.PlcFormalFuncInvokeFuncOption;
-import org.eclipse.escet.cif.cif2plc.options.PlcMaxIterOption;
-import org.eclipse.escet.cif.cif2plc.options.PlcNumberBits;
-import org.eclipse.escet.cif.cif2plc.options.PlcProjectNameOption;
-import org.eclipse.escet.cif.cif2plc.options.PlcResourceNameOption;
-import org.eclipse.escet.cif.cif2plc.options.PlcTaskCycleTimeOption;
-import org.eclipse.escet.cif.cif2plc.options.PlcTaskNameOption;
-import org.eclipse.escet.cif.cif2plc.options.PlcTaskPriorityOption;
-import org.eclipse.escet.cif.cif2plc.options.RenameWarningsOption;
-import org.eclipse.escet.cif.cif2plc.options.SimplifyValuesOption;
+import org.eclipse.escet.cif.plcgen.options.ConvertEnums;
+import org.eclipse.escet.cif.plcgen.options.ConvertEnumsOption;
+import org.eclipse.escet.cif.plcgen.options.PlcConfigurationNameOption;
+import org.eclipse.escet.cif.plcgen.options.PlcFormalFuncInvokeArgOption;
+import org.eclipse.escet.cif.plcgen.options.PlcFormalFuncInvokeFuncOption;
 import org.eclipse.escet.cif.plcgen.options.PlcIntTypeSizeOption;
+import org.eclipse.escet.cif.plcgen.options.PlcMaxIterOption;
+import org.eclipse.escet.cif.plcgen.options.PlcNumberBits;
+import org.eclipse.escet.cif.plcgen.options.PlcProjectNameOption;
 import org.eclipse.escet.cif.plcgen.options.PlcRealTypeSizeOption;
+import org.eclipse.escet.cif.plcgen.options.PlcResourceNameOption;
 import org.eclipse.escet.cif.plcgen.options.PlcTargetTypeOption;
+import org.eclipse.escet.cif.plcgen.options.PlcTaskCycleTimeOption;
+import org.eclipse.escet.cif.plcgen.options.PlcTaskNameOption;
+import org.eclipse.escet.cif.plcgen.options.PlcTaskPriorityOption;
+import org.eclipse.escet.cif.plcgen.options.RenameWarningsOption;
+import org.eclipse.escet.cif.plcgen.options.SimplifyValuesOption;
 import org.eclipse.escet.cif.plcgen.targets.AbbTarget;
 import org.eclipse.escet.cif.plcgen.targets.Iec611313Target;
+import org.eclipse.escet.cif.plcgen.targets.PlcBaseTarget;
 import org.eclipse.escet.cif.plcgen.targets.PlcOpenXmlTarget;
 import org.eclipse.escet.cif.plcgen.targets.PlcTarget;
 import org.eclipse.escet.cif.plcgen.targets.PlcTargetType;
@@ -94,7 +95,7 @@ public class CifPlcGenApp extends Application<IOutputComponent> {
     protected int runInternal() {
         // Configure code generation.
         PlcTargetType targetType = PlcTargetTypeOption.getPlcTargetType();
-        PlcTarget target;
+        PlcBaseTarget target;
         switch (targetType) {
             case ABB:
                 target = new AbbTarget();
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/PlcGenSettings.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/PlcGenSettings.java
index 19ca67e1ec0a52da473847ad7a9b8083b2bba453..5e98b43d7395ebebb8de15507425c3e53752fa45 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/PlcGenSettings.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/PlcGenSettings.java
@@ -15,8 +15,8 @@ package org.eclipse.escet.cif.plcgen;
 
 import java.util.function.Supplier;
 
-import org.eclipse.escet.cif.cif2plc.options.ConvertEnums;
-import org.eclipse.escet.cif.cif2plc.options.PlcNumberBits;
+import org.eclipse.escet.cif.plcgen.options.ConvertEnums;
+import org.eclipse.escet.cif.plcgen.options.PlcNumberBits;
 
 /** PLC code generator configuration. */
 public class PlcGenSettings {
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/conversion/ModelTextGenerator.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/conversion/ModelTextGenerator.java
index 78863cbc0fb3b0ed478030131ac9cc9355c67283..fbd264ecf632a710d27e5061a99f27d0cecf0005 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/conversion/ModelTextGenerator.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/conversion/ModelTextGenerator.java
@@ -17,6 +17,7 @@ import java.util.List;
 
 import org.eclipse.escet.cif.plcgen.model.expressions.PlcArrayLiteral;
 import org.eclipse.escet.cif.plcgen.model.expressions.PlcBoolLiteral;
+import org.eclipse.escet.cif.plcgen.model.expressions.PlcEnumLiteral;
 import org.eclipse.escet.cif.plcgen.model.expressions.PlcExpression;
 import org.eclipse.escet.cif.plcgen.model.expressions.PlcFuncAppl;
 import org.eclipse.escet.cif.plcgen.model.expressions.PlcIntLiteral;
@@ -104,6 +105,8 @@ public class ModelTextGenerator {
             toText(intLit, textBuilder);
         } else if (expr instanceof PlcRealLiteral realLit) {
             toText(realLit, textBuilder);
+        } else if (expr instanceof PlcEnumLiteral enumLit) {
+            toText(enumLit, textBuilder);
         } else if (expr instanceof PlcArrayLiteral arrayLit) {
             toText(arrayLit, textBuilder, funcApplPreference);
         } else if (expr instanceof PlcStructLiteral structLit) {
@@ -159,6 +162,16 @@ public class ModelTextGenerator {
         textBuilder.append(rslt);
     }
 
+    /**
+     * Convert an enumeration literal expression to text.
+     *
+     * @param enumLit Expression to convert.
+     * @param textBuilder Storage of produced text, extended in-place.
+     */
+    private void toText(PlcEnumLiteral enumLit, StringBuilder textBuilder) {
+        textBuilder.append(enumLit.value);
+    }
+
     /**
      * Convert an array literal expression to text.
      *
@@ -301,7 +314,7 @@ public class ModelTextGenerator {
     }
 
     /**
-     * Convert a sequence of PLC statements to text. Without {@code fixCodeBlock} an sequence without proper statement
+     * Convert a sequence of PLC statements to text. Without {@code fixCodeBlock} a sequence without proper statement
      * will crash the application.
      *
      * @param plcStats Statements to convert.
@@ -316,7 +329,7 @@ public class ModelTextGenerator {
     }
 
     /**
-     * Convert a sequence of PLC statements to text. Without {@code fixCodeBlock} an sequence without proper statement
+     * Convert a sequence of PLC statements to text. Without {@code fixCodeBlock} a sequence without proper statement
      * will crash the application.
      *
      * @param plcStats StatementS to convert.
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/conversion/PlcFunctionAppls.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/conversion/PlcFunctionAppls.java
index 9cb91c37ba7d373470b218156ecc2378292c9809..3aa7706d1f76c9b5a28a6206479cc19b97e531f4 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/conversion/PlcFunctionAppls.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/conversion/PlcFunctionAppls.java
@@ -17,7 +17,6 @@ import java.util.List;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcElementaryType;
 import org.eclipse.escet.cif.plcgen.model.expressions.PlcExpression;
 import org.eclipse.escet.cif.plcgen.model.expressions.PlcFuncAppl;
 import org.eclipse.escet.cif.plcgen.model.expressions.PlcIntLiteral;
@@ -29,10 +28,15 @@ import org.eclipse.escet.cif.plcgen.model.functions.PlcBasicFuncDescription.PlcP
 import org.eclipse.escet.cif.plcgen.model.functions.PlcCastFunction;
 import org.eclipse.escet.cif.plcgen.model.functions.PlcFuncOperation;
 import org.eclipse.escet.cif.plcgen.model.functions.PlcSemanticFuncDescription;
+import org.eclipse.escet.cif.plcgen.model.types.PlcElementaryType;
+import org.eclipse.escet.cif.plcgen.targets.PlcTarget;
 import org.eclipse.escet.common.java.Assert;
 
 /** Elementary function application construction methods for a target. */
 public class PlcFunctionAppls {
+    /** PLC to generate code for. */
+    private final PlcTarget target;
+
     /** Parameters for functions that take one input parameters. */
     private static final PlcParameterDescription[] ONE_INPUT_PARAMETER = new PlcParameterDescription[] {
             new PlcParameterDescription("IN", PlcParamDirection.INPUT_ONLY),
@@ -44,6 +48,15 @@ public class PlcFunctionAppls {
             new PlcParameterDescription("IN2", PlcParamDirection.INPUT_ONLY),
             new PlcParameterDescription("OUT", PlcParamDirection.OUTPUT_ONLY)};
 
+    /**
+     * Constructor of the {@link PlcFunctionAppls} class.
+     *
+     * @param target PLC to generate code for.
+     */
+    public PlcFunctionAppls(PlcTarget target) {
+        this.target = target;
+    }
+
     /**
      * Construct a function application for a negation.
      *
@@ -51,21 +64,26 @@ public class PlcFunctionAppls {
      * @return The constructed function application.
      */
     public PlcFuncAppl negateFuncAppl(PlcExpression in) {
+        Assert.check(target.supportsOperation(PlcFuncOperation.NEGATE_OP));
+
         PlcSemanticFuncDescription func = new PlcSemanticFuncDescription(PlcFuncOperation.NEGATE_OP, null,
                 ONE_INPUT_PARAMETER, "-", ExprBinding.UNARY_EXPR);
         return new PlcFuncAppl(func, List.of(new PlcNamedValue("IN", in)));
     }
 
     /**
-     * Construct a function application for an exponentiation.
+     * Construct a power function application ({@code base ** exponent}).
      *
      * @param in1 Base value argument of the function.
      * @param in2 Exponent argument of the function.
      * @return The constructed function application.
      */
-    public PlcFuncAppl exptFuncAppl(PlcExpression in1, PlcExpression in2) {
-        PlcSemanticFuncDescription func = new PlcSemanticFuncDescription(PlcFuncOperation.EXP_OP, "EXPT",
-                TWO_INPUT_PARAMATERS, "**", ExprBinding.EXPT_EXPR);
+    public PlcFuncAppl powerFuncAppl(PlcExpression in1, PlcExpression in2) {
+        Assert.check(target.supportsOperation(PlcFuncOperation.POWER_OP));
+
+        String infixText = target.supportsInfixNotation(PlcFuncOperation.POWER_OP) ? "**" : null;
+        PlcSemanticFuncDescription func = new PlcSemanticFuncDescription(PlcFuncOperation.POWER_OP, "EXPT",
+                TWO_INPUT_PARAMATERS, infixText, ExprBinding.POWER_EXPR);
         return new PlcFuncAppl(func, List.of(new PlcNamedValue("IN1", in1), new PlcNamedValue("IN2", in2)));
     }
 
@@ -76,7 +94,9 @@ public class PlcFunctionAppls {
      * @return The constructed function application.
      */
     public PlcFuncAppl multiplyFuncAppl(PlcExpression... inN) {
+        Assert.check(target.supportsOperation(PlcFuncOperation.MULTIPLY_OP));
         Assert.check(inN.length > 1);
+
         PlcSemanticFuncDescription func = new PlcSemanticFuncDescription(PlcFuncOperation.MULTIPLY_OP, "MUL",
                 makeParamList(inN.length), "*", ExprBinding.MUL_EXPR);
         List<PlcNamedValue> arguments = IntStream.range(0, inN.length)
@@ -92,6 +112,8 @@ public class PlcFunctionAppls {
      * @return The constructed function application.
      */
     public PlcFuncAppl divideFuncAppl(PlcExpression in1, PlcExpression in2) {
+        Assert.check(target.supportsOperation(PlcFuncOperation.DIVIDE_OP));
+
         PlcSemanticFuncDescription func = new PlcSemanticFuncDescription(PlcFuncOperation.DIVIDE_OP, "DIV",
                 TWO_INPUT_PARAMATERS, "/", ExprBinding.MUL_EXPR);
         return new PlcFuncAppl(func, List.of(new PlcNamedValue("IN1", in1), new PlcNamedValue("IN2", in2)));
@@ -105,6 +127,8 @@ public class PlcFunctionAppls {
      * @return The constructed function application.
      */
     public PlcFuncAppl moduloFuncAppl(PlcExpression in1, PlcExpression in2) {
+        Assert.check(target.supportsOperation(PlcFuncOperation.MODULO_OP));
+
         PlcSemanticFuncDescription func = new PlcSemanticFuncDescription(PlcFuncOperation.MODULO_OP, "MOD",
                 TWO_INPUT_PARAMATERS, null, ExprBinding.MUL_EXPR);
         return new PlcFuncAppl(func, List.of(new PlcNamedValue("IN1", in1), new PlcNamedValue("IN2", in2)));
@@ -117,7 +141,9 @@ public class PlcFunctionAppls {
      * @return The constructed function application.
      */
     public PlcFuncAppl addFuncAppl(PlcExpression... inN) {
+        Assert.check(target.supportsOperation(PlcFuncOperation.ADD_OP));
         Assert.check(inN.length > 1);
+
         PlcSemanticFuncDescription func = new PlcSemanticFuncDescription(PlcFuncOperation.ADD_OP, "ADD",
                 makeParamList(inN.length), "+", ExprBinding.ADD_EXPR);
         List<PlcNamedValue> arguments = IntStream.range(0, inN.length)
@@ -133,6 +159,8 @@ public class PlcFunctionAppls {
      * @return The constructed function application.
      */
     public PlcFuncAppl subtractFuncAppl(PlcExpression in1, PlcExpression in2) {
+        Assert.check(target.supportsOperation(PlcFuncOperation.SUBTRACT_OP));
+
         PlcSemanticFuncDescription func = new PlcSemanticFuncDescription(PlcFuncOperation.SUBTRACT_OP, "SUB",
                 TWO_INPUT_PARAMATERS, "-", ExprBinding.ADD_EXPR);
         return new PlcFuncAppl(func, List.of(new PlcNamedValue("IN1", in1), new PlcNamedValue("IN2", in2)));
@@ -146,6 +174,8 @@ public class PlcFunctionAppls {
      * @return The constructed function application.
      */
     public PlcFuncAppl lessThanFuncAppl(PlcExpression in1, PlcExpression in2) {
+        Assert.check(target.supportsOperation(PlcFuncOperation.LESS_THAN_OP));
+
         // The PLC function allows more than two parameters.
         PlcSemanticFuncDescription func = new PlcSemanticFuncDescription(PlcFuncOperation.LESS_THAN_OP, "LT",
                 TWO_INPUT_PARAMATERS, "<", ExprBinding.ORDER_EXPR);
@@ -160,6 +190,8 @@ public class PlcFunctionAppls {
      * @return The constructed function application.
      */
     public PlcFuncAppl lessEqualFuncAppl(PlcExpression in1, PlcExpression in2) {
+        Assert.check(target.supportsOperation(PlcFuncOperation.LESS_EQUAL_OP));
+
         // The PLC function allows more than two parameters.
         PlcSemanticFuncDescription func = new PlcSemanticFuncDescription(PlcFuncOperation.LESS_EQUAL_OP, "LE",
                 TWO_INPUT_PARAMATERS, "<=", ExprBinding.ORDER_EXPR);
@@ -174,6 +206,8 @@ public class PlcFunctionAppls {
      * @return The constructed function application.
      */
     public PlcFuncAppl greaterThanFuncAppl(PlcExpression in1, PlcExpression in2) {
+        Assert.check(target.supportsOperation(PlcFuncOperation.GREATER_THAN_OP));
+
         // The PLC function allows more than two parameters.
         PlcSemanticFuncDescription func = new PlcSemanticFuncDescription(PlcFuncOperation.GREATER_THAN_OP, "GT",
                 TWO_INPUT_PARAMATERS, ">", ExprBinding.ORDER_EXPR);
@@ -188,6 +222,8 @@ public class PlcFunctionAppls {
      * @return The constructed function application.
      */
     public PlcFuncAppl greaterEqualFuncAppl(PlcExpression in1, PlcExpression in2) {
+        Assert.check(target.supportsOperation(PlcFuncOperation.GREATER_EQUAL_OP));
+
         // The PLC function allows more than two parameters.
         PlcSemanticFuncDescription func = new PlcSemanticFuncDescription(PlcFuncOperation.GREATER_EQUAL_OP, "GE",
                 TWO_INPUT_PARAMATERS, ">=", ExprBinding.ORDER_EXPR);
@@ -202,6 +238,8 @@ public class PlcFunctionAppls {
      * @return The constructed function application.
      */
     public PlcFuncAppl equalFuncAppl(PlcExpression in1, PlcExpression in2) {
+        Assert.check(target.supportsOperation(PlcFuncOperation.EQUAL_OP));
+
         // The PLC function allows more than two parameters.
         PlcSemanticFuncDescription func = new PlcSemanticFuncDescription(PlcFuncOperation.EQUAL_OP, "EQ",
                 TWO_INPUT_PARAMATERS, "=", ExprBinding.EQUAL_EXPR);
@@ -216,6 +254,8 @@ public class PlcFunctionAppls {
      * @return The constructed function application.
      */
     public PlcFuncAppl unEqualFuncAppl(PlcExpression in1, PlcExpression in2) {
+        Assert.check(target.supportsOperation(PlcFuncOperation.UNEQUAL_OP));
+
         PlcSemanticFuncDescription func = new PlcSemanticFuncDescription(PlcFuncOperation.UNEQUAL_OP, "NE",
                 TWO_INPUT_PARAMATERS, "<>", ExprBinding.EQUAL_EXPR);
         return new PlcFuncAppl(func, List.of(new PlcNamedValue("IN1", in1), new PlcNamedValue("IN2", in2)));
@@ -228,6 +268,8 @@ public class PlcFunctionAppls {
      * @return The constructed function application.
      */
     public PlcFuncAppl complementFuncAppl(PlcExpression in) {
+        Assert.check(target.supportsOperation(PlcFuncOperation.COMPLEMENT_OP));
+
         PlcSemanticFuncDescription func = new PlcSemanticFuncDescription(PlcFuncOperation.COMPLEMENT_OP, "NOT",
                 ONE_INPUT_PARAMETER, null, ExprBinding.UNARY_EXPR);
         return new PlcFuncAppl(func, List.of(new PlcNamedValue("IN", in)));
@@ -240,7 +282,9 @@ public class PlcFunctionAppls {
      * @return The constructed function application.
      */
     public PlcFuncAppl andFuncAppl(PlcExpression... inN) {
+        Assert.check(target.supportsOperation(PlcFuncOperation.AND_OP));
         Assert.check(inN.length > 1);
+
         PlcSemanticFuncDescription func = new PlcSemanticFuncDescription(PlcFuncOperation.AND_OP, "AND",
                 makeParamList(inN.length), "AND", ExprBinding.CONJUNCT_EXPR);
         List<PlcNamedValue> arguments = IntStream.range(0, inN.length)
@@ -255,7 +299,9 @@ public class PlcFunctionAppls {
      * @return The constructed function application.
      */
     public PlcFuncAppl xorFuncAppl(PlcExpression... inN) {
+        Assert.check(target.supportsOperation(PlcFuncOperation.XOR_OP));
         Assert.check(inN.length > 1);
+
         PlcSemanticFuncDescription func = new PlcSemanticFuncDescription(PlcFuncOperation.XOR_OP, "XOR",
                 makeParamList(inN.length), "XOR", ExprBinding.EXCL_DISJUNCT_EXPR);
         List<PlcNamedValue> arguments = IntStream.range(0, inN.length)
@@ -270,7 +316,9 @@ public class PlcFunctionAppls {
      * @return The constructed function application.
      */
     public PlcFuncAppl orFuncAppl(PlcExpression... inN) {
+        Assert.check(target.supportsOperation(PlcFuncOperation.OR_OP));
         Assert.check(inN.length > 1);
+
         PlcSemanticFuncDescription func = new PlcSemanticFuncDescription(PlcFuncOperation.OR_OP, "OR",
                 makeParamList(inN.length), "OR", ExprBinding.DISJUNCT_EXPR);
         List<PlcNamedValue> arguments = IntStream.range(0, inN.length)
@@ -315,6 +363,8 @@ public class PlcFunctionAppls {
      * @return The constructed function application.
      */
     public PlcFuncAppl selFuncAppl(PlcExpression g, PlcExpression in0, PlcExpression in1) {
+        Assert.check(target.supportsOperation(PlcFuncOperation.SEL_OP));
+
         PlcParameterDescription[] params = new PlcParameterDescription[] {
                 new PlcParameterDescription("G", PlcParamDirection.INPUT_ONLY),
                 new PlcParameterDescription("IN0", PlcParamDirection.INPUT_ONLY),
@@ -338,4 +388,192 @@ public class PlcFunctionAppls {
         PlcExpression in1 = indexExpr;
         return selFuncAppl(g, in0, in1);
     }
+
+    /**
+     * Construct a function application for an absolute value operation.
+     *
+     * @param in The input argument of the function.
+     * @return The constructed function application.
+     */
+    public PlcFuncAppl absFuncAppl(PlcExpression in) {
+        Assert.check(target.supportsOperation(PlcFuncOperation.STDLIB_ABS));
+
+        PlcSemanticFuncDescription func = new PlcSemanticFuncDescription(PlcFuncOperation.STDLIB_ABS, "ABS",
+                ONE_INPUT_PARAMETER);
+        return new PlcFuncAppl(func, List.of(new PlcNamedValue("IN", in)));
+    }
+
+    /**
+     * Construct a function application for an exponential operation.
+     *
+     * @param in The input argument of the function.
+     * @return The constructed function application.
+     */
+    public PlcFuncAppl expFuncAppl(PlcExpression in) {
+        Assert.check(target.supportsOperation(PlcFuncOperation.STDLIB_EXP));
+
+        PlcSemanticFuncDescription func = new PlcSemanticFuncDescription(PlcFuncOperation.STDLIB_EXP, "EXP",
+                ONE_INPUT_PARAMETER);
+        return new PlcFuncAppl(func, List.of(new PlcNamedValue("IN", in)));
+    }
+
+    /**
+     * Construct a function application for a natural logarithm operation.
+     *
+     * @param in The input argument of the function.
+     * @return The constructed function application.
+     */
+    public PlcFuncAppl lnFuncAppl(PlcExpression in) {
+        Assert.check(target.supportsOperation(PlcFuncOperation.STDLIB_LN));
+
+        PlcSemanticFuncDescription func = new PlcSemanticFuncDescription(PlcFuncOperation.STDLIB_LN, "LN",
+                ONE_INPUT_PARAMETER);
+        return new PlcFuncAppl(func, List.of(new PlcNamedValue("IN", in)));
+    }
+
+    /**
+     * Construct a function application for a base 10 logarithm operation.
+     *
+     * @param in The input argument of the function.
+     * @return The constructed function application.
+     */
+    public PlcFuncAppl logFuncAppl(PlcExpression in) {
+        Assert.check(target.supportsOperation(PlcFuncOperation.STDLIB_LOG));
+
+        PlcSemanticFuncDescription func = new PlcSemanticFuncDescription(PlcFuncOperation.STDLIB_LOG, "LOG",
+                ONE_INPUT_PARAMETER);
+        return new PlcFuncAppl(func, List.of(new PlcNamedValue("IN", in)));
+    }
+
+    /**
+     * Construct a function application for a minimum operation.
+     *
+     * @param inN Input arguments of the function, must have at least two arguments.
+     * @return The constructed function application.
+     */
+    public PlcFuncAppl minFuncAppl(PlcExpression... inN) {
+        Assert.check(target.supportsOperation(PlcFuncOperation.STDLIB_MIN));
+        Assert.check(inN.length > 1);
+
+        PlcSemanticFuncDescription func = new PlcSemanticFuncDescription(PlcFuncOperation.STDLIB_MIN, "MIN",
+                makeParamList(inN.length));
+        List<PlcNamedValue> arguments = IntStream.range(0, inN.length)
+                .mapToObj(i -> new PlcNamedValue("IN" + String.valueOf(i + 1), inN[i])).collect(Collectors.toList());
+        return new PlcFuncAppl(func, arguments);
+    }
+
+    /**
+     * Construct a function application for a maximum operation.
+     *
+     * @param inN Input arguments of the function, must have at least two arguments.
+     * @return The constructed function application.
+     */
+    public PlcFuncAppl maxFuncAppl(PlcExpression... inN) {
+        Assert.check(target.supportsOperation(PlcFuncOperation.STDLIB_MAX));
+        Assert.check(inN.length > 1);
+
+        PlcSemanticFuncDescription func = new PlcSemanticFuncDescription(PlcFuncOperation.STDLIB_MAX, "MAX",
+                makeParamList(inN.length));
+        List<PlcNamedValue> arguments = IntStream.range(0, inN.length)
+                .mapToObj(i -> new PlcNamedValue("IN" + String.valueOf(i + 1), inN[i])).collect(Collectors.toList());
+        return new PlcFuncAppl(func, arguments);
+    }
+
+    /**
+     * Construct a function application for a square root operation.
+     *
+     * @param in The input argument of the function.
+     * @return The constructed function application.
+     */
+    public PlcFuncAppl sqrtFuncAppl(PlcExpression in) {
+        Assert.check(target.supportsOperation(PlcFuncOperation.STDLIB_SQRT));
+
+        PlcSemanticFuncDescription func = new PlcSemanticFuncDescription(PlcFuncOperation.STDLIB_SQRT, "SQRT",
+                ONE_INPUT_PARAMETER);
+        return new PlcFuncAppl(func, List.of(new PlcNamedValue("IN", in)));
+    }
+
+    /**
+     * Construct a function application for a arccosine operation.
+     *
+     * @param in The input argument of the function.
+     * @return The constructed function application.
+     */
+    public PlcFuncAppl acosFuncAppl(PlcExpression in) {
+        Assert.check(target.supportsOperation(PlcFuncOperation.STDLIB_ACOS));
+
+        PlcSemanticFuncDescription func = new PlcSemanticFuncDescription(PlcFuncOperation.STDLIB_ACOS, "ACOS",
+                ONE_INPUT_PARAMETER);
+        return new PlcFuncAppl(func, List.of(new PlcNamedValue("IN", in)));
+    }
+
+    /**
+     * Construct a function application for a arcsine operation.
+     *
+     * @param in The input argument of the function.
+     * @return The constructed function application.
+     */
+    public PlcFuncAppl asinFuncAppl(PlcExpression in) {
+        Assert.check(target.supportsOperation(PlcFuncOperation.STDLIB_ASIN));
+
+        PlcSemanticFuncDescription func = new PlcSemanticFuncDescription(PlcFuncOperation.STDLIB_ASIN, "ASIN",
+                ONE_INPUT_PARAMETER);
+        return new PlcFuncAppl(func, List.of(new PlcNamedValue("IN", in)));
+    }
+
+    /**
+     * Construct a function application for a arctangent operation.
+     *
+     * @param in The input argument of the function.
+     * @return The constructed function application.
+     */
+    public PlcFuncAppl atanFuncAppl(PlcExpression in) {
+        Assert.check(target.supportsOperation(PlcFuncOperation.STDLIB_ATAN));
+
+        PlcSemanticFuncDescription func = new PlcSemanticFuncDescription(PlcFuncOperation.STDLIB_ATAN, "ATAN",
+                ONE_INPUT_PARAMETER);
+        return new PlcFuncAppl(func, List.of(new PlcNamedValue("IN", in)));
+    }
+
+    /**
+     * Construct a function application for a cosine operation.
+     *
+     * @param in The input argument of the function.
+     * @return The constructed function application.
+     */
+    public PlcFuncAppl cosFuncAppl(PlcExpression in) {
+        Assert.check(target.supportsOperation(PlcFuncOperation.STDLIB_COS));
+
+        PlcSemanticFuncDescription func = new PlcSemanticFuncDescription(PlcFuncOperation.STDLIB_COS, "COS",
+                ONE_INPUT_PARAMETER);
+        return new PlcFuncAppl(func, List.of(new PlcNamedValue("IN", in)));
+    }
+
+    /**
+     * Construct a function application for a sine operation.
+     *
+     * @param in The input argument of the function.
+     * @return The constructed function application.
+     */
+    public PlcFuncAppl sinFuncAppl(PlcExpression in) {
+        Assert.check(target.supportsOperation(PlcFuncOperation.STDLIB_SIN));
+
+        PlcSemanticFuncDescription func = new PlcSemanticFuncDescription(PlcFuncOperation.STDLIB_SIN, "SIN",
+                ONE_INPUT_PARAMETER);
+        return new PlcFuncAppl(func, List.of(new PlcNamedValue("IN", in)));
+    }
+
+    /**
+     * Construct a function application for a tangent operation.
+     *
+     * @param in The input argument of the function.
+     * @return The constructed function application.
+     */
+    public PlcFuncAppl tanFuncAppl(PlcExpression in) {
+        Assert.check(target.supportsOperation(PlcFuncOperation.STDLIB_TAN));
+
+        PlcSemanticFuncDescription func = new PlcSemanticFuncDescription(PlcFuncOperation.STDLIB_TAN, "TAN",
+                ONE_INPUT_PARAMETER);
+        return new PlcFuncAppl(func, List.of(new PlcNamedValue("IN", in)));
+    }
 }
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/conversion/expressions/CifDataProvider.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/conversion/expressions/CifDataProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..c7e6309aa86c4d50425d03074f43e0f24ac765a1
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/conversion/expressions/CifDataProvider.java
@@ -0,0 +1,75 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.conversion.expressions;
+
+import org.eclipse.escet.cif.metamodel.cif.automata.Location;
+import org.eclipse.escet.cif.metamodel.cif.declarations.Constant;
+import org.eclipse.escet.cif.metamodel.cif.declarations.ContVariable;
+import org.eclipse.escet.cif.metamodel.cif.declarations.DiscVariable;
+import org.eclipse.escet.cif.metamodel.cif.declarations.InputVariable;
+import org.eclipse.escet.cif.plcgen.model.expressions.PlcExpression;
+
+/** Provider of PLC equivalents of CIF data. */
+
+/*
+ * TODO: Currently this class is an empty shell listing discovered needed conversions for expression generation from CIF
+ * complex components. It is not complete (for example initial locations and user-defined internal functions have not
+ * been considered). It is also possible that the currently proposed functions here are non-optimal for implementing
+ * this class.
+ */
+public abstract class CifDataProvider {
+    /**
+     * Return the PLC expression to get the value of the provided constant.
+     *
+     * @param constant Constant to access.
+     * @return The expression to get the value of the constant in the PLC.
+     */
+    protected abstract PlcExpression getExprForConstant(Constant constant);
+
+    /**
+     * Return the PLC expression to access the provided discrete variable.
+     *
+     * @param variable Variable to access.
+     * @return The expression to access the provided discrete variable.
+     */
+    protected abstract PlcExpression getExprForDiscVar(DiscVariable variable);
+
+    /**
+     * Return the PLC expression to access the value or the derivative of the provided continuous variable.
+     *
+     * @param variable Variable to access.
+     * @param getDerivative Whether access to the derivative value is requested, otherwise access to the value of the
+     *     variable itself is requested.
+     * @return The expression to access a value of the provided continuous variable.
+     */
+    protected abstract PlcExpression getExprForContvar(ContVariable variable, boolean getDerivative);
+
+    /**
+     * Return the PLC expression for deciding whether the automaton owning the given location is at the time of
+     * evaluation in that location.
+     *
+     * @param location Location being queried.
+     * @return A boolean expression expressing whether the owning automaton of the location is in that location.
+     */
+    protected abstract PlcExpression getExprForLocation(Location location);
+
+    /**
+     * Return the PLC expression to access the provided input variable.
+     *
+     * @param variable Variable to access.
+     * @return The expression to access the provided input variable.
+     * @note The returned expression may not allow writing to the variable.
+     */
+    protected abstract PlcExpression getExprForInputVar(InputVariable variable);
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/conversion/expressions/ExprGenResult.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/conversion/expressions/ExprGenResult.java
new file mode 100644
index 0000000000000000000000000000000000000000..18ed710ad9f3b76c78599440aba3cd2e26e83a7c
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/conversion/expressions/ExprGenResult.java
@@ -0,0 +1,249 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.conversion.expressions;
+
+import static org.eclipse.escet.common.java.Lists.list;
+import static org.eclipse.escet.common.java.Sets.set;
+
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.escet.cif.plcgen.conversion.ModelTextGenerator;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcVariable;
+import org.eclipse.escet.cif.plcgen.model.expressions.PlcExpression;
+import org.eclipse.escet.cif.plcgen.model.statements.PlcStatement;
+import org.eclipse.escet.common.java.Assert;
+
+/**
+ * Storage of a converted CIF expression.
+ *
+ * <p>
+ * The CIF language has a very rich set of expression constructs, it is much larger set than the PLC expression
+ * constructs. For this reason, a converted CIF expression cannot always be a PLC expression. It may first need to
+ * perform code to derive the value.
+ * </p>
+ *
+ * <p>
+ * The {@link ExprGenResult} encapsulates this need. It has
+ * <ul>
+ * <li>optional {@link #code}, statements that need to be executed before reading the {@link #value} of this result,
+ * </li>
+ * <li>optional {@link #codeVariables}, temporary variables used in the {@link #code},</li>
+ * <li>a {@link #value}, an expression that can be evaluated to obtain the final result value of the converted CIF
+ * expression, and</li>
+ * <li>optional {@link #valueVariables}, temporary variables assigned from the {@link #code} fragment and used in the
+ * {@link #value} expression.</li>
+ * </ul>
+ * To construct an {@link ExprGenResult} instance, an expression expressing the final value must be constructed and
+ * stored in {@link #value}. If the former expression needs dynamically computed values, the {@link #code} part can be
+ * used to store statements for that purpose.
+ * </p>
+ * <p>
+ * As the code computes values needed in the final value, intermediate variables are needed to transfer computed values
+ * from the statement to the moment of evaluating the final value. These variables should be stored in
+ * {@link #valueVariables} and be exclusively reserved for this purpose before the code is executed until after
+ * evaluating the {@link #value} expression. In addition, the code may need additional variables for its internal flow.
+ * These should be stored in {@link #codeVariables}, and be exclusively reserved for this purpose before the code is
+ * executed until execution of that code has finished.
+ * </p>
+ *
+ * <p>
+ * To obtain the final value of the instance in the PLC, the following steps should be followed.
+ * <ol>
+ * <li>Execute the statements in {@link #code} if it exists. Doing this may change the {@link #codeVariables} and the
+ * {@link #valueVariables}. As these variables should be reserved for this purpose at the time of obtaining the
+ * {@link ExprGenResult} instance, there is no need to take care of reserving them beforehand.</li>
+ * <li>After the {@link #code} has been executed, variables stored in the {@link #codeVariables} are not needed any more
+ * to obtain the final value. They should be released by calling {@link #releaseCodeVariables}.</li>
+ * <li>Obtain the final value by evaluating the {@link #value} expression. Use the final value or store it somewhere
+ * safe.</li>
+ * <li>After the final value is used or safely stored, the temporary values in {@link #valueVariables} are not needed
+ * any more, they should be released by calling {@link #releaseValueVariables}.</li>
+ * </ol>
+ * </p>
+ */
+public class ExprGenResult {
+    /** The expression generator managing the temporary variables that have been added here. */
+    private final ExprGenerator generator;
+
+    /**
+     * Temporary variables that are used in {@link #code the PLC code}. They should be released for reuse after
+     * inserting the {@link #code} in its execution context. In that way, the variables will not have important values
+     * for other parts in the generated result.
+     */
+    public Set<PlcVariable> codeVariables = set();
+
+    /** Code to perform before evaluating the {@link #value}. */
+    public List<PlcStatement> code = list();
+
+    /**
+     * Temporary variables that are assigned in {@link #code the PLC code} and used in evaluating the {@link #value
+     * result value}. They should be released for reuse after evaluating the {@link #value} expression in the generated
+     * result. In that way, the variables will not have important values for other parts in the generated result.
+     */
+    public Set<PlcVariable> valueVariables = set();
+
+    /**
+     * Expression to evaluate after running the {@link #code} if it exists. The {@link #valueVariables} should be
+     * released for reuse afterwards.
+     *
+     * <p>
+     * While the value can be set directly, it is generally recommended to use the {@link #setValue} daisy-chain method
+     * to construct an {@link ExprGenResult} instance.
+     * </p>
+     */
+    public PlcExpression value = null;
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        ModelTextGenerator tg = new ModelTextGenerator();
+        if (!code.isEmpty()) {
+            sb.append("code:\n");
+            for (PlcStatement s: code) {
+                sb.append(tg.toString(s, "noPou") + "\n");
+            }
+        }
+        if (!codeVariables.isEmpty()) {
+            sb.append("code-variables:");
+            for (PlcVariable v: codeVariables) {
+                sb.append(" " + v.name);
+            }
+            sb.append("\n");
+        }
+        if (value != null) {
+            sb.append("value: " + tg.toString(value) + "\n");
+        } else {
+            sb.append("value: <NULL>\n");
+        }
+        if (!valueVariables.isEmpty()) {
+            sb.append("value-variables:");
+            for (PlcVariable v: valueVariables) {
+                sb.append(" " + v.name);
+            }
+            sb.append("\n");
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Constructor of the {@link ExprGenResult} class.
+     *
+     * @param generator Expression generator managing the temporary variables.
+     * @param parentResults Results of child sub-expressions. Their code, code variables and value variables are copied
+     *     into this result in the specified order.
+     */
+    public ExprGenResult(ExprGenerator generator, ExprGenResult... parentResults) {
+        this.generator = generator;
+
+        for (ExprGenResult parentResult: parentResults) {
+            mergeCodeAndVariables(parentResult);
+        }
+    }
+
+    /**
+     * Append the code variables, code, and value variables of the parent result to this result.
+     *
+     * @param parentResult Source of the code variables, code, and value variables to copy.
+     */
+    public void mergeCodeAndVariables(ExprGenResult parentResult) {
+        mergeCodeVariables(parentResult);
+        mergeCode(parentResult);
+        mergeValueVariables(parentResult);
+    }
+
+    /**
+     * Append code variables of the parent result to this result.
+     *
+     * @param parentResult Source of the code variables to copy.
+     */
+    public void mergeCodeVariables(ExprGenResult parentResult) {
+        codeVariables.addAll(parentResult.codeVariables);
+    }
+
+    /**
+     * Append code of the parent result to this result.
+     *
+     * @param parentResult Source of the code to copy.
+     */
+    public void mergeCode(ExprGenResult parentResult) {
+        code.addAll(PlcStatement.copy(parentResult.code));
+    }
+
+    /**
+     * Append values variables of the parent result to this result.
+     *
+     * @param parentResult Source of the value variables to copy.
+     */
+    public void mergeValueVariables(ExprGenResult parentResult) {
+        valueVariables.addAll(parentResult.valueVariables);
+    }
+
+    /**
+     * Does the result have code that should be executed before evaluating {@link #value}?
+     *
+     * @return Whether code exists that should be executed before evaluating {@link #value}.
+     */
+    public boolean hasCode() {
+        Assert.implies(code.isEmpty(), codeVariables.isEmpty());
+        return !code.isEmpty();
+    }
+
+    /**
+     * Whether the result owns temporary variables needed to execute the {@link #code} part.
+     *
+     * @return Whether the {@link #code} uses temporary variables to obtain the {@link #value expression value}.
+     */
+    public boolean hasCodeVariables() {
+        Assert.implies(code.isEmpty(), codeVariables.isEmpty());
+        return !codeVariables.isEmpty();
+    }
+
+    /**
+     * Release the variables used in the {@link #code} of this result. After release the variables may be used for other
+     * purposes, executing the {@link #code} at that time may have unintended side-effects.
+     */
+    public void releaseCodeVariables() {
+        generator.releaseTempVariables(codeVariables);
+        codeVariables.clear();
+    }
+
+    /**
+     * Whether the expression generation result has temporary variables needed to evaluate the {@link #value} after
+     * executing the {@link #code} if it exists.
+     *
+     * @return Whether the expression generation result has temporary variables needed to evaluate the {@link #value}.
+     */
+    public boolean hasValueVariables() {
+        Assert.implies(value == null, valueVariables.isEmpty());
+        return !valueVariables.isEmpty();
+    }
+
+    /** Release the variables used in the {@link #value} result. After release, their content may change at any time. */
+    public void releaseValueVariables() {
+        generator.releaseTempVariables(valueVariables);
+        valueVariables.clear();
+    }
+
+    /**
+     * Set the result value.
+     *
+     * @param plcExpr Expression to give to the result.
+     * @return This result instance for daisy-chaining.
+     */
+    public ExprGenResult setValue(PlcExpression plcExpr) {
+        value = plcExpr;
+        return this;
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/conversion/expressions/ExprGenerator.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/conversion/expressions/ExprGenerator.java
new file mode 100644
index 0000000000000000000000000000000000000000..8e360e2039169f84534acfbc38c63aa18367b664
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/conversion/expressions/ExprGenerator.java
@@ -0,0 +1,1101 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.conversion.expressions;
+
+import static org.eclipse.escet.cif.common.CifTypeUtils.isRangeless;
+import static org.eclipse.escet.cif.common.CifTypeUtils.normalizeType;
+import static org.eclipse.escet.cif.common.CifValueUtils.flattenBinExpr;
+import static org.eclipse.escet.cif.common.CifValueUtils.getTupleProjIndex;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newIntType;
+import static org.eclipse.escet.cif.metamodel.java.CifConstructors.newRealType;
+import static org.eclipse.escet.common.java.Lists.copy;
+import static org.eclipse.escet.common.java.Lists.list;
+import static org.eclipse.escet.common.java.Lists.listc;
+import static org.eclipse.escet.common.java.Maps.map;
+import static org.eclipse.escet.common.java.Sets.set;
+
+import java.util.BitSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.escet.cif.common.CifTypeUtils;
+import org.eclipse.escet.cif.common.RangeCompat;
+import org.eclipse.escet.cif.metamodel.cif.expressions.AlgVariableExpression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.BinaryExpression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.BoolExpression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.CastExpression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.ConstantExpression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.ContVariableExpression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.DictExpression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.DiscVariableExpression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.ElifExpression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.EnumLiteralExpression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.Expression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.FunctionCallExpression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.FunctionExpression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.IfExpression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.InputVariableExpression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.IntExpression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.ListExpression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.LocationExpression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.ProjectionExpression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.RealExpression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.SetExpression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.SliceExpression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.StdLibFunction;
+import org.eclipse.escet.cif.metamodel.cif.expressions.StdLibFunctionExpression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.StringExpression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.TimeExpression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.TupleExpression;
+import org.eclipse.escet.cif.metamodel.cif.expressions.UnaryExpression;
+import org.eclipse.escet.cif.metamodel.cif.types.BoolType;
+import org.eclipse.escet.cif.metamodel.cif.types.CifType;
+import org.eclipse.escet.cif.metamodel.cif.types.EnumType;
+import org.eclipse.escet.cif.metamodel.cif.types.IntType;
+import org.eclipse.escet.cif.metamodel.cif.types.ListType;
+import org.eclipse.escet.cif.metamodel.cif.types.RealType;
+import org.eclipse.escet.cif.metamodel.cif.types.TupleType;
+import org.eclipse.escet.cif.plcgen.conversion.PlcFunctionAppls;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcVariable;
+import org.eclipse.escet.cif.plcgen.model.expressions.PlcBoolLiteral;
+import org.eclipse.escet.cif.plcgen.model.expressions.PlcExpression;
+import org.eclipse.escet.cif.plcgen.model.expressions.PlcIntLiteral;
+import org.eclipse.escet.cif.plcgen.model.expressions.PlcRealLiteral;
+import org.eclipse.escet.cif.plcgen.model.expressions.PlcValue;
+import org.eclipse.escet.cif.plcgen.model.expressions.PlcVarExpression;
+import org.eclipse.escet.cif.plcgen.model.expressions.PlcVarExpression.PlcArrayProjection;
+import org.eclipse.escet.cif.plcgen.model.expressions.PlcVarExpression.PlcProjection;
+import org.eclipse.escet.cif.plcgen.model.expressions.PlcVarExpression.PlcStructProjection;
+import org.eclipse.escet.cif.plcgen.model.functions.PlcFuncOperation;
+import org.eclipse.escet.cif.plcgen.model.statements.PlcAssignmentStatement;
+import org.eclipse.escet.cif.plcgen.model.statements.PlcSelectionStatement;
+import org.eclipse.escet.cif.plcgen.model.statements.PlcSelectionStatement.PlcSelectChoice;
+import org.eclipse.escet.cif.plcgen.model.statements.PlcStatement;
+import org.eclipse.escet.cif.plcgen.model.types.PlcStructType;
+import org.eclipse.escet.cif.plcgen.model.types.PlcType;
+import org.eclipse.escet.cif.plcgen.targets.PlcTarget;
+import org.eclipse.escet.common.java.Assert;
+import org.eclipse.escet.common.java.BitSetIterator;
+
+/** Converter of CIF expressions to PLC expressions and statements. */
+public class ExprGenerator {
+    /** An integer CIF type, used for type conversions. */
+    private static final CifType INT_TYPE = newIntType();
+
+    /** A real CIF type, used for type conversions. */
+    private static final CifType REAL_TYPE = newRealType();
+
+    /** Map for the name generator to create local variables. */
+    private final Map<String, Integer> localNameGenMap = map();
+
+    /** Local and temporary variables of the generator. */
+    private final List<PlcVariable> variables = list();
+
+    /** Map of variable names to their {@link #variables} index. */
+    private final Map<String, Integer> varNameToVarIndex = map();
+
+    /** Indices set of temporary variables. */
+    private final BitSet variableIsTemp = new BitSet();
+
+    /** Indices set of temporary variables that can be handed out. */
+    private final BitSet variableIsAvailable = new BitSet();
+
+    /** PLC target to generate code for. */
+    private final PlcTarget target;
+
+    /** Access to PLC equivalents of CIF data. */
+    private final CifDataProvider cifData;
+
+    /** PLC function applications of the target. */
+    private final PlcFunctionAppls funcAppls;
+
+    /**
+     * Constructor of the {@link ExprGenerator} class.
+     *
+     * @param target PLC target to generate code for.
+     * @param cifData Access to PLC equivalents of CIF data.
+     */
+    public ExprGenerator(PlcTarget target, CifDataProvider cifData) {
+        this.target = target;
+        this.cifData = cifData;
+        this.funcAppls = new PlcFunctionAppls(target);
+    }
+
+    /**
+     * Obtain a local scratch variable. Its name starts with the provided prefix, and it will have a PLC type that
+     * matches with the provided CIF type.
+     *
+     * @param prefix Initial part of the name of the variable.
+     * @param cifType CIF type to convert to a PLC type.
+     * @return The created variable.
+     */
+    public PlcVariable getTempVariable(String prefix, CifType cifType) {
+        PlcType plcType = target.getTypeGenerator().convertType(cifType);
+        return getTempVariable(prefix, plcType);
+    }
+
+    /**
+     * Obtain a local scratch variable. Its name starts with the provided prefix, and it will have the provided type.
+     *
+     * @param prefix Initial part of the name of the variable.
+     * @param plcType Type of the returned variable.
+     * @return The created variable.
+     */
+    public PlcVariable getTempVariable(String prefix, PlcType plcType) {
+        // 1. Attempt to find a temporary variable that can be used.
+        for (int idx: new BitSetIterator(variableIsAvailable)) {
+            PlcVariable var = variables.get(idx);
+            if (plcType.equals(var.type) && var.name.startsWith(prefix)) {
+                variableIsAvailable.clear(idx);
+                return var;
+            }
+        }
+
+        // 2. Make a new variable.
+        return createVariable(prefix, plcType, null, null, true);
+    }
+
+    /**
+     * Construct a local variable to use in the generated code.
+     *
+     * @param prefix Initial part of the name of the variable.
+     * @param plcType Type of the returned variable.
+     * @return The created variable.
+     */
+    public PlcVariable makeLocalVariable(String prefix, PlcType plcType) {
+        return createVariable(prefix, plcType, null, null, false);
+    }
+
+    /**
+     * Construct a local variable to use in the generated code.
+     *
+     * @param prefix Initial part of the name of the variable.
+     * @param plcType Type of the returned variable.
+     * @param address The address of the variable, or {@code null} if not specified.
+     * @param value The initial value of the variable, or {@code null} if not specified.
+     * @return The created variable.
+     */
+    public PlcVariable makeLocalVariable(String prefix, PlcType plcType, String address, PlcValue value) {
+        return createVariable(prefix, plcType, address, value, false);
+    }
+
+    /**
+     * Construct a new local variable and add it to the variable administration.
+     *
+     * @param prefix Initial part of the name of the variable.
+     * @param plcType Type of the returned variable.
+     * @param address The address of the variable, or {@code null} if not specified.
+     * @param value The initial value of the variable, or {@code null} if not specified.
+     * @param isTempVar Whether the variable is a temporary variable.
+     * @return The created variable.
+     * @note The new variable is not marked as available.
+     */
+    private PlcVariable createVariable(String prefix, PlcType plcType, String address, PlcValue value,
+            boolean isTempVar)
+    {
+        String name = target.getNameGenerator().generateLocalName(prefix, localNameGenMap);
+        PlcVariable newVar = new PlcVariable(name, plcType, address, value);
+        int newVarIndex = variables.size();
+        variables.add(newVar);
+        varNameToVarIndex.put(newVar.name, newVarIndex);
+        if (isTempVar) {
+            variableIsTemp.set(newVarIndex);
+        }
+        return newVar;
+    }
+
+    /**
+     * Give variables back to the generator for future re-use. Returning non-temporary variables is allowed but they are
+     * ignored.
+     *
+     * <p>
+     * Intended to be used by {@link ExprGenResult} instances.
+     * </p>
+     *
+     * @param variables Variables being returned.
+     */
+    public void releaseTempVariables(Set<PlcVariable> variables) {
+        for (PlcVariable var: variables) {
+            Integer idx = varNameToVarIndex.get(var.name);
+            if (idx == null || !variableIsTemp.get(idx)) {
+                continue;
+            }
+            variableIsAvailable.set(idx);
+        }
+    }
+
+    /**
+     * Convert a CIF expression to a combination of PLC expressions and statements.
+     *
+     * @param expr CIF expression to convert.
+     * @return The converted expression.
+     */
+    public ExprGenResult convertExpr(Expression expr) {
+        if (expr instanceof BoolExpression be) {
+            return new ExprGenResult(this).setValue(new PlcBoolLiteral(be.isValue()));
+        } else if (expr instanceof IntExpression ie) {
+            return new ExprGenResult(this).setValue(new PlcIntLiteral(ie.getValue()));
+        } else if (expr instanceof RealExpression re) {
+            return new ExprGenResult(this).setValue(new PlcRealLiteral(re.getValue()));
+        } else if (expr instanceof StringExpression) {
+            throw new RuntimeException("Precondition violation.");
+        } else if (expr instanceof TimeExpression) {
+            throw new RuntimeException("Precondition violation.");
+        } else if (expr instanceof CastExpression ce) {
+            return convertCastExpr(ce);
+        } else if (expr instanceof UnaryExpression ue) {
+            return convertUnaryExpr(ue);
+        } else if (expr instanceof BinaryExpression be) {
+            return convertBinaryExpr(be);
+        } else if (expr instanceof IfExpression ife) {
+            return convertIfExpr(ife);
+        } else if (expr instanceof ProjectionExpression pe) {
+            return convertProjectionExpr(pe);
+        } else if (expr instanceof SliceExpression) {
+            throw new RuntimeException("Precondition violation.");
+        } else if (expr instanceof FunctionCallExpression fce) {
+            return convertFuncCallExpr(fce);
+        } else if (expr instanceof ListExpression le) {
+            return convertArrayExpr(le);
+        } else if (expr instanceof SetExpression) {
+            throw new RuntimeException("Precondition violation.");
+        } else if (expr instanceof TupleExpression te) {
+            return convertTupleExpr(te);
+        } else if (expr instanceof DictExpression) {
+            throw new RuntimeException("Precondition violation.");
+        } else if (expr instanceof ConstantExpression ce) {
+            return new ExprGenResult(this).setValue(cifData.getExprForConstant(ce.getConstant()));
+        } else if (expr instanceof DiscVariableExpression de) {
+            // TODO This may not work for user-defined internal function parameters and local variables.
+            return new ExprGenResult(this).setValue(cifData.getExprForDiscVar(de.getVariable()));
+        } else if (expr instanceof AlgVariableExpression ae) {
+            // TODO: Decide how to deal with algebraic variables.
+            return convertExpr(ae.getVariable().getValue()); // Convert its definition.
+        } else if (expr instanceof ContVariableExpression ce) {
+            return new ExprGenResult(this).setValue(cifData.getExprForContvar(ce.getVariable(), ce.isDerivative()));
+        } else if (expr instanceof LocationExpression le) {
+            return new ExprGenResult(this).setValue(cifData.getExprForLocation(le.getLocation()));
+        } else if (expr instanceof EnumLiteralExpression eLit) {
+            return new ExprGenResult(this).setValue(target.getTypeGenerator().getPlcEnumLiteral(eLit.getLiteral()));
+        } else if (expr instanceof FunctionExpression) {
+            throw new RuntimeException("Precondition violation.");
+        } else if (expr instanceof InputVariableExpression ie) {
+            return new ExprGenResult(this).setValue(cifData.getExprForInputVar(ie.getVariable()));
+        }
+        throw new RuntimeException("Unexpected expr: " + expr);
+    }
+
+    /**
+     * Convert a cast expression.
+     *
+     * @param castExpr Expression to convert.
+     * @return The generated result.
+     */
+    private ExprGenResult convertCastExpr(CastExpression castExpr) {
+        ExprGenResult result = convertExpr(castExpr.getChild());
+        CifType ctype = normalizeType(castExpr.getChild().getType());
+        CifType rtype = normalizeType(castExpr.getType());
+        if (ctype instanceof IntType && rtype instanceof RealType) {
+            return result
+                    .setValue(funcAppls.castFunctionAppl(result.value, target.getIntegerType(), target.getRealType()));
+        }
+        if (CifTypeUtils.checkTypeCompat(ctype, rtype, RangeCompat.EQUAL)) {
+            // Ignore cast expression.
+            return result;
+        }
+
+        throw new RuntimeException("Precondition violation.");
+    }
+
+    /**
+     * Convert a unary operator expression.
+     *
+     * @param unaryExpr Expression to convert.
+     * @return The generated result.
+     */
+    private ExprGenResult convertUnaryExpr(UnaryExpression unaryExpr) {
+        ExprGenResult result = convertExpr(unaryExpr.getChild());
+        switch (unaryExpr.getOperator()) {
+            case INVERSE:
+                return result.setValue(funcAppls.complementFuncAppl(result.value));
+
+            case NEGATE:
+                return result.setValue(funcAppls.negateFuncAppl(result.value));
+
+            case PLUS:
+                return result;
+
+            case SAMPLE:
+                throw new RuntimeException("Precondition violation.");
+
+            default:
+                throw new RuntimeException("Unknown unop: " + unaryExpr.getOperator());
+        }
+    }
+
+    /**
+     * Convert a binary operator expression.
+     *
+     * @param binExpr Binary expression to convert.
+     * @return The generated result.
+     */
+    private ExprGenResult convertBinaryExpr(BinaryExpression binExpr) {
+        CifType ltype = normalizeType(binExpr.getLeft().getType());
+        CifType rtype = normalizeType(binExpr.getRight().getType());
+
+        ExprGenResult leftResult = convertExpr(binExpr.getLeft());
+        ExprGenResult rightResult = convertExpr(binExpr.getRight());
+        ExprGenResult result = new ExprGenResult(this, leftResult, rightResult);
+        switch (binExpr.getOperator()) {
+            case IMPLICATION:
+                // Right-value or not left-value.
+                return result.setValue(
+                        funcAppls.orFuncAppl(rightResult.value, funcAppls.complementFuncAppl(leftResult.value)));
+
+            case BI_CONDITIONAL:
+                return result.setValue(funcAppls.equalFuncAppl(leftResult.value, rightResult.value));
+
+            case DISJUNCTION:
+                if (ltype instanceof BoolType) {
+                    return convertFlattenedExpr(binExpr);
+                }
+
+                throw new RuntimeException("Precondition violation.");
+
+            case CONJUNCTION:
+                if (ltype instanceof BoolType) {
+                    return convertFlattenedExpr(binExpr);
+                }
+
+                throw new RuntimeException("Precondition violation.");
+
+            case LESS_THAN: {
+                // S7-400 and S7-300 only support less than on the same types.
+                PlcExpression leftSide = unifyTypeOfExpr(leftResult.value, ltype, rtype);
+                PlcExpression rightSide = unifyTypeOfExpr(rightResult.value, rtype, ltype);
+                return result.setValue(funcAppls.lessThanFuncAppl(leftSide, rightSide));
+            }
+
+            case LESS_EQUAL: {
+                // S7-400 and S7-300 only support less equal on the same types.
+                PlcExpression leftSide = unifyTypeOfExpr(leftResult.value, ltype, rtype);
+                PlcExpression rightSide = unifyTypeOfExpr(rightResult.value, rtype, ltype);
+                return result.setValue(funcAppls.lessEqualFuncAppl(leftSide, rightSide));
+            }
+
+            case GREATER_THAN: {
+                // S7-400 and S7-300 only support greater than on the same types.
+                PlcExpression leftSide = unifyTypeOfExpr(leftResult.value, ltype, rtype);
+                PlcExpression rightSide = unifyTypeOfExpr(rightResult.value, rtype, ltype);
+                return result.setValue(funcAppls.greaterThanFuncAppl(leftSide, rightSide));
+            }
+
+            case GREATER_EQUAL: {
+                // S7-400 and S7-300 only support greater equal on the same types.
+                PlcExpression leftSide = unifyTypeOfExpr(leftResult.value, ltype, rtype);
+                PlcExpression rightSide = unifyTypeOfExpr(rightResult.value, rtype, ltype);
+                return result.setValue(funcAppls.greaterEqualFuncAppl(leftSide, rightSide));
+            }
+
+            case EQUAL:
+                // Comparing structure types is not allowed in IEC 61131-3,
+                // and thus equality on tuples can't be supported directly.
+                // We could always create code for it though.
+                if (ltype instanceof BoolType || ltype instanceof IntType || ltype instanceof RealType
+                        || ltype instanceof EnumType)
+                {
+                    return result.setValue(funcAppls.equalFuncAppl(leftResult.value, rightResult.value));
+                }
+
+                throw new RuntimeException("Precondition violation.");
+
+            case UNEQUAL:
+                // Comparing structure types is not allowed in IEC 61131-3,
+                // and thus equality on tuples can't be supported directly.
+                // We could always create code for it though.
+                if (ltype instanceof BoolType || ltype instanceof IntType || ltype instanceof RealType
+                        || ltype instanceof EnumType)
+                {
+                    return result.setValue(funcAppls.unEqualFuncAppl(leftResult.value, rightResult.value));
+                }
+
+                throw new RuntimeException("Precondition violation.");
+
+            case ADDITION:
+                if (ltype instanceof IntType || ltype instanceof RealType) {
+                    return convertFlattenedExpr(binExpr);
+                }
+
+                throw new RuntimeException("Precondition violation.");
+
+            case SUBTRACTION:
+                // S7-400 and S7-300 only support subtraction on the same types.
+                if (ltype instanceof IntType || ltype instanceof RealType) {
+                    PlcExpression leftSide = unifyTypeOfExpr(leftResult.value, ltype, rtype);
+                    PlcExpression rightSide = unifyTypeOfExpr(rightResult.value, rtype, ltype);
+                    return result.setValue(funcAppls.subtractFuncAppl(leftSide, rightSide));
+                }
+
+                throw new RuntimeException("Precondition violation.");
+
+            case MULTIPLICATION:
+                return convertFlattenedExpr(binExpr);
+
+            case DIVISION: {
+                // S7-400 and S7-300 only support division on the same types.
+                PlcExpression leftSide = unifyTypeOfExpr(leftResult.value, ltype, REAL_TYPE);
+                PlcExpression rightSide = unifyTypeOfExpr(rightResult.value, rtype, REAL_TYPE);
+                return result.setValue(funcAppls.divideFuncAppl(leftSide, rightSide));
+            }
+
+            case INTEGER_DIVISION:
+                // Truncated towards zero in both CIF and IEC 61131-3.
+                return result.setValue(funcAppls.divideFuncAppl(leftResult.value, rightResult.value));
+
+            case MODULUS:
+                // Note that in CIF division by zero is an error, while
+                // in IEC 61131-3 it results in zero.
+                return result.setValue(funcAppls.moduloFuncAppl(leftResult.value, rightResult.value));
+
+            case ELEMENT_OF:
+                throw new RuntimeException("Precondition violation.");
+
+            case SUBSET:
+                throw new RuntimeException("Precondition violation.");
+
+            default:
+                throw new RuntimeException("Unknown binary expression operator: " + binExpr.getOperator());
+        }
+    }
+
+    /**
+     * Flatten the binary expression on its operator, convert the collection children, and combine the children into an
+     * n-ary PLC function.
+     *
+     * @param binExpr Binary expression to flatten and convert. Must be a disjunction, conjunction, addition, or
+     *     multiplication expression.
+     * @return The converted expression.
+     */
+    private ExprGenResult convertFlattenedExpr(BinaryExpression binExpr) {
+        // Configure some variables to guide the conversion.
+        java.util.function.Function<PlcExpression[], PlcExpression> applFunc;
+        boolean unifyTypes;
+        switch (binExpr.getOperator()) {
+            case DISJUNCTION:
+                applFunc = values -> funcAppls.orFuncAppl(values);
+                unifyTypes = false;
+                break;
+            case CONJUNCTION:
+                applFunc = values -> funcAppls.andFuncAppl(values);
+                unifyTypes = false;
+                break;
+            case ADDITION:
+                applFunc = values -> funcAppls.addFuncAppl(values);
+                unifyTypes = true; // S7-400 and S7-300 only support addition on the same types.
+                break;
+            case MULTIPLICATION:
+                applFunc = values -> funcAppls.multiplyFuncAppl(values);
+                unifyTypes = true; // S7-400 and S7-300 only support multiplication on the same types.
+                break;
+            default:
+                throw new RuntimeException("Unexpected flattened binary expression operator: " + binExpr.getOperator());
+        }
+
+        // Collect the child expressions and compute a unified type if needed.
+        List<Expression> exprs = flattenBinExpr(List.of(binExpr), binExpr.getOperator());
+        CifType unifiedType;
+        if (unifyTypes) {
+            unifiedType = INT_TYPE;
+            for (Expression expr: exprs) {
+                if (normalizeType(expr.getType()) instanceof RealType) {
+                    unifiedType = REAL_TYPE;
+                    break;
+                }
+            }
+        } else {
+            unifiedType = null;
+        }
+
+        // Convert each child expression, and collect the child results as preparation to their merge. Also collect the
+        // child result expressions separately as they need to be applied to the N-ary function decided above.
+        ExprGenResult[] exprGenResults = new ExprGenResult[exprs.size()];
+        PlcExpression[] values = new PlcExpression[exprs.size()];
+        int i = 0;
+        for (Expression expr: exprs) {
+            exprGenResults[i] = convertExpr(expr);
+            if (unifyTypes) {
+                values[i] = unifyTypeOfExpr(exprGenResults[i].value, normalizeType(expr.getType()), unifiedType);
+            } else {
+                values[i] = exprGenResults[i].value;
+            }
+            i++;
+        }
+
+        // Create the final result and give it to the caller.
+        ExprGenResult exprGenResult = new ExprGenResult(this, exprGenResults);
+        return exprGenResult.setValue(applFunc.apply(values));
+    }
+
+    /**
+     * Convert an 'if' expression to PLC code.
+     *
+     * @param ifExpr Expression to convert.
+     * @return The converted expression.
+     */
+    private ExprGenResult convertIfExpr(IfExpression ifExpr) {
+        ExprGenResult result = new ExprGenResult(this);
+        PlcType resultValueType = target.getTypeGenerator().convertType(ifExpr.getType());
+        PlcVariable resultVar = getTempVariable("ifResult", resultValueType);
+        result.valueVariables.add(resultVar);
+        result.setValue(new PlcVarExpression(resultVar));
+
+        PlcSelectionStatement selStat = null;
+        selStat = addBranch(ifExpr.getGuards(), ifExpr.getThen(), resultVar, selStat, result.code);
+
+        for (ElifExpression elif: ifExpr.getElifs()) {
+            selStat = addBranch(elif.getGuards(), elif.getThen(), resultVar, selStat, result.code);
+        }
+        addBranch(null, ifExpr.getElse(), resultVar, selStat, result.code);
+        return result;
+    }
+
+    /**
+     * Append an {@link IfExpression} branch to the PLC code.
+     *
+     * <p>
+     * Conceptually this function appends a <pre>ELSE IF guards THEN resultVar := thenExpr</pre> branch to the selection
+     * statement in {@code selStat}. The {@code guards} variable also controls whether there is a condition at all to
+     * test and {@code selStat} controls whether the first branch is created.
+     * </p>
+     * <p>
+     * The difficulty here is that the converted {@code guards} may have generated code attached which must be executed
+     * before evaluating the guards condition. The PLC {@code IF} statement does not support that.
+     * </p>
+     * <p>
+     * Therefore in such a case the current {@code selStat} cannot be extended with another {@code IF} branch. Instead,
+     * the code attached to the converted guards must be put in its {@code ELSE} branch so it can be executed. Below
+     * that code, a new selection statement must be started to evaluate the guards and possibly perform the assignment.
+     * That is, it generates <pre> ELSE
+     *     // Code to perform before evaluating the guards.
+     *     IF guard-expr THEN resultVar := thenExpr
+     *     ... // Possibly more branches will be added.
+     *     END_IF
+     * END_IF</pre> where the top {@code ELSE} and bottom {@code END_IF} are part of the supplied {@code selStat}.
+     * </p>
+     * <p>
+     * In addition, next branches must now be added to this new selection statement. The returned value thus changes to
+     * the new selection statement.
+     * </p>
+     *
+     * @param guards CIF expressions that must hold to select the branch. Is {@code null} for the 'else' branch.
+     * @param thenExpr Expression value to return if the guards hold.
+     * @param resultVar Variable to assign the 'thenExpr' value to.
+     * @param selStat Selection statement used the previous time, or {@code null} if no selection statement has been
+     *     created yet.
+     * @param rootCode Code block for storing the entire 'if' expression.
+     * @return The last used selection statement after adding the branch.
+     */
+    private PlcSelectionStatement addBranch(List<Expression> guards, Expression thenExpr, PlcVariable resultVar,
+            PlcSelectionStatement selStat, List<PlcStatement> rootCode)
+    {
+        // Place to store generated guard condition code. If no guards are present (that is, it's the 'else' of the
+        // 'if' expression), the final assignment of the return value is put there.
+        List<PlcStatement> codeStorage = (selStat != null) ? selStat.elseStats : rootCode;
+
+        if (guards != null) {
+            // Convert the guard conditions. Copy any generated code into storage, collect the used variables and the
+            // converted expression for the final N-ary AND.
+            PlcExpression[] grdValues = new PlcExpression[guards.size()];
+            boolean seenGuardCode = false;
+            Set<PlcVariable> grdVariables = set();
+
+            // For all guard expressions, convert them and store their output.
+            int grdNum = 0;
+            for (Expression guard: guards) {
+                ExprGenResult grdResult = convertExpr(guard);
+                if (grdResult.hasCode()) {
+                    seenGuardCode = true;
+                    codeStorage.addAll(grdResult.code);
+                    grdVariables.addAll(grdResult.codeVariables);
+                }
+                grdVariables.addAll(grdResult.valueVariables);
+                grdValues[grdNum] = grdResult.value;
+                grdNum++;
+            }
+
+            // If there is no previous selection statement or we added code to the 'else' branch of it, the previous
+            // selection statement cannot be used for this branch. Append a new selection statement to the code block
+            // in that case.
+            if (selStat == null || seenGuardCode) {
+                selStat = new PlcSelectionStatement();
+                codeStorage.add(selStat);
+            }
+
+            // Add a new branch in the previous selection statement or in the just appended new selection statement.
+            PlcSelectChoice choice;
+            if (grdNum == 1) {
+                choice = new PlcSelectChoice(grdValues[0], list());
+            } else {
+                choice = new PlcSelectChoice(funcAppls.andFuncAppl(grdValues), list());
+            }
+            selStat.condChoices.add(choice);
+            releaseTempVariables(grdVariables);
+
+            // The 'then' statements of that choice are now the spot to write the 'then' code + value.
+            codeStorage = choice.thenStats;
+        }
+        // else there is no guard and 'codeStorage' already points at the right spot for writing the final 'else' code +
+        // value.
+
+        // Convert the result value. As we released the guard condition temporaries above, these may be used again here.
+        ExprGenResult retValueResult = convertExpr(thenExpr);
+        codeStorage.addAll(retValueResult.code);
+        codeStorage.add(new PlcAssignmentStatement(new PlcVarExpression(resultVar), retValueResult.value));
+        releaseTempVariables(retValueResult.codeVariables);
+        releaseTempVariables(retValueResult.valueVariables);
+        return selStat;
+    }
+
+    /**
+     * Convert projection expressions to a PLC expression.
+     *
+     * @param expr Projection expression to convert.
+     * @return The converted expression.
+     */
+    private ExprGenResult convertProjectionExpr(Expression expr) {
+        // Unwrap and store the nested projections, last projection at index 0.
+        List<ProjectionExpression> projections = list();
+        while (expr instanceof ProjectionExpression proj) {
+            projections.add(proj);
+            expr = proj.getChild();
+        }
+        Assert.check(!projections.isEmpty());
+
+        // Convert the projection root value and make it usable for the PLC.
+        ExprGenResult exprResult = convertExpr(expr);
+
+        // Setup the result of this method and prepare it for stacking the above collected projections on top of it.
+        if (exprResult.value instanceof PlcVarExpression parentVarExpr) {
+            // We received a variable to project at, grab the result to add more projections.
+
+            // Build a new PLC projections expressions with the parent variable and the collected projections.
+            PlcVarExpression varExpr = new PlcVarExpression(parentVarExpr.variable,
+                    convertAddProjections(projections, copy(parentVarExpr.projections), exprResult));
+            exprResult.setValue(varExpr);
+            return exprResult;
+        } else {
+            // We got something different than a single variable. Assume the worst and use a new variable.
+            PlcType plcType = target.getTypeGenerator().convertType(expr.getType());
+            PlcVariable projectVar = getTempVariable("project", plcType);
+
+            // Construct a new result, add the parent result, and append "projectVar := <root-value expression>;" to the
+            // code to get the parent result in the new variable.
+            ExprGenResult convertResult = new ExprGenResult(this, exprResult);
+            PlcVarExpression varExpr = new PlcVarExpression(projectVar);
+            convertResult.code.add(new PlcAssignmentStatement(varExpr, convertResult.value));
+            convertResult.codeVariables.addAll(exprResult.valueVariables); // Parent value is now in code.
+
+            // Convert the CIF projections that were on top of the projection root value and apply them to the new
+            // variable.
+            convertResult.setValue(
+                    new PlcVarExpression(projectVar, convertAddProjections(projections, list(), convertResult)));
+            convertResult.valueVariables.add(projectVar);
+            return convertResult;
+        }
+    }
+
+    /**
+     * Convert CIF projections to PLC projections while reversing order and add them after the supplied PLC projections.
+     *
+     * @param cifProjections CIF projections to convert, in reverse order. Last projection to apply should be at index
+     *     {@code 0}.
+     * @param plcProjections Storage of converted CIF projections. Is extended in-place.
+     * @param convertResult Storage of expression generator results from CIF array index expressions.
+     * @return The updated list PLC projections.
+     */
+    private List<PlcProjection> convertAddProjections(List<ProjectionExpression> cifProjections,
+            List<PlcProjection> plcProjections, ExprGenResult convertResult)
+    {
+        for (int i = cifProjections.size() - 1; i >= 0; i--) {
+            ProjectionExpression cifProjection = cifProjections.get(i);
+            CifType unProjectedType = normalizeType(cifProjection.getChild().getType());
+            Expression cifIndexExpr = cifProjection.getIndex();
+
+            if (unProjectedType instanceof ListType lt) {
+                // Convert the index.
+                ExprGenResult indexResult = convertExpr(cifIndexExpr);
+                convertResult.mergeCodeAndVariables(indexResult);
+
+                PlcExpression normalizedIndex = funcAppls.normalizeArrayIndex(indexResult.value, lt.getUpper());
+                plcProjections.add(new PlcArrayProjection(normalizedIndex));
+            } else if (unProjectedType instanceof TupleType tt) {
+                int fieldIndex = getTupleProjIndex(cifProjection);
+
+                PlcType structTypeName = target.getTypeGenerator().convertType(unProjectedType);
+                PlcStructType structType = target.getTypeGenerator().getStructureType(structTypeName);
+                plcProjections.add(new PlcStructProjection(structType.fields.get(fieldIndex).name));
+            } else {
+                throw new AssertionError("Unexpected unprojected type \"" + unProjectedType + "\" found.");
+            }
+        }
+        return plcProjections;
+    }
+
+    /**
+     * Convert a function call.
+     *
+     * @param funcCallExpr Expression performing the call.
+     * @return The converted expression.
+     */
+    private ExprGenResult convertFuncCallExpr(FunctionCallExpression funcCallExpr) {
+        // Convert all parameters of the call.
+        List<ExprGenResult> argumentResults = listc(funcCallExpr.getParams().size());
+        for (Expression param: funcCallExpr.getParams()) {
+            argumentResults.add(convertExpr(param));
+        }
+
+        // Dispatch call construction based on the function being called.
+        Expression fexpr = funcCallExpr.getFunction();
+        if (fexpr instanceof StdLibFunctionExpression stdlibExpr) {
+            return convertStdlibExpr(funcCallExpr, argumentResults);
+        }
+        // TODO: Implement function calls to internal user-defined functions.
+        throw new RuntimeException("Calls to internal user-defined functions are not implemented yet.");
+    }
+
+    /**
+     * Convert a call to a standard library function.
+     *
+     * @param stdlibCallExpr The performed call to convert.
+     * @param argumentResults Already converted argument values of the call.
+     * @return The converted expression.
+     */
+    private ExprGenResult convertStdlibExpr(FunctionCallExpression stdlibCallExpr,
+            List<ExprGenResult> argumentResults)
+    {
+        List<Expression> arguments = stdlibCallExpr.getParams();
+        StdLibFunction stdlib = ((StdLibFunctionExpression)stdlibCallExpr.getFunction()).getFunction();
+        switch (stdlib) {
+            case ABS: {
+                Assert.check(argumentResults.size() == 1);
+                ExprGenResult arg1 = argumentResults.get(0);
+                return arg1.setValue(funcAppls.absFuncAppl(arg1.value));
+            }
+
+            case CBRT: {
+                // Use reals to get real result. Use two real-typed values to support S7-400 and S7-300.
+                PlcExpression expValue = funcAppls.divideFuncAppl(new PlcRealLiteral("1.0"), new PlcRealLiteral("3.0"));
+
+                Assert.check(argumentResults.size() == 1);
+                ExprGenResult arg1 = argumentResults.get(0);
+                return arg1.setValue(funcAppls.powerFuncAppl(arg1.value, expValue));
+            }
+
+            case CEIL:
+                // Unsupported. IEC 61131-3 has only TRUNC (round
+                // towards zero) and REAL_TO_INT (rounds to the nearest
+                // even integer if equally far from two integers).
+                throw new RuntimeException("Precondition violation.");
+
+            case DELETE:
+                // Unsupported.
+                throw new RuntimeException("Precondition violation.");
+
+            case EMPTY:
+                // Unsupported.
+                throw new RuntimeException("Precondition violation.");
+
+            case EXP: {
+                Assert.check(argumentResults.size() == 1);
+                ExprGenResult arg1 = argumentResults.get(0);
+                return arg1.setValue(funcAppls.expFuncAppl(arg1.value));
+            }
+
+            case FLOOR:
+                // Unsupported. IEC 61131-3 has only TRUNC (round
+                // towards zero) and REAL_TO_INT (rounds to the nearest
+                // even integer if equally far from two integers).
+                throw new RuntimeException("Precondition violation.");
+
+            case FORMAT:
+                // Unsupported.
+                throw new RuntimeException("Precondition violation.");
+
+            case LN: {
+                Assert.check(argumentResults.size() == 1);
+                ExprGenResult arg1 = argumentResults.get(0);
+                return arg1.setValue(funcAppls.lnFuncAppl(arg1.value));
+            }
+
+            case LOG: {
+                Assert.check(argumentResults.size() == 1);
+                ExprGenResult arg1 = argumentResults.get(0);
+
+                if (!target.supportsOperation(PlcFuncOperation.STDLIB_LOG)) {
+                    // Fallback to log10(x) = ln(x) / ln(10).
+                    PlcExpression lnX = funcAppls.lnFuncAppl(arg1.value);
+                    PlcExpression ln10 = funcAppls.lnFuncAppl(new PlcRealLiteral("10.0"));
+                    return arg1.setValue(funcAppls.divideFuncAppl(lnX, ln10));
+                }
+                return arg1.setValue(funcAppls.logFuncAppl(arg1.value));
+            }
+
+            case MAXIMUM:
+            case MINIMUM: {
+                CifType ltype = normalizeType(arguments.get(0).getType());
+                CifType rtype = normalizeType(arguments.get(1).getType());
+                PlcExpression leftSide = unifyTypeOfExpr(argumentResults.get(0).value, ltype, rtype);
+                PlcExpression rightSide = unifyTypeOfExpr(argumentResults.get(1).value, rtype, ltype);
+
+                // TODO Both MIN and MAX can be flattened to N-ary function calls thus allowing to perform multiple such
+                // CIF function calls at the same time.
+                ExprGenResult result = new ExprGenResult(this, argumentResults.get(0), argumentResults.get(1));
+                if (stdlib == StdLibFunction.MAXIMUM) {
+                    return result.setValue(funcAppls.maxFuncAppl(leftSide, rightSide));
+                } else {
+                    return result.setValue(funcAppls.minFuncAppl(leftSide, rightSide));
+                }
+            }
+
+            case POP:
+                // Unsupported.
+                throw new RuntimeException("Precondition violation.");
+
+            case POWER: {
+                CifType baseType = normalizeType(arguments.get(0).getType());
+                CifType exponentType = normalizeType(arguments.get(1).getType());
+                boolean baseIsInt = baseType instanceof IntType;
+                boolean exponentIsInt = exponentType instanceof IntType;
+
+                // CIF input and output expectations.
+                boolean baseAllowsInt = baseIsInt && !isRangeless((IntType)baseType);
+                boolean exponentAllowsInt = exponentIsInt && !isRangeless((IntType)exponentType)
+                        && ((IntType)exponentType).getLower() >= 0;
+                boolean cifIntResult = baseAllowsInt & exponentAllowsInt;
+
+                // Find an input type combination that works for the PLC.
+                boolean plcBaseIsInt = baseIsInt;
+                boolean plcExponentIsInt = exponentIsInt;
+                if (!target.supportsPower(plcBaseIsInt, plcExponentIsInt) && plcBaseIsInt) {
+                    plcBaseIsInt = false; // 'int ** X' doesn't work, use a real as base type.
+                }
+                if (!target.supportsPower(plcBaseIsInt, plcExponentIsInt) && plcExponentIsInt) {
+                    plcExponentIsInt = false; // 'X ** int' doesn't work, use a real as exponent type.
+                }
+                // Either a working combination has been found or we fell back to the always supported
+                // POW(real, real) case.
+
+                // Convert both sides if needed.
+                PlcExpression baseSide = argumentResults.get(0).value;
+                if (baseIsInt && !plcBaseIsInt) {
+                    baseSide = funcAppls.castFunctionAppl(baseSide, target.getIntegerType(), target.getRealType());
+                }
+                PlcExpression exponentSide = argumentResults.get(1).value;
+                if (exponentIsInt && !plcExponentIsInt) {
+                    exponentSide = funcAppls.castFunctionAppl(exponentSide, target.getIntegerType(),
+                            target.getRealType());
+                }
+
+                // Generate the call.
+                PlcExpression powCall = funcAppls.powerFuncAppl(baseSide, exponentSide);
+                boolean plcIntResult = plcBaseIsInt & plcExponentIsInt;
+
+                // Convert the result back if CIF and PLC types are not the same. Note that the PLC cannot reach an
+                // integer typed result if CIF does not have it as the PLC sides are never changed to integer type.
+                if (cifIntResult && !plcIntResult) {
+                    powCall = funcAppls.castFunctionAppl(powCall, target.getRealType(), target.getIntegerType());
+                }
+
+                ExprGenResult result = new ExprGenResult(this, argumentResults.get(0), argumentResults.get(1));
+                return result.setValue(powCall);
+            }
+
+            case ROUND:
+                // Unsupported. IEC 61131-3 has only TRUNC (round
+                // towards zero) and REAL_TO_INT (rounds to the nearest
+                // even integer if equally far from two integers).
+                throw new RuntimeException("Precondition violation.");
+
+            case SCALE:
+                // Unsupported. We could support this by expanding
+                // it to the definition of 'scale', using addition,
+                // subtraction, etc.
+                throw new RuntimeException("Precondition violation.");
+
+            case SIGN:
+                // Unsupported. We could support this by adding our
+                // own sign function.
+                throw new RuntimeException("Precondition violation.");
+
+            case SIZE:
+                // Unsupported.
+                throw new RuntimeException("Precondition violation.");
+
+            case SQRT: {
+                Assert.check(argumentResults.size() == 1);
+                ExprGenResult arg1 = argumentResults.get(0);
+                return arg1.setValue(funcAppls.sqrtFuncAppl(arg1.value));
+            }
+
+            case ACOS: {
+                Assert.check(argumentResults.size() == 1);
+                ExprGenResult arg1 = argumentResults.get(0);
+                return arg1.setValue(funcAppls.acosFuncAppl(arg1.value));
+            }
+
+            case ASIN: {
+                Assert.check(argumentResults.size() == 1);
+                ExprGenResult arg1 = argumentResults.get(0);
+                return arg1.setValue(funcAppls.asinFuncAppl(arg1.value));
+            }
+
+            case ATAN: {
+                Assert.check(argumentResults.size() == 1);
+                ExprGenResult arg1 = argumentResults.get(0);
+                return arg1.setValue(funcAppls.atanFuncAppl(arg1.value));
+            }
+
+            case COS: {
+                Assert.check(argumentResults.size() == 1);
+                ExprGenResult arg1 = argumentResults.get(0);
+                return arg1.setValue(funcAppls.cosFuncAppl(arg1.value));
+            }
+
+            case SIN: {
+                Assert.check(argumentResults.size() == 1);
+                ExprGenResult arg1 = argumentResults.get(0);
+                return arg1.setValue(funcAppls.sinFuncAppl(arg1.value));
+            }
+
+            case TAN: {
+                Assert.check(argumentResults.size() == 1);
+                ExprGenResult arg1 = argumentResults.get(0);
+                return arg1.setValue(funcAppls.tanFuncAppl(arg1.value));
+            }
+
+            case ACOSH:
+            case ASINH:
+            case ATANH:
+            case COSH:
+            case SINH:
+            case TANH:
+                // Unsupported.
+                throw new RuntimeException("Precondition violation.");
+
+            case BERNOULLI:
+            case BETA:
+            case BINOMIAL:
+            case CONSTANT:
+            case ERLANG:
+            case EXPONENTIAL:
+            case GAMMA:
+            case GEOMETRIC:
+            case LOG_NORMAL:
+            case NORMAL:
+            case POISSON:
+            case RANDOM:
+            case TRIANGLE:
+            case UNIFORM:
+            case WEIBULL:
+                // Unsupported.
+                throw new RuntimeException("Precondition violation.");
+        }
+        throw new RuntimeException("Unexpected standard library function: " + stdlib);
+    }
+
+    /**
+     * Convert an array literal expression to PLC code.
+     *
+     * @param listExpr Expression to convert.
+     * @return The converted expression.
+     */
+    private ExprGenResult convertArrayExpr(ListExpression listExpr) {
+        PlcType listType = target.getTypeGenerator().convertType(listExpr.getType());
+        PlcVariable arrayVar = getTempVariable("litArray", listType);
+
+        ExprGenResult result = new ExprGenResult(this);
+        int idx = 0;
+        for (Expression e: listExpr.getElements()) {
+            ExprGenResult childResult = convertExpr(e);
+            // Add child computation to the result, return the temporary variables of it.
+            result.mergeCode(childResult);
+            releaseTempVariables(childResult.codeVariables);
+
+            // Construct assignment.
+            PlcArrayProjection arrayProj = new PlcArrayProjection(List.of(new PlcIntLiteral(idx)));
+            PlcVarExpression lhs = new PlcVarExpression(arrayVar, List.of(arrayProj));
+            PlcAssignmentStatement assignment = new PlcAssignmentStatement(lhs, childResult.value);
+            idx++;
+
+            // Add statement to the result.
+            result.code.add(assignment);
+            releaseTempVariables(childResult.valueVariables);
+        }
+        result.valueVariables.add(arrayVar);
+        return result.setValue(new PlcVarExpression(arrayVar));
+    }
+
+    /**
+     * Convert a tuple literal expression to PLC code.
+     *
+     * @param tupleExpr Expression to convert.
+     * @return The converted expression.
+     */
+    private ExprGenResult convertTupleExpr(TupleExpression tupleExpr) {
+        // Construct the destination variable.
+        PlcType varType = target.getTypeGenerator().convertType(tupleExpr.getType());
+        PlcVariable structVar = getTempVariable("litStruct", varType);
+
+        // Get the underlying structure type.
+        PlcStructType structType = target.getTypeGenerator().getStructureType(varType);
+
+        // Convert the values of the tuple expression and assign them to fields of the destination variable.
+        ExprGenResult result = new ExprGenResult(this);
+        int idx = 0;
+        for (Expression e: tupleExpr.getFields()) {
+            ExprGenResult childResult = convertExpr(e);
+            // Add child computation to the result, return the temporary variables of it.
+            result.mergeCode(childResult);
+            releaseTempVariables(childResult.codeVariables);
+
+            // Construct assignment.
+            PlcStructProjection structProj = new PlcStructProjection(structType.fields.get(idx).name);
+            PlcVarExpression lhs = new PlcVarExpression(structVar, List.of(structProj));
+            PlcAssignmentStatement assignment = new PlcAssignmentStatement(lhs, childResult.value);
+            idx++;
+
+            // Add statement to the result.
+            result.code.add(assignment);
+            releaseTempVariables(childResult.valueVariables);
+        }
+        result.valueVariables.add(structVar);
+        return result.setValue(new PlcVarExpression(structVar));
+    }
+
+    /**
+     * If necessary, adapt the result value of {@code subExpr} such that it becomes compatible with {@code otherType}.
+     *
+     * @param expr Expression to make compatible with {@code otherType}.
+     * @param myType Type of the expression, must be either {@link IntType} or {@link RealType}.
+     * @param otherType Type to unify to, must be either {@link IntType} or {@link RealType}.
+     * @return An expression like {@code expr} with compatible type to {@code otherType}.
+     */
+    private PlcExpression unifyTypeOfExpr(PlcExpression expr, CifType myType, CifType otherType) {
+        if (myType instanceof IntType && otherType instanceof RealType) {
+            return funcAppls.castFunctionAppl(expr, target.getIntegerType(), target.getRealType());
+        }
+        return expr;
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/generators/CifProcessor.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/generators/CifProcessor.java
index 03dbae32c5f3eaeff35e4f5ab4d2be03e3bb523a..fb6a9ba64d51779280372e202c42ec51733435bc 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/generators/CifProcessor.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/generators/CifProcessor.java
@@ -14,11 +14,8 @@
 package org.eclipse.escet.cif.plcgen.generators;
 
 import static org.eclipse.escet.common.java.Lists.list;
-import static org.eclipse.escet.common.java.Maps.map;
 import static org.eclipse.escet.common.java.Strings.fmt;
 
-import java.util.Map;
-
 import org.eclipse.escet.cif.cif2cif.AddDefaultInitialValues;
 import org.eclipse.escet.cif.cif2cif.ElimComponentDefInst;
 import org.eclipse.escet.cif.cif2cif.ElimConsts;
@@ -28,15 +25,12 @@ import org.eclipse.escet.cif.cif2cif.EnumsToInts;
 import org.eclipse.escet.cif.cif2cif.RemoveIoDecls;
 import org.eclipse.escet.cif.cif2cif.SimplifyOthers;
 import org.eclipse.escet.cif.cif2cif.SimplifyValues;
-import org.eclipse.escet.cif.cif2plc.CifToPlcPreChecker;
-import org.eclipse.escet.cif.cif2plc.options.ConvertEnums;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcType;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcVariable;
 import org.eclipse.escet.cif.common.CifCollectUtils;
 import org.eclipse.escet.cif.common.checkers.CifPreconditionChecker;
 import org.eclipse.escet.cif.common.checkers.checks.AutOnlyWithOneInitLocCheck;
 import org.eclipse.escet.cif.common.checkers.checks.CompNoInitPredsCheck;
 import org.eclipse.escet.cif.common.checkers.checks.EdgeNoUrgentCheck;
+import org.eclipse.escet.cif.common.checkers.checks.EqnNotAllowedCheck;
 import org.eclipse.escet.cif.common.checkers.checks.ExprNoSpecificBinaryExprsCheck;
 import org.eclipse.escet.cif.common.checkers.checks.ExprNoSpecificBinaryExprsCheck.NoSpecificBinaryOp;
 import org.eclipse.escet.cif.common.checkers.checks.ExprNoSpecificExprsCheck;
@@ -64,9 +58,9 @@ import org.eclipse.escet.cif.metamodel.cif.declarations.Declaration;
 import org.eclipse.escet.cif.metamodel.cif.declarations.DiscVariable;
 import org.eclipse.escet.cif.metamodel.cif.declarations.EnumDecl;
 import org.eclipse.escet.cif.metamodel.cif.declarations.InputVariable;
-import org.eclipse.escet.cif.metamodel.cif.types.CifType;
 import org.eclipse.escet.cif.plcgen.PlcGenSettings;
 import org.eclipse.escet.cif.plcgen.WarnOutput;
+import org.eclipse.escet.cif.plcgen.options.ConvertEnums;
 import org.eclipse.escet.cif.plcgen.targets.PlcTarget;
 import org.eclipse.escet.common.app.framework.exceptions.InvalidInputException;
 
@@ -90,39 +84,19 @@ public class CifProcessor {
     /** Callback to send warnings to the user. */
     private final WarnOutput warnOutput;
 
-    /** Type generator. */
-    private final TypeGenerator typeGen;
-
-    /** PLC code storage and writer. */
-    private final PlcCodeStorage codeStorage;
-
-    /** Generator for obtaining clash-free names in the generated code. */
-    private final NameGenerator nameGenerator;
-
-    /** Names of converted declarations. */
-    private final Map<Declaration, String> variableNames = map();
-
     /**
      * Process the input CIF specification, reading it, and extracting the relevant information for PLC code generation.
      *
      * @param target PLC target to generate code for.
      * @param settings Configuration to use.
-     * @param typeGen Type generator.
-     * @param codeStorage PLC code storage and writer.
-     * @param nameGenerator Generator for obtaining clash-free names in the generated code.
      */
-    public CifProcessor(PlcTarget target, PlcGenSettings settings, TypeGenerator typeGen, PlcCodeStorage codeStorage,
-            NameGenerator nameGenerator)
-    {
+    public CifProcessor(PlcTarget target, PlcGenSettings settings) {
         this.target = target;
         inputPath = settings.inputPath;
         absInputPath = settings.absInputPath;
         simplifyValues = settings.simplifyValues;
         enumConversion = settings.enumConversion;
         warnOutput = settings.warnOutput;
-        this.typeGen = typeGen;
-        this.codeStorage = codeStorage;
-        this.nameGenerator = nameGenerator;
     }
 
     /** Process the input CIF specification, extracting the relevant information for PLC code generation. */
@@ -136,11 +110,11 @@ public class CifProcessor {
         // Convert the discrete and input variables as well as enumeration declarations throughout the specification.
         for (Declaration decl: CifCollectUtils.collectDeclarations(spec, list())) {
             if (decl instanceof DiscVariable discVar) {
-                convertVariable(decl, discVar.getType());
+                target.getVarStorage().addStateVariable(decl, discVar.getType());
             } else if (decl instanceof InputVariable inpVar) {
-                convertVariable(decl, inpVar.getType());
+                target.getVarStorage().addStateVariable(decl, inpVar.getType());
             } else if (decl instanceof EnumDecl enumDecl) {
-                typeGen.convertEnumDecl(enumDecl);
+                target.getTypeGenerator().convertEnumDecl(enumDecl);
             }
 
             // TODO Constants.
@@ -149,20 +123,6 @@ public class CifProcessor {
         }
     }
 
-    /**
-     * Convert a CIF variable and add it to the global variable table in the PLC.
-     *
-     * @param decl Discrete variable or input variable to convert.
-     * @param type Type of the variable.
-     */
-    private void convertVariable(Declaration decl, CifType type) {
-        PlcType varType = typeGen.convertType(type);
-        String varName = nameGenerator.generateName(decl);
-        variableNames.put(decl, varName);
-
-        codeStorage.addStateVariable(new PlcVariable(varName, varType));
-    }
-
     /**
      * Eliminate CIF features to widen the set of accepted specifications.
      *
@@ -211,7 +171,7 @@ public class CifProcessor {
     /** CIF PLC code generator precondition checker. Does not support component definition/instantiation. */
     private static class PlcGenPreChecker extends CifPreconditionChecker {
         /**
-         * Constructor of the {@link CifToPlcPreChecker} class.
+         * Constructor of the {@link PlcGenPreChecker} class.
          *
          * @param supportArrays Whether the target supports arrays.
          */
@@ -236,6 +196,10 @@ public class CifProcessor {
                             .disallow(NoInvariantSupKind.ALL_KINDS, NoInvariantKind.STATE,
                                     NoInvariantPlaceKind.ALL_PLACES),
 
+                    // Disallow equations.
+                    // TODO This may be too strict. Consider what equations should be allowed more closely.
+                    new EqnNotAllowedCheck(),
+
                     // No urgency.
                     new LocNoUrgentCheck(), //
                     new EdgeNoUrgentCheck(),
@@ -262,8 +226,8 @@ public class CifProcessor {
                             (supportArrays ? NoSpecificType.LIST_TYPES_NON_ARRAY : NoSpecificType.LIST_TYPES)),
 
                     // Allow only casting to the same type and int to real, allow projection only on tuples and arrays,
-                    // forbid string, set, and dictionary literals, forbid slicing, and function references outside call
-                    // context.
+                    // forbid string, set, and dictionary literals and time, forbid slicing, and function references
+                    // outside call context.
                     new ExprNoSpecificExprsCheck( //
                             NoSpecificExpr.CAST_EXPRS_FROM_STRING, //
                             NoSpecificExpr.CAST_EXPRS_TO_STRING, //
@@ -274,7 +238,8 @@ public class CifProcessor {
                             NoSpecificExpr.PROJECTION_EXPRS_STRINGS, //
                             NoSpecificExpr.SET_LITS, //
                             NoSpecificExpr.STRING_LITS, //
-                            NoSpecificExpr.SLICE_EXPRS),
+                            NoSpecificExpr.SLICE_EXPRS, //
+                            NoSpecificExpr.TIME_VAR_REFS),
 
                     // Disallow sampling.
                     new ExprNoSpecificUnaryExprsCheck(NoSpecificUnaryOp.SAMPLE),
@@ -347,7 +312,7 @@ public class CifProcessor {
         } else if (!target.supportsEnumerations()) {
             // Enumerations are not converted.
             String msg = fmt("Enumerations are not converted, while this is required for %s code. Please set the "
-                    + "\"Convert enumerations\" option accordingly.", target.targetType.dialogText);
+                    + "\"Convert enumerations\" option accordingly.", target.getTargetType().dialogText);
             throw new InvalidInputException(msg);
         }
     }
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/generators/DefaultNameGenerator.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/generators/DefaultNameGenerator.java
new file mode 100644
index 0000000000000000000000000000000000000000..c823d77e2c6a8f3fb348020d45978a88d09cdc60
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/generators/DefaultNameGenerator.java
@@ -0,0 +1,218 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.generators;
+
+import static org.eclipse.escet.common.java.Maps.map;
+import static org.eclipse.escet.common.java.Sets.setc;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.escet.cif.common.CifTextUtils;
+import org.eclipse.escet.cif.plcgen.PlcGenSettings;
+import org.eclipse.escet.cif.plcgen.WarnOutput;
+import org.eclipse.escet.common.java.Assert;
+import org.eclipse.escet.common.position.metamodel.position.PositionObject;
+
+/**
+ * Generator for obtaining clash-free names in the generated code.
+ *
+ * <p>
+ * The generator can generate globally unique names using {@link #generateGlobalName}. On top of globally unique names
+ * you can create local names that are both locally and globally unique in a scope using {@link #generateLocalName}.
+ * However, as local names are not taken into account for global names (it is assumed all global names occurring in the
+ * local scope are created before generating local names), safely creating new global names for use in the same local
+ * scope is not supported after creating the first local names in a scope.
+ * </p>
+ */
+public class DefaultNameGenerator implements NameGenerator {
+    /** Default single lower-case letter name to use if no prefix can be constructed. */
+    static final char DEFAULT_CHAR = 'x';
+
+    /**
+     * All names in the PLC language standard, as an unmodifiable set. These are to be avoided for generated names.
+     *
+     * <p>
+     * The keywords in the PLC language are case insensitive. This set only contains the names in lower-case ASCII.
+     * </p>
+     */
+    private static final Set<String> PLC_LANGUAGE_KEYWORDS;
+
+    /** If the value holds the user should be warned about changing the name, else the user should not be warned. */
+    private final boolean warnOnRename;
+
+    /** Callback to send warnings to the user. */
+    private final WarnOutput warnOutput;
+
+    /** Numeric suffix values already given out to a caller for globally unique names, ordered by the name prefix. */
+    private Map<String, Integer> globalSuffixes;
+
+    /**
+     * Constructor of the {@link DefaultNameGenerator} class.
+     *
+     * @param settings Configuration to use.
+     */
+    public DefaultNameGenerator(PlcGenSettings settings) {
+        warnOnRename = settings.warnOnRename;
+        warnOutput = settings.warnOutput;
+
+        globalSuffixes = map();
+        for (String name: PLC_LANGUAGE_KEYWORDS) {
+            globalSuffixes.put(name, 0);
+        }
+    }
+
+    @Override
+    public String generateGlobalName(PositionObject posObject) {
+        Assert.check(CifTextUtils.hasName(posObject), "Missing name for \"" + String.valueOf(posObject) + "\".");
+        return generateName(CifTextUtils.getAbsName(posObject, false), true, null);
+    }
+
+    @Override
+    public String generateGlobalName(String initialName, boolean initialIsCifName) {
+        return generateName(initialName, initialIsCifName, null);
+    }
+
+    @Override
+    public String generateLocalName(String initialName, Map<String, Integer> localSuffixes) {
+        return generateName(initialName, false, localSuffixes);
+    }
+
+    /**
+     * Convert the given name to a proper name that does not clash with the PLC language or with previously generated
+     * names.
+     *
+     * @param initialName Suggested name to to use.
+     * @param initialIsCifName Whether the initial name is known by the CIF user. Used to produce rename warnings. As
+     *     producing such rename warnings for objects that have no name in CIF is meaningless to the user, this
+     *     parameter should be {@code false} for those names.
+     * @param localSuffixes Name suffix information of local names. Use the same map to generate all local names in a
+     *     scope. Must be {@code null} when generating global names.
+     * @return A proper name that does not clash with PLC language keywords or previously generated global names. If a
+     *     {@code localSuffixes} map is supplied, the produced names also don't clash with all previously generated
+     *     local names that used that same map.
+     */
+    private String generateName(String initialName, boolean initialIsCifName, Map<String, Integer> localSuffixes) {
+        // Cleanup the name.
+        StringBuilder cleanedName = new StringBuilder(initialName.length() + 1 + 2 + 8);
+        boolean needsUnderscore = false;
+        for (int index = 0; index < initialName.length(); index++) {
+            char c = initialName.charAt(index);
+            if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
+                if (needsUnderscore) {
+                    cleanedName.append('_');
+                    needsUnderscore = false;
+                }
+                cleanedName.append(c);
+            } else if (c >= '0' && c <= '9') {
+                if (cleanedName.isEmpty()) {
+                    cleanedName.append(DEFAULT_CHAR);
+                } else if (needsUnderscore) {
+                    cleanedName.append('_');
+                }
+                cleanedName.append(c);
+                needsUnderscore = false;
+            } else {
+                needsUnderscore = !cleanedName.isEmpty();
+            }
+        }
+        if (cleanedName.isEmpty()) {
+            cleanedName.append(DEFAULT_CHAR);
+        }
+
+        // Make the name unique.
+        String lowerCleanedName = cleanedName.toString().toLowerCase(Locale.US);
+        int maxUsedNumber = globalSuffixes.getOrDefault(lowerCleanedName, -1);
+        if (localSuffixes != null) {
+            maxUsedNumber = Math.max(maxUsedNumber, localSuffixes.getOrDefault(lowerCleanedName, -1));
+        }
+
+        if (maxUsedNumber < 0) {
+            // First use of a name without numeric suffix -> use as-is.
+            //
+            // Store it as 0 suffix, next use will get "__1" appended.
+            if (localSuffixes != null) {
+                localSuffixes.put(lowerCleanedName, 0);
+            } else {
+                globalSuffixes.put(lowerCleanedName, 0);
+            }
+            return cleanedName.toString();
+        } else {
+            // Identifier already used, append a new suffix.
+            maxUsedNumber++;
+            if (localSuffixes != null) {
+                localSuffixes.put(lowerCleanedName, maxUsedNumber);
+            } else {
+                globalSuffixes.put(lowerCleanedName, maxUsedNumber);
+            }
+
+            cleanedName.append("__");
+            cleanedName.append(maxUsedNumber);
+            String newName = cleanedName.toString();
+            if (initialIsCifName && warnOnRename) {
+                warnOutput.warn("Renaming \"%s\" to \"%s\".", initialName, newName);
+            }
+            return newName;
+        }
+    }
+
+    static {
+        // Keywords of the language, note that "en" and "eno" special parameter names have been left out.
+        String[] languageKeywords = new String[] {"action", "end_action", "array", "of", "at", "case", "of", "else",
+                "end_case", "configuration", "end_configuration", "constant", "exit", "false", "f_edge", "for", "to",
+                "by", "do", "end_for", "function", "end_function", "function_block", "end_function_block", "if", "then",
+                "elsif", "else", "end_if", "initial_step", "end_step", "not", "mod", "and", "xor", "or", "program",
+                "with", "program", "end_program", "r_edge", "read_only", "read_write", "repeat", "until", "end_repeat",
+                "resource", "on", "end_resource", "retain", "end_retain", "return", "step", "end_step", "struct",
+                "end_struct", "task", "transition", "from", "to", "end_transition", "true", "type", "end_type", "var",
+                "end_var", "var_input", "var_output", "var_in_out", "var_temp", "var_external", "var_access",
+                "var_config", "var_gloval", "while", "do", "end_while", "with"};
+
+        String[] typeKeywords = new String[] {"bool", "sint", "int", "dint", "lint", "usint", "uint", "ulint", "udint",
+                "real", "lreal", "time", "date", "time_of_day", "tod", "date_and_time", "dt", "string", "byte", "word",
+                "dword", "lword", "wstring"};
+
+        String[] genericTypeKeywords = new String[] {"any", "and_derived", "any_elementary", "any_magnitude", "any_num",
+                "any_real", "any_int", "any_bit", "any_string", "any_date"};
+
+        // Construct a set container of appropriate size.
+        int numTypes = genericTypeKeywords.length;
+        int keywordCount = languageKeywords.length + typeKeywords.length + genericTypeKeywords.length
+                + numTypes * (numTypes - 1);
+        Set<String> keywords = setc(keywordCount);
+
+        // Add everything.
+        keywords.addAll(Arrays.asList(languageKeywords));
+        keywords.addAll(Arrays.asList(typeKeywords));
+        keywords.addAll(Arrays.asList(genericTypeKeywords));
+
+        // Casts (X_TO_Y functions).
+        for (int i = 0; i < typeKeywords.length; i++) {
+            for (int j = 0; j < typeKeywords.length; j++) {
+                if (i == j) {
+                    continue;
+                }
+                keywords.add(typeKeywords[i] + "_to_" + typeKeywords[j]);
+            }
+        }
+
+        // TODO: Add standard library function names.
+        // TODO: Add standard function block names.
+
+        PLC_LANGUAGE_KEYWORDS = Collections.unmodifiableSet(keywords);
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/generators/DefaultTypeGenerator.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/generators/DefaultTypeGenerator.java
new file mode 100644
index 0000000000000000000000000000000000000000..1ba26d3796790c80143bf1a7de199efd3f496b88
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/generators/DefaultTypeGenerator.java
@@ -0,0 +1,248 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.generators;
+
+import static org.eclipse.escet.common.java.Maps.map;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.eclipse.escet.cif.common.CifEnumUtils.EnumDeclEqHashWrap;
+import org.eclipse.escet.cif.common.CifTextUtils;
+import org.eclipse.escet.cif.common.CifTypeUtils;
+import org.eclipse.escet.cif.common.TypeEqHashWrap;
+import org.eclipse.escet.cif.metamodel.cif.declarations.EnumDecl;
+import org.eclipse.escet.cif.metamodel.cif.declarations.EnumLiteral;
+import org.eclipse.escet.cif.metamodel.cif.types.BoolType;
+import org.eclipse.escet.cif.metamodel.cif.types.CifType;
+import org.eclipse.escet.cif.metamodel.cif.types.EnumType;
+import org.eclipse.escet.cif.metamodel.cif.types.Field;
+import org.eclipse.escet.cif.metamodel.cif.types.IntType;
+import org.eclipse.escet.cif.metamodel.cif.types.ListType;
+import org.eclipse.escet.cif.metamodel.cif.types.RealType;
+import org.eclipse.escet.cif.metamodel.cif.types.TupleType;
+import org.eclipse.escet.cif.metamodel.cif.types.TypeRef;
+import org.eclipse.escet.cif.plcgen.PlcGenSettings;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcTypeDecl;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcVariable;
+import org.eclipse.escet.cif.plcgen.model.expressions.PlcEnumLiteral;
+import org.eclipse.escet.cif.plcgen.model.types.PlcArrayType;
+import org.eclipse.escet.cif.plcgen.model.types.PlcDerivedType;
+import org.eclipse.escet.cif.plcgen.model.types.PlcElementaryType;
+import org.eclipse.escet.cif.plcgen.model.types.PlcEnumType;
+import org.eclipse.escet.cif.plcgen.model.types.PlcStructType;
+import org.eclipse.escet.cif.plcgen.model.types.PlcType;
+import org.eclipse.escet.cif.plcgen.options.ConvertEnums;
+import org.eclipse.escet.cif.plcgen.targets.PlcTarget;
+import org.eclipse.escet.common.java.Assert;
+
+/** Class for handling types. */
+public class DefaultTypeGenerator implements TypeGenerator {
+    /** PLC target to generate code for. */
+    private final PlcTarget target;
+
+    /** Standard integer type. */
+    private final PlcElementaryType standardIntType;
+
+    /** Standard real type. */
+    private final PlcElementaryType standardRealType;
+
+    /** How to convert enumeration declarations to the PLC. */
+    private final ConvertEnums enumConversion;
+
+    /** Mapping from CIF tuple types wrapped in {@link TypeEqHashWrap} instances, to PLC type-declaration names. */
+    private final Map<TypeEqHashWrap, String> structNames = map();
+
+    /** Mapping from type declaration names to their underlying structure type. */
+    private final Map<String, PlcStructType> structTypes = map();
+
+    /**
+     * Mapping from CIF enumerations to PLC enumeration type and value information.
+     *
+     * <p>
+     * The map combines compatible enumerations (as defined by {@link CifTypeUtils#areEnumsCompatible}) to one
+     * information instance.
+     * </p>
+     */
+    private final Map<EnumDeclEqHashWrap, EnumDeclData> enumDeclNames = map();
+
+    /**
+     * Constructor of the {@link DefaultTypeGenerator} class.
+     *
+     * @param target PLC target.
+     * @param settings Configuration to use.
+     */
+    public DefaultTypeGenerator(PlcTarget target, PlcGenSettings settings) {
+        this.target = target;
+        standardIntType = target.getIntegerType();
+        standardRealType = target.getRealType();
+        enumConversion = settings.enumConversion;
+    }
+
+    @Override
+    public PlcType convertType(CifType type) {
+        if (type instanceof BoolType) {
+            return PlcElementaryType.BOOL_TYPE;
+        } else if (type instanceof IntType) {
+            return standardIntType;
+        } else if (type instanceof RealType) {
+            return standardRealType;
+        } else if (type instanceof TypeRef typeRef) {
+            return convertType(typeRef.getType().getType());
+        } else if (type instanceof TupleType tupleType) {
+            return convertTupleType(tupleType);
+        } else if (type instanceof EnumType enumType) {
+            return convertEnumDecl(enumType.getEnum());
+        } else if (type instanceof ListType arrayType) {
+            int size = arrayType.getLower();
+            Assert.check(CifTypeUtils.isArrayType(arrayType));
+            Assert.check(!(arrayType.getElementType() instanceof ListType)); // TODO Multi-dimensional or nested arrays.
+            PlcType elemType = convertType(arrayType.getElementType());
+            return new PlcArrayType(0, (size == 0) ? 0 : size - 1, elemType);
+        } else {
+            throw new RuntimeException("Unexpected type: " + type);
+        }
+    }
+
+    /**
+     * Converts a CIF tuple type to a PLC structure.
+     *
+     * @param tupleType The CIF tuple type.
+     * @return The PLC structure type generated for the tuple type.
+     */
+    private PlcType convertTupleType(TupleType tupleType) {
+        TypeEqHashWrap typeWrap = new TypeEqHashWrap(tupleType, true, false);
+        String sname = structNames.get(typeWrap);
+        if (sname == null) {
+            // Generate PLC struct for tuple.
+            // TODO Improve the relation from the PLC code back to the CIF specification by using supplied field names.
+            PlcStructType structType = new PlcStructType();
+            int fieldNumber = 1;
+            for (Field field: tupleType.getFields()) {
+                String fieldName = "field" + String.valueOf(fieldNumber);
+                PlcType ftype = convertType(field.getType());
+                structType.fields.add(new PlcVariable(fieldName, ftype));
+                fieldNumber++;
+            }
+
+            // Wrap a type declaration around the struct type, make it findable for future queries, and store the
+            // created PLC structure type.
+            sname = target.getNameGenerator().generateGlobalName("TupleStruct", false);
+            PlcTypeDecl typeDecl = new PlcTypeDecl(sname, structType);
+            structNames.put(typeWrap, sname);
+            structTypes.put(sname, structType);
+            target.getCodeStorage().addTypeDecl(typeDecl);
+        }
+        return new PlcDerivedType(sname);
+    }
+
+    @Override
+    public PlcStructType getStructureType(PlcType type) {
+        Assert.check(type instanceof PlcDerivedType);
+        PlcStructType structType = structTypes.get(((PlcDerivedType)type).name);
+        Assert.notNull(structType);
+        return structType;
+    }
+
+    @Override
+    public PlcType convertEnumDecl(EnumDecl enumDecl) {
+        return ensureEnumDecl(enumDecl).enumDeclType;
+    }
+
+    /**
+     * Ensure that the given CIF enumeration declaration is or becomes available as a named PLC enumeration.
+     *
+     * @param enumDecl Enumeration declaration to check.
+     * @return The PLC equivalent of the given CIF declaration.
+     */
+    private EnumDeclData ensureEnumDecl(EnumDecl enumDecl) {
+        EnumDeclEqHashWrap wrappedEnumDecl = new EnumDeclEqHashWrap(enumDecl);
+        EnumDeclData declData = enumDeclNames.get(wrappedEnumDecl);
+        if (declData == null) {
+            declData = makeEnumDeclData(enumDecl);
+            enumDeclNames.put(wrappedEnumDecl, declData);
+        }
+        return declData;
+    }
+
+    @Override
+    public PlcEnumLiteral getPlcEnumLiteral(EnumLiteral enumLit) {
+        EnumDecl enumDecl = (EnumDecl)enumLit.eContainer();
+        return ensureEnumDecl(enumDecl).getLiteral(enumLit);
+    }
+
+    /** Enumeration declaration type and value information storage. */
+    private static class EnumDeclData {
+        /** The enumeration data type in the PLC. */
+        public final PlcType enumDeclType;
+
+        /** Values of the converted enumeration literals. */
+        private final PlcEnumLiteral[] values;
+
+        /**
+         * Constructor of the {@link EnumDeclData} class.
+         *
+         * @param enumDeclType The enumeration data type in the PLC.
+         * @param values Values of the converted enumeration literals.
+         */
+        public EnumDeclData(PlcType enumDeclType, PlcEnumLiteral[] values) {
+            this.enumDeclType = enumDeclType;
+            this.values = values;
+        }
+
+        /**
+         * Get the equivalent value of the provided enumeration literal in the PLC.
+         *
+         * @param literal Enumeration literal to translate. Must be a literal of a compatible enumeration.
+         * @return The translated value.
+         */
+        public PlcEnumLiteral getLiteral(EnumLiteral literal) {
+            // Use the enumeration containing the literal itself for getting the index.
+            EnumDecl enumDecl = (EnumDecl)literal.eContainer();
+            return values[enumDecl.getLiterals().indexOf(literal)];
+        }
+    }
+
+    /**
+     * Create the equivalent enumeration type and values to use in the PLC for the given declaration.
+     *
+     * @param enumDecl Enumeration declaration to convert.
+     * @return The created equivalent PLC type and value information.
+     */
+    public EnumDeclData makeEnumDeclData(EnumDecl enumDecl) {
+        Assert.check(enumConversion.equals(ConvertEnums.NO)); // Other conversions have been eliminated already.
+
+        // Convert the enumeration literals.
+        List<EnumLiteral> cifLiterals = enumDecl.getLiterals();
+        PlcEnumLiteral[] literals = new PlcEnumLiteral[cifLiterals.size()];
+        int litIndex = 0;
+        for (EnumLiteral lit: cifLiterals) {
+            String litName = target.getNameGenerator().generateGlobalName(CifTextUtils.getAbsName(lit, false), true);
+            literals[litIndex] = new PlcEnumLiteral(litName);
+
+            litIndex++;
+        }
+
+        // Construct the type and add it to the global type declarations.
+        String declName = target.getNameGenerator().generateGlobalName(CifTextUtils.getAbsName(enumDecl, false), true);
+        PlcType declType = new PlcDerivedType(declName);
+        PlcEnumType plcEnumType = new PlcEnumType(
+                Arrays.stream(literals).map(v -> v.value).collect(Collectors.toList()));
+        target.getCodeStorage().addTypeDecl(new PlcTypeDecl(declName, plcEnumType));
+
+        return new EnumDeclData(declType, literals);
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/generators/DefaultVariableStorage.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/generators/DefaultVariableStorage.java
new file mode 100644
index 0000000000000000000000000000000000000000..10c8093f3b8380ffe36ce6ad757c01c981c9f044
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/generators/DefaultVariableStorage.java
@@ -0,0 +1,144 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.generators;
+
+import static org.eclipse.escet.common.java.Lists.first;
+import static org.eclipse.escet.common.java.Lists.list;
+import static org.eclipse.escet.common.java.Maps.map;
+
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.escet.cif.common.StateInitVarOrderer;
+import org.eclipse.escet.cif.metamodel.cif.automata.Location;
+import org.eclipse.escet.cif.metamodel.cif.declarations.Constant;
+import org.eclipse.escet.cif.metamodel.cif.declarations.ContVariable;
+import org.eclipse.escet.cif.metamodel.cif.declarations.Declaration;
+import org.eclipse.escet.cif.metamodel.cif.declarations.DiscVariable;
+import org.eclipse.escet.cif.metamodel.cif.declarations.InputVariable;
+import org.eclipse.escet.cif.metamodel.cif.types.CifType;
+import org.eclipse.escet.cif.plcgen.conversion.expressions.CifDataProvider;
+import org.eclipse.escet.cif.plcgen.conversion.expressions.ExprGenResult;
+import org.eclipse.escet.cif.plcgen.conversion.expressions.ExprGenerator;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcVariable;
+import org.eclipse.escet.cif.plcgen.model.expressions.PlcBoolLiteral;
+import org.eclipse.escet.cif.plcgen.model.expressions.PlcExpression;
+import org.eclipse.escet.cif.plcgen.model.expressions.PlcVarExpression;
+import org.eclipse.escet.cif.plcgen.model.statements.PlcAssignmentStatement;
+import org.eclipse.escet.cif.plcgen.model.statements.PlcCommentLine;
+import org.eclipse.escet.cif.plcgen.model.statements.PlcStatement;
+import org.eclipse.escet.cif.plcgen.model.types.PlcElementaryType;
+import org.eclipse.escet.cif.plcgen.model.types.PlcType;
+import org.eclipse.escet.cif.plcgen.targets.PlcTarget;
+import org.eclipse.escet.common.java.Assert;
+
+/** Class for handling storage and retrieval of globally used variables in the PLC program. */
+public class DefaultVariableStorage implements VariableStorage {
+    /** PLC target to generate code for. */
+    private final PlcTarget target;
+
+    /** Names of converted declarations. */
+    private final Map<Declaration, PlcVariable> variables = map();
+
+    /**
+     * Constructor of the {@link DefaultVariableStorage} class.
+     *
+     * @param target PLC target to generate code for.
+     */
+    public DefaultVariableStorage(PlcTarget target) {
+        this.target = target;
+    }
+
+    @Override
+    public void addStateVariable(Declaration decl, CifType type) {
+        PlcType varType = target.getTypeGenerator().convertType(type);
+        String varName = target.getNameGenerator().generateGlobalName(decl);
+        PlcVariable plcVar = new PlcVariable(varName, varType);
+        variables.put(decl, plcVar);
+        target.getCodeStorage().addStateVariable(plcVar);
+    }
+
+    @Override
+    public void process() {
+        // Construct a converter for CIF expressions.
+        ExprGenerator exprGen = target.getCodeStorage().getExprGenerator();
+
+        // Order the discrete variables on their dependencies for initialization.
+        // TODO Add continuous variables here as well.
+        // TODO Find out what to do with algebraic variables here (they are not state, this orderer will choke on them).
+        StateInitVarOrderer varOrderer = new StateInitVarOrderer();
+        for (Declaration decl: variables.keySet()) {
+            if (decl instanceof DiscVariable) {
+                varOrderer.addObject(decl);
+            }
+        }
+
+        // Generate initialization code and store it.
+        List<PlcStatement> statements = list();
+        // TODO Initialize the constants if not done in its declaration.
+        // TODO Initialize input variables by reading the sensors.
+        statements.add(new PlcCommentLine("Initialize the state variables."));
+        for (Declaration decl: varOrderer.computeOrder(true)) {
+            ExprGenResult exprResult;
+            if (decl instanceof DiscVariable discVar) {
+                exprResult = exprGen.convertExpr(first(discVar.getValue().getValues()));
+            } else {
+                throw new AssertionError("Unexpected kind of variable " + decl);
+            }
+            statements.addAll(exprResult.code);
+            exprGen.releaseTempVariables(exprResult.codeVariables);
+            PlcVarExpression lhs = new PlcVarExpression(variables.get(decl));
+            statements.add(new PlcAssignmentStatement(lhs, exprResult.value));
+            exprGen.releaseTempVariables(exprResult.valueVariables);
+        }
+        target.getCodeStorage().addStateInitialization(statements);
+    }
+
+    @Override
+    public CifDataProvider getRootCifDataProvider() {
+        return new CifDataProvider() {
+            @Override
+            public PlcExpression getExprForConstant(Constant constant) {
+                // TODO Return the proper PLC expression for the requested constant.
+                return new PlcVarExpression(new PlcVariable("someConstantvariable", PlcElementaryType.LREAL_TYPE));
+            }
+
+            @Override
+            public PlcExpression getExprForDiscVar(DiscVariable variable) {
+                PlcVariable plcDiscvar = variables.get(variable);
+                Assert.notNull(plcDiscvar);
+                return new PlcVarExpression(plcDiscvar);
+            }
+
+            @Override
+            public PlcExpression getExprForContvar(ContVariable variable, boolean getDerivative) {
+                // TODO Return the proper PLC expression for the requested continuous variable.
+                return new PlcVarExpression(new PlcVariable("someContvariable", PlcElementaryType.LREAL_TYPE));
+            }
+
+            @Override
+            public PlcExpression getExprForLocation(Location location) {
+                // TODO Return the proper PLC expression for the requested location.
+                return new PlcBoolLiteral(false);
+            }
+
+            @Override
+            public PlcExpression getExprForInputVar(InputVariable variable) {
+                PlcVariable plcInpvar = variables.get(variable);
+                Assert.notNull(plcInpvar);
+                return new PlcVarExpression(plcInpvar);
+            }
+        };
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/generators/NameGenerator.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/generators/NameGenerator.java
index d6b22b2dd5aaef6a9cc2e91858e9a42dd3a804b2..8d13e65f1a59ec4e42d6deee8ff59a5aff5eb9ef 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/generators/NameGenerator.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/generators/NameGenerator.java
@@ -1,5 +1,5 @@
 //////////////////////////////////////////////////////////////////////////////
-// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
 //
 // See the NOTICE file(s) distributed with this work for additional
 // information regarding copyright ownership.
@@ -13,172 +13,43 @@
 
 package org.eclipse.escet.cif.plcgen.generators;
 
-import static org.eclipse.escet.common.java.Maps.map;
-import static org.eclipse.escet.common.java.Sets.setc;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Locale;
 import java.util.Map;
-import java.util.Set;
 
-import org.eclipse.escet.cif.common.CifTextUtils;
-import org.eclipse.escet.cif.plcgen.PlcGenSettings;
-import org.eclipse.escet.cif.plcgen.WarnOutput;
-import org.eclipse.escet.common.java.Assert;
 import org.eclipse.escet.common.position.metamodel.position.PositionObject;
 
-/** Generator for obtaining clash-free names in the generated code. */
-public class NameGenerator {
-    /** Default single lower-case letter name to use if no prefix can be constructed. */
-    static final char DEFAULT_CHAR = 'x';
-
-    /**
-     * All names in the PLC language standard, as an unmodifiable set. These are to be avoided for generated names.
-     *
-     * <p>
-     * The keywords in the PLC language are case insensitive. This set only contains the names in lower-case ASCII.
-     * </p>
-     */
-    private static final Set<String> PLC_LANGUAGE_KEYWORDS;
-
-    /** If the value holds the user should be warned about changing the name, else the user should not be warned. */
-    private final boolean warnOnRename;
-
-    /** Callback to send warnings to the user. */
-    private final WarnOutput warnOutput;
-
-    /** Numeric suffix value already given out to a caller, ordered by the name prefix. */
-    private Map<String, Integer> maxSuffixes;
-
+/** Code generator interface for a {@link DefaultNameGenerator}. */
+public interface NameGenerator {
     /**
-     * Constructor of the {@link NameGenerator} class.
+     * Convert the given object to a proper name that does not clash with the PLC language or with previously generated
+     * global names. This function should not be used for generating names that also may contain local generated names.
      *
-     * @param settings Configuration to use.
+     * @param posObject Named CIF object.
+     * @return A proper name that does not clash with PLC language keywords or previously generated global names.
      */
-    public NameGenerator(PlcGenSettings settings) {
-        warnOnRename = settings.warnOnRename;
-        warnOutput = settings.warnOutput;
-
-        maxSuffixes = map();
-        for (String name: PLC_LANGUAGE_KEYWORDS) {
-            maxSuffixes.put(name, 0);
-        }
-    }
+    public abstract String generateGlobalName(PositionObject posObject);
 
     /**
-     * Convert the given object to something that does not clash with the PLC language or with previously generated
-     * names.
+     * Convert the given name to a proper name that does not clash with the PLC language or with previously generated
+     * global names. This function should not be used for generating names that also may contain local generated names.
      *
-     * @param posObject Named CIF object.
-     * @return A safe name that does not clash with either the PLC language keywords or names generated earlier.
+     * @param initialName Suggested name to to use.
+     * @param initialIsCifName Whether the initial name is known by the CIF user. Used to produce rename warnings. As
+     *     producing such rename warnings for elements that have no name in CIF is meaningless to a user, this parameter
+     *     should be {@code false} for those names.
+     * @return A proper name that does not clash with PLC language keywords or previously generated global names.
      */
-    public String generateName(PositionObject posObject) {
-        Assert.check(CifTextUtils.hasName(posObject), "Missing name for \"" + String.valueOf(posObject) + "\".");
-        return generateName(CifTextUtils.getAbsName(posObject, false), true);
-    }
+    public abstract String generateGlobalName(String initialName, boolean initialIsCifName);
 
     /**
-     * Convert the given name to something that does not clash with the PLC language or with previously generated names.
+     * Convert the given name to a proper name that does not clash with the PLC language, with previously generated
+     * global names or with previously generated local names that used the same {@code localSuffixes} information.
      *
      * @param initialName Suggested name to to use.
-     * @param initialIsCifName Whether the initial name is known by the CIF user. For objects that have no name in CIF,
-     *     producing rename warnings is meaningless.
-     * @return A safe name that does not clash with PLC language keywords or previously generated names.
+     * @param localSuffixes Name suffix information of local names. Use the same map to generate all local names in a
+     *     scope.
+     * @return A proper name that does not clash with PLC language keywords, previously generated global names or local
+     *     names created using this function with the same {@code localSuffixes} map.
+     * @note Local names are assumed not to be used for representing CIF variables.
      */
-    public String generateName(String initialName, boolean initialIsCifName) {
-        StringBuilder cleanedName = new StringBuilder(initialName.length() + 1 + 2 + 8);
-        boolean needsUnderscore = false;
-        for (int index = 0; index < initialName.length(); index++) {
-            char c = initialName.charAt(index);
-            if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
-                if (needsUnderscore) {
-                    cleanedName.append('_');
-                    needsUnderscore = false;
-                }
-                cleanedName.append(c);
-            } else if (c >= '0' && c <= '9') {
-                if (cleanedName.isEmpty()) {
-                    cleanedName.append(DEFAULT_CHAR);
-                } else if (needsUnderscore) {
-                    cleanedName.append('_');
-                }
-                cleanedName.append(c);
-                needsUnderscore = false;
-            } else {
-                needsUnderscore = !cleanedName.isEmpty();
-            }
-        }
-        if (cleanedName.isEmpty()) {
-            cleanedName.append(DEFAULT_CHAR);
-        }
-
-        String lowerCleanedName = cleanedName.toString().toLowerCase(Locale.US);
-        int maxUsedNumber = maxSuffixes.getOrDefault(lowerCleanedName, -1);
-        if (maxUsedNumber < 0) {
-            // First use of a name without numeric suffix -> use as-is.
-            //
-            // Store it as 0 suffix, next use will get "__1" appended.
-            maxSuffixes.put(lowerCleanedName, 0);
-            return cleanedName.toString();
-        } else {
-            // Identifier already used, append a new suffix.
-            maxUsedNumber++;
-            maxSuffixes.put(lowerCleanedName, maxUsedNumber);
-
-            cleanedName.append("__");
-            cleanedName.append(maxUsedNumber);
-            String newName = cleanedName.toString();
-            if (initialIsCifName && warnOnRename) {
-                warnOutput.warn("Renaming \"%s\" to \"%s\".", initialName, newName);
-            }
-            return newName;
-        }
-    }
-
-    static {
-        // Keywords of the language, note that "en" and "eno" special parameter names have been left out.
-        String[] languageKeywords = new String[] {"action", "end_action", "array", "of", "at", "case", "of", "else",
-                "end_case", "configuration", "end_configuration", "constant", "exit", "false", "f_edge", "for", "to",
-                "by", "do", "end_for", "function", "end_function", "function_block", "end_function_block", "if", "then",
-                "elsif", "else", "end_if", "initial_step", "end_step", "not", "mod", "and", "xor", "or", "program",
-                "with", "program", "end_program", "r_edge", "read_only", "read_write", "repeat", "until", "end_repeat",
-                "resource", "on", "end_resource", "retain", "end_retain", "return", "step", "end_step", "struct",
-                "end_struct", "task", "transition", "from", "to", "end_transition", "true", "type", "end_type", "var",
-                "end_var", "var_input", "var_output", "var_in_out", "var_temp", "var_external", "var_access",
-                "var_config", "var_gloval", "while", "do", "end_while", "with"};
-
-        String[] typeKeywords = new String[] {"bool", "sint", "int", "dint", "lint", "usint", "uint", "ulint", "udint",
-                "real", "lreal", "time", "date", "time_of_day", "tod", "date_and_time", "dt", "string", "byte", "word",
-                "dword", "lword", "wstring"};
-
-        String[] genericTypeKeywords = new String[] {"any", "and_derived", "any_elementary", "any_magnitude", "any_num",
-                "any_real", "any_int", "any_bit", "any_string", "any_date"};
-
-        // Construct a set container of appropriate size.
-        int numTypes = genericTypeKeywords.length;
-        int keywordCount = languageKeywords.length + typeKeywords.length + genericTypeKeywords.length
-                + numTypes * (numTypes - 1);
-        Set<String> keywords = setc(keywordCount);
-
-        // Add everything.
-        keywords.addAll(Arrays.asList(languageKeywords));
-        keywords.addAll(Arrays.asList(typeKeywords));
-        keywords.addAll(Arrays.asList(genericTypeKeywords));
-
-        // Casts (X_TO_Y functions).
-        for (int i = 0; i < typeKeywords.length; i++) {
-            for (int j = 0; j < typeKeywords.length; j++) {
-                if (i == j) {
-                    continue;
-                }
-                keywords.add(typeKeywords[i] + "_to_" + typeKeywords[j]);
-            }
-        }
-
-        // TODO: Add standard library function names.
-        // TODO: Add standard function block names.
-
-        PLC_LANGUAGE_KEYWORDS = Collections.unmodifiableSet(keywords);
-    }
+    public abstract String generateLocalName(String initialName, Map<String, Integer> localSuffixes);
 }
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/generators/PlcCodeStorage.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/generators/PlcCodeStorage.java
index e7ee7fcad193f74fd6c703b24093c6df7ecb7dd1..f04b240cee81659c38f96868cbe08ee22d226221 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/generators/PlcCodeStorage.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/generators/PlcCodeStorage.java
@@ -13,24 +13,30 @@
 
 package org.eclipse.escet.cif.plcgen.generators;
 
-import static org.eclipse.escet.cif.cif2plc.plcdata.PlcElementaryType.INT_TYPE;
-
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcConfiguration;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcDerivedType;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcGlobalVarList;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcPou;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcPouInstance;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcPouType;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcProject;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcResource;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcTask;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcType;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcTypeDecl;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcValue;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcVariable;
-import org.eclipse.escet.cif.cif2plc.writers.OutputTypeWriter;
+import static org.eclipse.escet.cif.plcgen.model.types.PlcElementaryType.INT_TYPE;
+
+import java.util.List;
+
 import org.eclipse.escet.cif.plcgen.PlcGenSettings;
+import org.eclipse.escet.cif.plcgen.conversion.expressions.ExprGenerator;
+import org.eclipse.escet.cif.plcgen.model.PlcModelUtils;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcConfiguration;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcGlobalVarList;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcPou;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcPouInstance;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcPouType;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcProject;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcResource;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcTask;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcTypeDecl;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcVariable;
+import org.eclipse.escet.cif.plcgen.model.expressions.PlcValue;
+import org.eclipse.escet.cif.plcgen.model.statements.PlcStatement;
+import org.eclipse.escet.cif.plcgen.model.types.PlcDerivedType;
+import org.eclipse.escet.cif.plcgen.model.types.PlcElementaryType;
+import org.eclipse.escet.cif.plcgen.model.types.PlcType;
 import org.eclipse.escet.cif.plcgen.targets.PlcTarget;
+import org.eclipse.escet.common.box.CodeBox;
 import org.eclipse.escet.common.java.Assert;
 
 /** Class that stores and writes generated PLC code. */
@@ -38,9 +44,6 @@ public class PlcCodeStorage {
     /** PLC target to generate code for. */
     private final PlcTarget target;
 
-    /** Absolute base path to which to write the generated code. */
-    private final String outputPath;
-
     /** Project with PLC code. */
     private final PlcProject project;
 
@@ -62,6 +65,12 @@ public class PlcCodeStorage {
     /** Global variable list for state variables, lazily created. */
     private PlcGlobalVarList globalStateVars = null;
 
+    /** The expression generator to use for generating code in the main program. Initialized lazily. */
+    private ExprGenerator exprGenerator = null;
+
+    /** If not {@code null}, code for initializing the state variables. */
+    private List<PlcStatement> stateInitializationCode = null;
+
     /**
      * Constructor of the {@link PlcCodeStorage} class.
      *
@@ -70,7 +79,6 @@ public class PlcCodeStorage {
      */
     public PlcCodeStorage(PlcTarget target, PlcGenSettings settings) {
         this.target = target;
-        this.outputPath = settings.outputPath;
 
         // Create project, configuration, resource, and task.
         project = new PlcProject(settings.projectName);
@@ -84,6 +92,18 @@ public class PlcCodeStorage {
         resource.tasks.add(task);
     }
 
+    /**
+     * Get the expression generator to use for generating code in the main program.
+     *
+     * @return The expression generator to use for generating code in the main program.
+     */
+    public ExprGenerator getExprGenerator() {
+        if (exprGenerator == null) {
+            exprGenerator = new ExprGenerator(target, target.getVarStorage().getRootCifDataProvider());
+        }
+        return exprGenerator;
+    }
+
     /**
      * Add a variable to the global constants table.
      *
@@ -143,6 +163,18 @@ public class PlcCodeStorage {
         project.typeDecls.add(decl);
     }
 
+    /**
+     * Add code to initialize the state of the globally used variables.
+     *
+     * @param stateInitializationCode Code for initializing the globally used variables.
+     */
+    public void addStateInitialization(List<PlcStatement> stateInitializationCode) {
+        Assert.check(this.stateInitializationCode == null);
+        if (PlcModelUtils.isNonEmptyCode(stateInitializationCode)) {
+            this.stateInitializationCode = stateInitializationCode;
+        }
+    }
+
     /** Perform any additional processing to make the generated PLC program ready. */
     public void finishPlcProgram() {
         // Add all created variable tables.
@@ -155,15 +187,32 @@ public class PlcCodeStorage {
         PlcPou main = new PlcPou("MAIN", PlcPouType.PROGRAM, null);
         project.pous.add(main);
 
-        // Global variable list of the main program. Note that the cif2plc Siemens target requires the "TIMERS" name.
+        // Global variable list of the main program. Note that the Siemens target currently requires the "TIMERS" name.
         PlcGlobalVarList mainVariables = new PlcGlobalVarList("TIMERS", false);
         addGlobalVariableTable(mainVariables);
 
+        ExprGenerator exprGen = getExprGenerator();
+        if (stateInitializationCode != null) {
+            // Insert code to create the initial state.
+            PlcVariable firstFlag = exprGen.makeLocalVariable("firstRun", PlcElementaryType.BOOL_TYPE, null,
+                    new PlcValue("TRUE"));
+            mainVariables.variables.add(firstFlag);
+
+            CodeBox box = main.body;
+            box.add("IF %s THEN", firstFlag.name);
+            box.indent();
+            box.add("%s := FALSE;", firstFlag.name);
+            box.add();
+            target.getModelTextGenerator().toText(stateInitializationCode, box, main.name, false);
+            box.dedent();
+            box.add("END_IF;");
+        }
+
         // Add main program variables.
         PlcType tonType = new PlcDerivedType("TON");
-        mainVariables.variables.add(new PlcVariable("timer0", tonType));
-        mainVariables.variables.add(new PlcVariable("timer1", tonType));
-        mainVariables.variables.add(new PlcVariable("curTimer", INT_TYPE, null, new PlcValue("0")));
+        mainVariables.variables.add(exprGen.makeLocalVariable("timer0", tonType));
+        mainVariables.variables.add(exprGen.makeLocalVariable("timer1", tonType));
+        mainVariables.variables.add(exprGen.makeLocalVariable("curTimer", INT_TYPE, null, new PlcValue("0")));
 
         // Add program to task.
         task.pouInstances.add(new PlcPouInstance("MAIN", main));
@@ -186,7 +235,6 @@ public class PlcCodeStorage {
      * @note Depending on the actual write implementation a single file or a directory may be written.
      */
     public void writeOutput() {
-        OutputTypeWriter writer = target.getPlcCodeWriter();
-        writer.write(project, outputPath);
+        target.writeOutput(project);
     }
 }
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/generators/TypeGenerator.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/generators/TypeGenerator.java
index 597a0304244f005be1ad3739f72a3f49fefcb6f9..fc6444478e8dff18cf56788607174c6a8806859e 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/generators/TypeGenerator.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/generators/TypeGenerator.java
@@ -1,5 +1,5 @@
 //////////////////////////////////////////////////////////////////////////////
-// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
 //
 // See the NOTICE file(s) distributed with this work for additional
 // information regarding copyright ownership.
@@ -13,149 +13,30 @@
 
 package org.eclipse.escet.cif.plcgen.generators;
 
-import static org.eclipse.escet.common.java.Maps.map;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-import org.eclipse.escet.cif.cif2plc.options.ConvertEnums;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcArrayType;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcDerivedType;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcElementaryType;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcEnumType;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcStructType;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcType;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcTypeDecl;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcValue;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcVariable;
-import org.eclipse.escet.cif.common.CifEnumUtils.EnumDeclEqHashWrap;
-import org.eclipse.escet.cif.common.CifTextUtils;
-import org.eclipse.escet.cif.common.CifTypeUtils;
-import org.eclipse.escet.cif.common.TypeEqHashWrap;
 import org.eclipse.escet.cif.metamodel.cif.declarations.EnumDecl;
 import org.eclipse.escet.cif.metamodel.cif.declarations.EnumLiteral;
-import org.eclipse.escet.cif.metamodel.cif.types.BoolType;
 import org.eclipse.escet.cif.metamodel.cif.types.CifType;
-import org.eclipse.escet.cif.metamodel.cif.types.EnumType;
-import org.eclipse.escet.cif.metamodel.cif.types.Field;
-import org.eclipse.escet.cif.metamodel.cif.types.IntType;
-import org.eclipse.escet.cif.metamodel.cif.types.ListType;
-import org.eclipse.escet.cif.metamodel.cif.types.RealType;
-import org.eclipse.escet.cif.metamodel.cif.types.TupleType;
-import org.eclipse.escet.cif.metamodel.cif.types.TypeRef;
-import org.eclipse.escet.cif.plcgen.PlcGenSettings;
-import org.eclipse.escet.cif.plcgen.targets.PlcTarget;
-import org.eclipse.escet.common.java.Assert;
-
-/** Class for handling types. */
-public class TypeGenerator {
-    /** Standard integer type. */
-    private final PlcElementaryType standardIntType;
-
-    /** Standard real type. */
-    private final PlcElementaryType standardRealType;
-
-    /** How to convert enumeration declarations to the PLC. */
-    private final ConvertEnums enumConversion;
-
-    /** Generator for obtaining clash-free names in the generated code. */
-    private final NameGenerator nameGenerator;
-
-    /** Generator that stores and writes generated PLC code. */
-    private final PlcCodeStorage plcCodeStorage;
-
-    /** Mapping from CIF tuple types wrapped in {@link TypeEqHashWrap} instances, to PLC names. */
-    private final Map<TypeEqHashWrap, String> structNames = map();
-
-    /**
-     * Mapping from CIF enumerations to PLC enumeration type and value information.
-     *
-     * <p>
-     * The map combines compatible enumerations (as defined by {@link CifTypeUtils#areEnumsCompatible}) to one
-     * information instance.
-     * </p>
-     */
-    private final Map<EnumDeclEqHashWrap, EnumDeclData> enumDeclNames = map();
-
-    /**
-     * Constructor of the {@link TypeGenerator} class.
-     *
-     * @param target PLC target.
-     * @param settings Configuration to use.
-     * @param nameGenerator Generator for obtaining clash-free names in the generated code.
-     * @param plcCodeStorage Generator that stores and writes generated PLC code.
-     */
-    public TypeGenerator(PlcTarget target, PlcGenSettings settings, NameGenerator nameGenerator,
-            PlcCodeStorage plcCodeStorage)
-    {
-        standardIntType = target.getIntegerType();
-        standardRealType = target.getRealType();
-        enumConversion = settings.enumConversion;
-
-        this.nameGenerator = nameGenerator;
-        this.plcCodeStorage = plcCodeStorage;
-    }
+import org.eclipse.escet.cif.plcgen.model.expressions.PlcEnumLiteral;
+import org.eclipse.escet.cif.plcgen.model.types.PlcStructType;
+import org.eclipse.escet.cif.plcgen.model.types.PlcType;
 
+/** Code generation interface for a {@link DefaultTypeGenerator}. */
+public interface TypeGenerator {
     /**
      * Convert a CIF type to a PLC type.
      *
      * @param type CIF type to convert.
      * @return The associated PLC type.
      */
-    public PlcType convertType(CifType type) {
-        if (type instanceof BoolType) {
-            return PlcElementaryType.BOOL_TYPE;
-        } else if (type instanceof IntType) {
-            return standardIntType;
-        } else if (type instanceof RealType) {
-            return standardRealType;
-        } else if (type instanceof TypeRef typeRef) {
-            return convertType(typeRef.getType().getType());
-        } else if (type instanceof TupleType tupleType) {
-            return convertTupleType(tupleType);
-        } else if (type instanceof EnumType enumType) {
-            return convertEnumDecl(enumType.getEnum());
-        } else if (type instanceof ListType arrayType) {
-            int size = arrayType.getLower();
-            Assert.check(CifTypeUtils.isArrayType(arrayType));
-            Assert.check(!(arrayType.getElementType() instanceof ListType)); // TODO Multi-dimensional or nested arrays.
-            PlcType elemType = convertType(arrayType.getElementType());
-            return new PlcArrayType(0, (size == 0) ? 0 : size - 1, elemType);
-        } else {
-            throw new RuntimeException("Unexpected type: " + type);
-        }
-    }
+    public PlcType convertType(CifType type);
 
     /**
-     * Converts a CIF tuple type to a PLC structure.
+     * Get the underlying structure type from the associated declaration type used in the generators.
      *
-     * @param tupleType The CIF tuple type.
-     * @return The PLC structure type generated for the tuple type.
+     * @param type Declaration type of the structure type being queried.
+     * @return The underlying structure type.
      */
-    private PlcType convertTupleType(TupleType tupleType) {
-        TypeEqHashWrap typeWrap = new TypeEqHashWrap(tupleType, true, false);
-        String sname = structNames.get(typeWrap);
-        if (sname == null) {
-            // Generate PLC struct for tuple.
-            sname = nameGenerator.generateName("TupleStruct", false);
-            structNames.put(typeWrap, sname);
-
-            PlcStructType structType = new PlcStructType();
-            int fieldNumber = 1;
-            for (Field field: tupleType.getFields()) {
-                String fieldName = "field" + String.valueOf(fieldNumber);
-                PlcType ftype = convertType(field.getType());
-                structType.fields.add(new PlcVariable(fieldName, ftype));
-                fieldNumber++;
-            }
-
-            PlcTypeDecl typeDecl = new PlcTypeDecl(sname, structType);
-            plcCodeStorage.addTypeDecl(typeDecl);
-        }
-        return new PlcDerivedType(sname);
-    }
+    public PlcStructType getStructureType(PlcType type);
 
     /**
      * Convert a CIF enumeration declaration to a named PLC enumeration.
@@ -163,76 +44,13 @@ public class TypeGenerator {
      * @param enumDecl Enumeration declaration to convert.
      * @return The PLC type generated for the enumeration.
      */
-    public PlcType convertEnumDecl(EnumDecl enumDecl) {
-        EnumDeclEqHashWrap wrappedEnumDecl = new EnumDeclEqHashWrap(enumDecl);
-        EnumDeclData declData = enumDeclNames.get(wrappedEnumDecl);
-        if (declData == null) {
-            declData = makeEnumDeclData(enumDecl);
-            enumDeclNames.put(wrappedEnumDecl, declData);
-        }
-        return declData.enumDeclType;
-    }
-
-    /** Enumeration declaration type and value information storage. */
-    private static class EnumDeclData {
-        /** The enumeration data type in the PLC. */
-        public final PlcType enumDeclType;
-
-        /** Values of the converted enumeration literals. */
-        private final PlcValue[] values;
-
-        /**
-         * Constructor of the {@link EnumDeclData} class.
-         *
-         * @param enumDeclType The enumeration data type in the PLC.
-         * @param values Values of the converted enumeration literals.
-         */
-        public EnumDeclData(PlcType enumDeclType, PlcValue[] values) {
-            this.enumDeclType = enumDeclType;
-            this.values = values;
-        }
-
-        /**
-         * Get the equivalent value of the provided enumeration literal in the PLC.
-         *
-         * @param literal Enumeration literal to translate. Must be a literal of a compatible enumeration.
-         * @return The translated value.
-         */
-        @SuppressWarnings("unused") // TODO Use the function in expression conversions.
-        public PlcValue getLiteral(EnumLiteral literal) {
-            // Use the enumeration containing the literal itself for getting the index.
-            EnumDecl enumDecl = (EnumDecl)literal.eContainer();
-            return values[enumDecl.getLiterals().indexOf(literal)];
-        }
-    }
+    public PlcType convertEnumDecl(EnumDecl enumDecl);
 
     /**
-     * Create the equivalent enumeration type and values to use in the PLC for the given declaration.
+     * Get the PLC equivalent of the given CIF enumeration literal.
      *
-     * @param enumDecl Enumeration declaration to convert.
-     * @return The created equivalent PLC type and value information.
+     * @param enumLit Enumeration to convert.
+     * @return The equivalent PLC value of the provided enum literal.
      */
-    public EnumDeclData makeEnumDeclData(EnumDecl enumDecl) {
-        Assert.check(enumConversion.equals(ConvertEnums.NO)); // Other conversions have been eliminated already.
-
-        // Convert the enumeration literals.
-        List<EnumLiteral> cifLiterals = enumDecl.getLiterals();
-        PlcValue[] literals = new PlcValue[cifLiterals.size()];
-        int litIndex = 0;
-        for (EnumLiteral lit: cifLiterals) {
-            String litName = nameGenerator.generateName(CifTextUtils.getAbsName(lit, false), true);
-            literals[litIndex] = new PlcValue(litName);
-
-            litIndex++;
-        }
-
-        // Construct the type and add it to the global type declarations.
-        String declName = nameGenerator.generateName(CifTextUtils.getAbsName(enumDecl, false), true);
-        PlcType declType = new PlcDerivedType(declName);
-        PlcEnumType plcEnumType = new PlcEnumType(
-                Arrays.stream(literals).map(v -> v.value).collect(Collectors.toList()));
-        plcCodeStorage.addTypeDecl(new PlcTypeDecl(declName, plcEnumType));
-
-        return new EnumDeclData(declType, literals);
-    }
+    public PlcEnumLiteral getPlcEnumLiteral(EnumLiteral enumLit);
 }
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/generators/VariableStorage.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/generators/VariableStorage.java
new file mode 100644
index 0000000000000000000000000000000000000000..b1ad1d0b92acaf7ffc4a8e43817cb7bc123cbc39
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/generators/VariableStorage.java
@@ -0,0 +1,41 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.generators;
+
+import org.eclipse.escet.cif.metamodel.cif.declarations.Declaration;
+import org.eclipse.escet.cif.metamodel.cif.declarations.DiscVariable;
+import org.eclipse.escet.cif.metamodel.cif.declarations.InputVariable;
+import org.eclipse.escet.cif.metamodel.cif.types.CifType;
+import org.eclipse.escet.cif.plcgen.conversion.expressions.CifDataProvider;
+
+/** Interface for storing and retrieving globally used variables in the PLC program. */
+public interface VariableStorage {
+    /**
+     * Add a state variable to the storage.
+     *
+     * @param variable Variable to add, should be a {@link DiscVariable} or {@link InputVariable}.
+     * @param type CIF type of the variable.
+     */
+    void addStateVariable(Declaration variable, CifType type);
+
+    /** Make the variables ready for use in the PLC code. */
+    void process();
+
+    /**
+     * Provide access to PLC equivalents of the globally used CIF state for expression generation.
+     *
+     * @return Access to PLC equivalents of the globally used CIF state for expression generation.
+     */
+    public CifDataProvider getRootCifDataProvider();
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/PlcModelUtils.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/PlcModelUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..2b1d1e3a7f9f48a4a77275b9e19ee5ede20582c5
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/PlcModelUtils.java
@@ -0,0 +1,43 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.model;
+
+import java.util.List;
+
+import org.eclipse.escet.cif.plcgen.model.statements.PlcCommentLine;
+import org.eclipse.escet.cif.plcgen.model.statements.PlcStatement;
+
+/** Utility functions for model classes. */
+public class PlcModelUtils {
+    /** Constructor of the static {@link PlcModelUtils} class. */
+    private PlcModelUtils() {
+        // Static class.
+    }
+
+    /**
+     * Does executing the given statements (likely) have an effect?
+     *
+     * @param statements Statements to analyze.
+     * @return Whether the statement are (likely) having an effect.
+     * @note The function assumes all statements except the {@link PlcCommentLine} have an effect.
+     */
+    public static boolean isNonEmptyCode(List<PlcStatement> statements) {
+        for (PlcStatement plcStat: statements) {
+            if (!(plcStat instanceof PlcCommentLine)) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/declarations/PlcConfiguration.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/declarations/PlcConfiguration.java
new file mode 100644
index 0000000000000000000000000000000000000000..8e82a90fbbb6871d5c95b1c90160dd1f2502b36f
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/declarations/PlcConfiguration.java
@@ -0,0 +1,39 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.model.declarations;
+
+import static org.eclipse.escet.common.java.Lists.list;
+
+import java.util.List;
+
+/** PLC configuration. */
+public class PlcConfiguration {
+    /** The name of the configuration. */
+    public final String name;
+
+    /** The global variable lists of the configuration. */
+    public List<PlcGlobalVarList> globalVarLists = list();
+
+    /** The resources of the configuration. */
+    public List<PlcResource> resources = list();
+
+    /**
+     * Constructor for the {@link PlcConfiguration} class.
+     *
+     * @param name The name of the configuration.
+     */
+    public PlcConfiguration(String name) {
+        this.name = name;
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/declarations/PlcGlobalVarList.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/declarations/PlcGlobalVarList.java
new file mode 100644
index 0000000000000000000000000000000000000000..23fca1b5056a3c3329e780ff51cdc6b3aa4a1fa7
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/declarations/PlcGlobalVarList.java
@@ -0,0 +1,41 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.model.declarations;
+
+import static org.eclipse.escet.common.java.Lists.list;
+
+import java.util.List;
+
+/** PLC global variable list. */
+public class PlcGlobalVarList {
+    /** The name of the global variable list. */
+    public final String name;
+
+    /** Whether the variable list contains constants ({@code true}) or variables ({@code false}). */
+    public final boolean constants;
+
+    /** The variables of the global variable list. */
+    public List<PlcVariable> variables = list();
+
+    /**
+     * Constructor for the {@link PlcGlobalVarList} class.
+     *
+     * @param name The name of the global variable list.
+     * @param constants Whether the variable list contains constants ({@code true}) or variables ({@code false}).
+     */
+    public PlcGlobalVarList(String name, boolean constants) {
+        this.name = name;
+        this.constants = constants;
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/declarations/PlcPou.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/declarations/PlcPou.java
new file mode 100644
index 0000000000000000000000000000000000000000..4e62e16f8db1963c1def2bd190d5e4895a4b42bd
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/declarations/PlcPou.java
@@ -0,0 +1,63 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.model.declarations;
+
+import static org.eclipse.escet.cif.plcgen.model.declarations.PlcProject.INDENT;
+import static org.eclipse.escet.common.java.Lists.list;
+
+import java.util.List;
+
+import org.eclipse.escet.cif.plcgen.model.types.PlcType;
+import org.eclipse.escet.common.box.CodeBox;
+import org.eclipse.escet.common.box.MemoryCodeBox;
+
+/** PLC Program Organization Unit (POU). */
+public class PlcPou {
+    /** The name of the POU. */
+    public final String name;
+
+    /** The type of the POU. */
+    public final PlcPouType pouType;
+
+    /** The return type for function, {@code null} for programs. */
+    public final PlcType retType;
+
+    /** The input variables of the POU. */
+    public List<PlcVariable> inputVars = list();
+
+    /** The output variables of the POU. */
+    public List<PlcVariable> outputVars = list();
+
+    /** The local persistent variables of the POU. */
+    public List<PlcVariable> localVars = list();
+
+    /** The local temporary (non-persistent) variables of the POU. */
+    public List<PlcVariable> tempVars = list();
+
+    /** Body of the POU in IEC 61131-3 Structured Text syntax. */
+    public CodeBox body = new MemoryCodeBox(INDENT);
+
+    /**
+     * Constructor for the {@link PlcPou} class.
+     *
+     * @param name The name of the POU.
+     * @param pouType The type of the POU.
+     * @param retType The return type for function, {@code null} for programs.
+     */
+    public PlcPou(String name, PlcPouType pouType, PlcType retType) {
+        this.name = name;
+        this.pouType = pouType;
+        this.retType = retType;
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/declarations/PlcPouInstance.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/declarations/PlcPouInstance.java
new file mode 100644
index 0000000000000000000000000000000000000000..a7a6adf052e9df776f0b3588209f2dd8eac261c7
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/declarations/PlcPouInstance.java
@@ -0,0 +1,34 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.model.declarations;
+
+/** PLC POU instance. */
+public class PlcPouInstance {
+    /** The name of the POU instance. */
+    public final String name;
+
+    /** The POU being instantiated. */
+    public final PlcPou pou;
+
+    /**
+     * Constructor for the {@link PlcPouInstance} class.
+     *
+     * @param name The name of the POU instance.
+     * @param pou The POU being instantiated.
+     */
+    public PlcPouInstance(String name, PlcPou pou) {
+        this.name = name;
+        this.pou = pou;
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_aut_missing_loc.cif b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/declarations/PlcPouType.java
similarity index 65%
rename from cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_aut_missing_loc.cif
rename to cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/declarations/PlcPouType.java
index 20748947b86231c58be03d3db1ada0c64a14b315..6ac29a9b9340a9b8e0ceeb01e08f1e12c4bfe935 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_aut_missing_loc.cif
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/declarations/PlcPouType.java
@@ -11,19 +11,13 @@
 // SPDX-License-Identifier: MIT
 //////////////////////////////////////////////////////////////////////////////
 
-automaton a:
-  const int c1 = switch self:
-                   case l2: 1
-                 end;
-  const int c2 = switch a:
-                   case l1: 1
-                   case l3: 2
-                 end;
+package org.eclipse.escet.cif.plcgen.model.declarations;
 
-  location l1:
-    initial;
-  location l2:
-    initial;
-  location l3:
-    initial;
-end
+/** PLC Program Organization Unit (POU) type. */
+public enum PlcPouType {
+    /** Program. */
+    PROGRAM,
+
+    /** Function. */
+    FUNCTION;
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/declarations/PlcProject.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/declarations/PlcProject.java
new file mode 100644
index 0000000000000000000000000000000000000000..7c0d055e826d48149a6a921f7f0f652304eb0edd
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/declarations/PlcProject.java
@@ -0,0 +1,45 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.model.declarations;
+
+import static org.eclipse.escet.common.java.Lists.list;
+
+import java.util.List;
+
+/** PLC project. */
+public class PlcProject {
+    /** The indentation to use for the Structured Text files. */
+    public static final int INDENT = 4;
+
+    /** The name of the PLC project. */
+    public final String name;
+
+    /** The type declarations of the project. */
+    public List<PlcTypeDecl> typeDecls = list();
+
+    /** The POUs of the project. */
+    public List<PlcPou> pous = list();
+
+    /** The configurations of the project. */
+    public List<PlcConfiguration> configurations = list();
+
+    /**
+     * Constructor for the {@link PlcProject} class.
+     *
+     * @param name The name of the PLC project.
+     */
+    public PlcProject(String name) {
+        this.name = name;
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/declarations/PlcResource.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/declarations/PlcResource.java
new file mode 100644
index 0000000000000000000000000000000000000000..c41ad26326092ab6446560c91bcc415254a9e029
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/declarations/PlcResource.java
@@ -0,0 +1,42 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.model.declarations;
+
+import static org.eclipse.escet.common.java.Lists.list;
+
+import java.util.List;
+
+/** PLC resource. */
+public class PlcResource {
+    /** The name of the resource. */
+    public final String name;
+
+    /** The global variable lists of the resource. */
+    public final List<PlcGlobalVarList> globalVarLists = list();
+
+    /** The tasks of the resource. */
+    public List<PlcTask> tasks = list();
+
+    /** The POU instances of the resource. */
+    public List<PlcPouInstance> pouInstances = list();
+
+    /**
+     * Constructor for the {@link PlcResource} class.
+     *
+     * @param name The name of the resource.
+     */
+    public PlcResource(String name) {
+        this.name = name;
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/declarations/PlcTask.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/declarations/PlcTask.java
new file mode 100644
index 0000000000000000000000000000000000000000..f4db79af27012d3fd301636d1ea65f209d874999
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/declarations/PlcTask.java
@@ -0,0 +1,50 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.model.declarations;
+
+import static org.eclipse.escet.common.java.Lists.list;
+
+import java.util.List;
+
+/** PLC task. */
+public class PlcTask {
+    /** The name of the task. */
+    public final String name;
+
+    /**
+     * The positive cycle time in milliseconds, if periodic task scheduling is used, or zero if periodic task scheduling
+     * is disabled.
+     */
+    public final int cycleTime;
+
+    /** The priority of the task, in range [0 .. 65535]. */
+    public final int priority;
+
+    /** The POU instances of the task. */
+    public List<PlcPouInstance> pouInstances = list();
+
+    /**
+     * Constructor for the {@link PlcTask} class.
+     *
+     * @param name The name of the task.
+     * @param cycleTime The positive cycle time in milliseconds, if periodic task scheduling is used, or zero if
+     *     periodic task scheduling is disabled.
+     * @param priority The priority of the task, in range [0 .. 65535].
+     */
+    public PlcTask(String name, int cycleTime, int priority) {
+        this.name = name;
+        this.cycleTime = cycleTime;
+        this.priority = priority;
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/declarations/PlcTypeDecl.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/declarations/PlcTypeDecl.java
new file mode 100644
index 0000000000000000000000000000000000000000..e380f0c4fd3c1c1fad77e199cd3f261d00a6d5f4
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/declarations/PlcTypeDecl.java
@@ -0,0 +1,36 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.model.declarations;
+
+import org.eclipse.escet.cif.plcgen.model.types.PlcType;
+
+/** PLC type declaration. */
+public class PlcTypeDecl {
+    /** The name of the type declaration. */
+    public final String name;
+
+    /** The type of the type declaration. */
+    public final PlcType type;
+
+    /**
+     * Constructor for the {@link PlcTypeDecl} class.
+     *
+     * @param name The name of the type declaration.
+     * @param type The type of the type declaration.
+     */
+    public PlcTypeDecl(String name, PlcType type) {
+        this.name = name;
+        this.type = type;
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/declarations/PlcVariable.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/declarations/PlcVariable.java
new file mode 100644
index 0000000000000000000000000000000000000000..93b916375c8cdcec79af771444d1b7bba8d411fb
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/declarations/PlcVariable.java
@@ -0,0 +1,57 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.model.declarations;
+
+import org.eclipse.escet.cif.plcgen.model.expressions.PlcValue;
+import org.eclipse.escet.cif.plcgen.model.types.PlcType;
+
+/** PLC variable (or constant). */
+public class PlcVariable {
+    /** The name of the variable. */
+    public final String name;
+
+    /** The type of the variable. */
+    public final PlcType type;
+
+    /** The address of the variable, or {@code null} if not specified. */
+    public final String address;
+
+    /** The initial value of the variable, or {@code null} if not specified. */
+    public final PlcValue value;
+
+    /**
+     * Constructor for the {@link PlcVariable} class, without address and initial value.
+     *
+     * @param name The name of the variable.
+     * @param type The type of the variable.
+     */
+    public PlcVariable(String name, PlcType type) {
+        this(name, type, null, null);
+    }
+
+    /**
+     * Constructor for the {@link PlcVariable} class.
+     *
+     * @param name The name of the variable.
+     * @param type The type of the variable.
+     * @param address The address of the variable, or {@code null} if not specified.
+     * @param value The initial value of the variable, or {@code null} if not specified.
+     */
+    public PlcVariable(String name, PlcType type, String address, PlcValue value) {
+        this.name = name;
+        this.type = type;
+        this.address = address;
+        this.value = value;
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/expressions/PlcArrayLiteral.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/expressions/PlcArrayLiteral.java
index 8d0c55b27c9544a66373286161a4ca9670aa5246..bb65025b8c92d90261cf5509bce0e5d0bf7c93fd 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/expressions/PlcArrayLiteral.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/expressions/PlcArrayLiteral.java
@@ -13,6 +13,7 @@
 
 package org.eclipse.escet.cif.plcgen.model.expressions;
 
+import java.util.Collections;
 import java.util.List;
 
 /** Expression describing an array value. */
@@ -26,6 +27,6 @@ public class PlcArrayLiteral extends PlcExpression {
      * @param values Values of the array.
      */
     public PlcArrayLiteral(List<PlcExpression> values) {
-        this.values = values;
+        this.values = Collections.unmodifiableList(values);
     }
 }
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/expressions/PlcEnumLiteral.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/expressions/PlcEnumLiteral.java
new file mode 100644
index 0000000000000000000000000000000000000000..116f6f8cb25c21a5efe4bb3a7bfce912f344181d
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/expressions/PlcEnumLiteral.java
@@ -0,0 +1,29 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.model.expressions;
+
+/** Expression class for an enumeration literal. */
+public class PlcEnumLiteral extends PlcExpression {
+    /** Value of the literal. */
+    public final String value;
+
+    /**
+     * Constructor of the {@link PlcEnumLiteral} class.
+     *
+     * @param value Value of the literal.
+     */
+    public PlcEnumLiteral(String value) {
+        this.value = value;
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/expressions/PlcFuncAppl.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/expressions/PlcFuncAppl.java
index a9cb2575d2cd7678cf0cda3dc7ac77d29a475eeb..7dd4645b84f514bb2720f6d63c14e132c70c1101 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/expressions/PlcFuncAppl.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/expressions/PlcFuncAppl.java
@@ -13,6 +13,7 @@
 
 package org.eclipse.escet.cif.plcgen.model.expressions;
 
+import java.util.Collections;
 import java.util.List;
 
 import org.eclipse.escet.cif.plcgen.model.functions.PlcBasicFuncDescription;
@@ -34,7 +35,7 @@ public class PlcFuncAppl extends PlcExpression {
      */
     public PlcFuncAppl(PlcBasicFuncDescription function, List<PlcNamedValue> arguments) {
         this.function = function;
-        this.arguments = arguments;
+        this.arguments = Collections.unmodifiableList(arguments);
 
         Assert.check(!arguments.isEmpty());
     }
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/expressions/PlcStructLiteral.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/expressions/PlcStructLiteral.java
index f2e2d83f36388e0f49ac76768f5ec1f3d8bd9589..481fe44c7444312c1329c0efdd3f78d4882c43a9 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/expressions/PlcStructLiteral.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/expressions/PlcStructLiteral.java
@@ -13,6 +13,7 @@
 
 package org.eclipse.escet.cif.plcgen.model.expressions;
 
+import java.util.Collections;
 import java.util.List;
 
 /** Expression describing a structure value. */
@@ -26,6 +27,6 @@ public class PlcStructLiteral extends PlcExpression {
      * @param values Values of the structure.
      */
     public PlcStructLiteral(List<PlcNamedValue> values) {
-        this.values = values;
+        this.values = Collections.unmodifiableList(values);
     }
 }
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/expressions/PlcValue.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/expressions/PlcValue.java
new file mode 100644
index 0000000000000000000000000000000000000000..fc9bfe4acce6337387693decfbe56c3dbb13825d
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/expressions/PlcValue.java
@@ -0,0 +1,29 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.model.expressions;
+
+/** PLC value. */
+public class PlcValue {
+    /** The 'simple' value in IEC 61131-3 Structured Text syntax. */
+    public final String value;
+
+    /**
+     * Constructor for the {@link PlcValue} class.
+     *
+     * @param value The 'simple' value in IEC 61131-3 Structured Text syntax.
+     */
+    public PlcValue(String value) {
+        this.value = value;
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/expressions/PlcVarExpression.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/expressions/PlcVarExpression.java
index dabb61239024ebb0ca09f6f7520983d402810079..f24d4775972d51b84355ce85cb8970cfe7486946 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/expressions/PlcVarExpression.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/expressions/PlcVarExpression.java
@@ -14,9 +14,10 @@
 package org.eclipse.escet.cif.plcgen.model.expressions;
 
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcVariable;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcVariable;
 import org.eclipse.escet.common.java.Assert;
 
 /** Expression referencing a variable, includes optional projections on the variable. */
@@ -34,8 +35,7 @@ public class PlcVarExpression extends PlcExpression {
      * @param projections Projections to select a part of the variable.
      */
     public PlcVarExpression(PlcVariable variable, PlcProjection... projections) {
-        this.variable = variable;
-        this.projections = Arrays.asList(projections);
+        this(variable, Arrays.asList(projections));
     }
 
     /**
@@ -46,7 +46,7 @@ public class PlcVarExpression extends PlcExpression {
      */
     public PlcVarExpression(PlcVariable variable, List<PlcProjection> projections) {
         this.variable = variable;
-        this.projections = projections;
+        this.projections = Collections.unmodifiableList(projections);
     }
 
     /** Projection in the value of the referenced variable. */
@@ -90,7 +90,7 @@ public class PlcVarExpression extends PlcExpression {
          */
         public PlcArrayProjection(List<PlcExpression> indexExpressions) {
             Assert.check(!indexExpressions.isEmpty());
-            this.indexExpressions = indexExpressions;
+            this.indexExpressions = Collections.unmodifiableList(indexExpressions);
         }
     }
 }
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/functions/PlcBasicFuncDescription.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/functions/PlcBasicFuncDescription.java
index 4a6de757265d87fab4be682470db7aaa5f9fea22..c9e01c97efd3de8bc643e7e5b0e6d55f5e855907 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/functions/PlcBasicFuncDescription.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/functions/PlcBasicFuncDescription.java
@@ -84,8 +84,8 @@ public abstract class PlcBasicFuncDescription {
         /** Unary expression binding. */
         UNARY_EXPR(1, ExprAssociativity.RIGHT),
 
-        /** Exponentiation expression binding. */
-        EXPT_EXPR(2, ExprAssociativity.ALWAYS),
+        /** Power expression binding ({@code base ** exponent}). */
+        POWER_EXPR(2, ExprAssociativity.ALWAYS),
 
         /** Multiplicative expression binding. */
         MUL_EXPR(3, ExprAssociativity.LEFT),
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/functions/PlcCastFunction.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/functions/PlcCastFunction.java
index 051188acead9891ed537bef8b14e600c0ca1aad0..2cbabad8840536cbb377e0ac420983d566d95185 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/functions/PlcCastFunction.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/functions/PlcCastFunction.java
@@ -15,7 +15,7 @@ package org.eclipse.escet.cif.plcgen.model.functions;
 
 import java.util.List;
 
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcElementaryType;
+import org.eclipse.escet.cif.plcgen.model.types.PlcElementaryType;
 
 /** Cast function with the semantic type conversion performed in a function application. */
 public class PlcCastFunction extends PlcBasicFuncDescription {
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/functions/PlcFuncOperation.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/functions/PlcFuncOperation.java
index 063339a928a712b508a9a3145e8bfb93fb0b2142..4bf2ab886070c0f8c4d276882a7f147b556b0d6d 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/functions/PlcFuncOperation.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/functions/PlcFuncOperation.java
@@ -18,8 +18,8 @@ public enum PlcFuncOperation {
     /** Negate (unary minus) operation. */
     NEGATE_OP,
 
-    /** Exponentiation operation. */
-    EXP_OP,
+    /** Power operation ({@code base ** exponent}). */
+    POWER_OP,
 
     /** Multiplication operation. */
     MULTIPLY_OP,
@@ -70,5 +70,44 @@ public enum PlcFuncOperation {
     CAST_OP,
 
     /** Tertiary if/else operation. */
-    SEL_OP;
+    SEL_OP,
+
+    /** Absolute value operation. */
+    STDLIB_ABS,
+
+    /** Exponential operation ((@code e ** x}). */
+    STDLIB_EXP,
+
+    /** Natural logarithm operation. */
+    STDLIB_LN,
+
+    /** Base 10 logarithm operation. */
+    STDLIB_LOG,
+
+    /** Minimum value operation. */
+    STDLIB_MIN,
+
+    /** Maximum value operation. */
+    STDLIB_MAX,
+
+    /** Square root operation. */
+    STDLIB_SQRT,
+
+    /** Arccosine operation. */
+    STDLIB_ACOS,
+
+    /** Arcsine operation. */
+    STDLIB_ASIN,
+
+    /** Arctangent operation. */
+    STDLIB_ATAN,
+
+    /** Cosine operation. */
+    STDLIB_COS,
+
+    /** Sine operation. */
+    STDLIB_SIN,
+
+    /** Tangent operation. */
+    STDLIB_TAN;
 }
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/statements/PlcAssignmentStatement.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/statements/PlcAssignmentStatement.java
index 826936710d8ca20bc8cbc56005c0124af33acf6c..34f6319b0cecfb147bb6a27baeb8132f7e362860 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/statements/PlcAssignmentStatement.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/statements/PlcAssignmentStatement.java
@@ -34,4 +34,9 @@ public class PlcAssignmentStatement extends PlcStatement {
         this.lhs = lhs;
         this.value = value;
     }
+
+    @Override
+    public PlcAssignmentStatement copy() {
+        return new PlcAssignmentStatement(lhs, value);
+    }
 }
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/statements/PlcCommentLine.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/statements/PlcCommentLine.java
index f1b2714652dd26eb93751f77a8aa09ed15144fa2..31c6ebcf62171ca310209c60ef77aa11bf2b83de 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/statements/PlcCommentLine.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/statements/PlcCommentLine.java
@@ -58,4 +58,9 @@ public class PlcCommentLine extends PlcStatement {
         this.commentText = commentText;
         this.isEmptyStatement = isEmptyStatement;
     }
+
+    @Override
+    public PlcStatement copy() {
+        return new PlcCommentLine(commentText, isEmptyStatement);
+    }
 }
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/statements/PlcFuncApplStatement.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/statements/PlcFuncApplStatement.java
index 561b83b4907d58dfaab4427cc412784931f569d8..23b604a7c9c840eadf46a1ee4666bf756ee553d3 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/statements/PlcFuncApplStatement.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/statements/PlcFuncApplStatement.java
@@ -28,4 +28,9 @@ public class PlcFuncApplStatement extends PlcStatement {
     public PlcFuncApplStatement(PlcFuncAppl funcApplExpr) {
         this.funcApplExpr = funcApplExpr;
     }
+
+    @Override
+    public PlcStatement copy() {
+        return new PlcFuncApplStatement(funcApplExpr);
+    }
 }
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/statements/PlcReturnStatement.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/statements/PlcReturnStatement.java
index 78643c944f10392738f4181c36ae9be1c2d99d05..eaf3a5a88d0c6f5492cd6301c07ca9024dda2559 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/statements/PlcReturnStatement.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/statements/PlcReturnStatement.java
@@ -34,4 +34,9 @@ public class PlcReturnStatement extends PlcStatement {
     public PlcReturnStatement(PlcExpression returnValue) {
         this.returnValue = returnValue;
     }
+
+    @Override
+    public PlcReturnStatement copy() {
+        return new PlcReturnStatement(returnValue);
+    }
 }
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/statements/PlcSelectionStatement.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/statements/PlcSelectionStatement.java
index 8cf20bd1e665d719076ec0f447b4d0f4028f8478..3ee68c04233a319d1b00053e3cf793941def0cd0 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/statements/PlcSelectionStatement.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/statements/PlcSelectionStatement.java
@@ -13,7 +13,11 @@
 
 package org.eclipse.escet.cif.plcgen.model.statements;
 
+import static org.eclipse.escet.common.java.Lists.list;
+import static org.eclipse.escet.common.java.Lists.listc;
+
 import java.util.List;
+import java.util.stream.Collectors;
 
 import org.eclipse.escet.cif.plcgen.model.expressions.PlcExpression;
 
@@ -25,6 +29,11 @@ public class PlcSelectionStatement extends PlcStatement {
     /** Choice to perform if none of the {@link #condChoices} can be chosen. */
     public List<PlcStatement> elseStats;
 
+    /** Constructor of the {@link PlcSelectionStatement} class. */
+    public PlcSelectionStatement() {
+        this(list(), list());
+    }
+
     /**
      * Constructor of the {@link PlcSelectionStatement} class.
      *
@@ -54,5 +63,21 @@ public class PlcSelectionStatement extends PlcStatement {
             this.guard = guard;
             this.thenStats = thenStats;
         }
+
+        /**
+         * Make a copy of the selection choice.
+         *
+         * @return The newly created copy of the selection choice.
+         */
+        public PlcSelectChoice copy() {
+            return new PlcSelectChoice(guard, PlcStatement.copy(thenStats));
+        }
+    }
+
+    @Override
+    public PlcStatement copy() {
+        List<PlcSelectChoice> choices = listc(condChoices.size());
+        condChoices.stream().map(PlcSelectChoice::copy).collect(Collectors.toCollection(() -> choices));
+        return new PlcSelectionStatement(choices, PlcStatement.copy(elseStats));
     }
 }
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/statements/PlcStatement.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/statements/PlcStatement.java
index a83b06f008574c7a9f4644bffaf056cf3c9a4bfd..87b1fc2f8d6133677fbcf3f8f7fd8b758255e153 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/statements/PlcStatement.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/statements/PlcStatement.java
@@ -13,7 +13,29 @@
 
 package org.eclipse.escet.cif.plcgen.model.statements;
 
+import static org.eclipse.escet.common.java.Lists.listc;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
 /** Statement in PLC code. */
 public abstract class PlcStatement {
-    // Nothing to do.
+    /**
+     * Make a copy of the statement.
+     *
+     * @return The newly created statement.
+     */
+    public abstract PlcStatement copy();
+
+    /**
+     * Copy a sequence of statements.
+     *
+     * @param statements Statements to copy.
+     * @return The copied statements.
+     */
+    public static List<PlcStatement> copy(List<PlcStatement> statements) {
+        List<PlcStatement> stats = listc(statements.size());
+        statements.stream().map(PlcStatement::copy).collect(Collectors.toCollection(() -> stats));
+        return stats;
+    }
 }
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/types/PlcArrayType.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/types/PlcArrayType.java
new file mode 100644
index 0000000000000000000000000000000000000000..adbd0672007ace8911bf35f714db5e201c52fcf5
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/types/PlcArrayType.java
@@ -0,0 +1,60 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.model.types;
+
+import org.eclipse.escet.common.java.Assert;
+
+/** PLC array type. */
+public class PlcArrayType extends PlcType {
+    /** The lower bound index of the array, i.e. the lowest index value that exists. Always zero for CIF. */
+    public final int lower;
+
+    /** The upper bound index of the array, i.e. the highest index value that exists. */
+    public final int upper;
+
+    /** The element type. */
+    public final PlcType elemType;
+
+    /**
+     * Constructor for the {@link PlcArrayType} class.
+     *
+     * @param lower The lower bound index of the array, i.e. the lowest index value that exists. Always zero for CIF.
+     * @param upper The upper bound index of the array, i.e. the highest index value that exists.
+     * @param elemType The element type.
+     */
+    public PlcArrayType(int lower, int upper, PlcType elemType) {
+        this.lower = lower;
+        this.upper = upper;
+        this.elemType = elemType;
+
+        Assert.check(lower == 0);
+        Assert.check(upper >= lower);
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        }
+        if (!(other instanceof PlcArrayType arrayType)) {
+            return false;
+        }
+        return lower == arrayType.lower && upper == arrayType.upper && elemType.equals(arrayType.elemType);
+    }
+
+    @Override
+    public int hashCode() {
+        return elemType.hashCode() + upper + lower;
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/types/PlcDerivedType.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/types/PlcDerivedType.java
new file mode 100644
index 0000000000000000000000000000000000000000..a03492fc62e01db6817d9acc585547fccf90031f
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/types/PlcDerivedType.java
@@ -0,0 +1,48 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.model.types;
+
+/** PLC derived type (reference to a user-defined data type or POU). */
+public class PlcDerivedType extends PlcType {
+    /** PLC 'STATE' type reference. */
+    public static final PlcDerivedType STATE_TYPE = new PlcDerivedType("STATE");
+
+    /** The name of the derived type. */
+    public final String name;
+
+    /**
+     * Constructor for the {@link PlcDerivedType} class.
+     *
+     * @param name The name of the derived type.
+     */
+    public PlcDerivedType(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        }
+        if (!(other instanceof PlcDerivedType derivedType)) {
+            return false;
+        }
+        return name.equals(derivedType.name);
+    }
+
+    @Override
+    public int hashCode() {
+        return name.hashCode();
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/types/PlcElementaryType.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/types/PlcElementaryType.java
new file mode 100644
index 0000000000000000000000000000000000000000..c12d30d3efd42c118b455d0816b5f743c2783431
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/types/PlcElementaryType.java
@@ -0,0 +1,102 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.model.types;
+
+/** PLC elementary type. */
+public class PlcElementaryType extends PlcType {
+    /** PLC BOOL type. */
+    public static final PlcElementaryType BOOL_TYPE = new PlcElementaryType("BOOL");
+
+    /** PLC INT type. */
+    public static final PlcElementaryType INT_TYPE = new PlcElementaryType("INT");
+
+    /** PLC DINT type. */
+    public static final PlcElementaryType DINT_TYPE = new PlcElementaryType("DINT");
+
+    /** PLC LINT type. */
+    public static final PlcElementaryType LINT_TYPE = new PlcElementaryType("LINT");
+
+    /** PLC REAL type. */
+    public static final PlcElementaryType REAL_TYPE = new PlcElementaryType("REAL");
+
+    /** PLC LREAL type. */
+    public static final PlcElementaryType LREAL_TYPE = new PlcElementaryType("LREAL");
+
+    /** PLC TIME type. */
+    public static final PlcElementaryType TIME_TYPE = new PlcElementaryType("TIME");
+
+    /** The name of the elementary type. */
+    public final String name;
+
+    /**
+     * Constructor for the {@link PlcElementaryType} class.
+     *
+     * @param name The name of the elementary type.
+     */
+    public PlcElementaryType(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        }
+        if (!(other instanceof PlcElementaryType elementaryType)) {
+            return false;
+        }
+        return name.equals(elementaryType.name);
+    }
+
+    @Override
+    public int hashCode() {
+        return name.hashCode();
+    }
+
+    /**
+     * Retrieve the integer type that uses the given number of bits in PLC memory.
+     *
+     * @param numBits Wanted length of integer values in bits.
+     * @return The PLC integer type with exactly the requested number of bits.
+     */
+    public static PlcElementaryType getIntTypeBySize(int numBits) {
+        switch (numBits) {
+            case 16:
+                return INT_TYPE;
+            case 32:
+                return DINT_TYPE;
+            case 64:
+                return LINT_TYPE;
+            default:
+                throw new AssertionError("Unexpected integer size " + String.valueOf(numBits) + " found.");
+        }
+    }
+
+    /**
+     * Retrieve the real type that uses the given number of bits in PLC memory.
+     *
+     * @param numBits Wanted length of real values in bits.
+     * @return The PLC real type with exactly the requested number of bits.
+     */
+    public static PlcElementaryType getRealTypeBySize(int numBits) {
+        switch (numBits) {
+            case 32:
+                return REAL_TYPE;
+            case 64:
+                return LREAL_TYPE;
+            default:
+                throw new AssertionError("Unexpected real size " + String.valueOf(numBits) + " found.");
+        }
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/types/PlcEnumType.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/types/PlcEnumType.java
new file mode 100644
index 0000000000000000000000000000000000000000..37ae8d33f2cd210234aabe93ebf985a6f1a1296c
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/types/PlcEnumType.java
@@ -0,0 +1,47 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.model.types;
+
+import java.util.List;
+
+/** PLC enum type. */
+public class PlcEnumType extends PlcType {
+    /** The literals of the enum type. */
+    public final List<String> literals;
+
+    /**
+     * Constructor for the {@link PlcEnumType} class.
+     *
+     * @param literals The literals of the enum type.
+     */
+    public PlcEnumType(List<String> literals) {
+        this.literals = literals;
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        }
+        if (!(other instanceof PlcEnumType enumType)) {
+            return false;
+        }
+        return literals.equals(enumType.literals);
+    }
+
+    @Override
+    public int hashCode() {
+        return literals.hashCode();
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/types/PlcStructType.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/types/PlcStructType.java
new file mode 100644
index 0000000000000000000000000000000000000000..9101ef5bef1e1764d632366ffc6d929deb5ca538
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/types/PlcStructType.java
@@ -0,0 +1,54 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.model.types;
+
+import static org.eclipse.escet.common.java.Lists.list;
+
+import java.util.List;
+
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcVariable;
+
+/** PLC struct type. */
+public class PlcStructType extends PlcType {
+    /** The fields of the struct type. */
+    public List<PlcVariable> fields = list();
+
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        }
+        if (!(other instanceof PlcStructType structType) || fields.size() != structType.fields.size()) {
+            return false;
+        }
+        for (int i = 0; i < fields.size(); i++) {
+            if (!fields.get(i).name.equals(structType.fields.get(i).name)) {
+                return false;
+            }
+            if (!fields.get(i).type.equals(structType.fields.get(i).type)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int h = 0;
+        for (PlcVariable field: fields) {
+            h = h + field.name.hashCode() + field.type.hashCode() * 23;
+        }
+        return h;
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/types/PlcType.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/types/PlcType.java
new file mode 100644
index 0000000000000000000000000000000000000000..6a9a79b5e564af5a0656e1ac5d9e214dde623534
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/model/types/PlcType.java
@@ -0,0 +1,23 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.model.types;
+
+/** PLC type. */
+public abstract class PlcType {
+    @Override
+    public abstract boolean equals(Object other);
+
+    @Override
+    public abstract int hashCode();
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/ConvertEnums.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/ConvertEnums.java
new file mode 100644
index 0000000000000000000000000000000000000000..aaeeb8b4dcd735403a59b4c9e6349d64f667bede
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/ConvertEnums.java
@@ -0,0 +1,26 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.options;
+
+/** Should enumeration data types be converted? */
+public enum ConvertEnums {
+    /** No, keep enumeration data types. */
+    NO,
+
+    /** Yes, convert enumerations to integers. */
+    INTS,
+
+    /** Yes, convert enumerations to constants. */
+    CONSTS;
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/ConvertEnumsOption.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/ConvertEnumsOption.java
new file mode 100644
index 0000000000000000000000000000000000000000..bc69904a4a06035862a16c9fb618087a9eaaa1f6
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/ConvertEnumsOption.java
@@ -0,0 +1,51 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.options;
+
+import org.eclipse.escet.common.app.framework.options.EnumOption;
+import org.eclipse.escet.common.app.framework.options.Options;
+
+/** Convert enumerations option. */
+public class ConvertEnumsOption extends EnumOption<ConvertEnums> {
+    /** Constructor for the {@link ConvertEnumsOption} class. */
+    public ConvertEnumsOption() {
+        super("Convert enumerations", "Specify whether enumerations should be converted. Specify \"no\" to preserve "
+                + "enumerations, \"ints\" for conversion to integers, or \"consts\" for conversion to constants. "
+                + "[DEFAULT=no]", null, "convert-enums", "CONVERT", ConvertEnums.NO, true,
+                "Should enumerations be converted?");
+    }
+
+    @Override
+    protected String getDialogText(ConvertEnums value) {
+        switch (value) {
+            case NO:
+                return "Keep enumerations";
+            case INTS:
+                return "Convert enumerations to integers";
+            case CONSTS:
+                return "Convert enumerations to constants";
+            default:
+                throw new RuntimeException("Unknown value: " + value);
+        }
+    }
+
+    /**
+     * Should enumerations be converted?
+     *
+     * @return Value indicating whether enumerations are preserved, converted to integers, or converted to constants.
+     */
+    public static ConvertEnums getValue() {
+        return Options.get(ConvertEnumsOption.class);
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/ElimEnumsOption.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/ElimEnumsOption.java
new file mode 100644
index 0000000000000000000000000000000000000000..7f5e6ef3685948a20d909b4fd25993efb2ac6a3c
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/ElimEnumsOption.java
@@ -0,0 +1,36 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.options;
+
+import org.eclipse.escet.common.app.framework.options.BooleanOption;
+import org.eclipse.escet.common.app.framework.options.Options;
+
+/** Eliminate enumerations option. */
+public class ElimEnumsOption extends BooleanOption {
+    /** Constructor for the {@link ElimEnumsOption} class. */
+    public ElimEnumsOption() {
+        super("Eliminate enumerations",
+                "Whether the eliminate enumerations (BOOL=yes), or keep them (BOOL=no). [DEFAULT=no] (deprecated)",
+                null, "elim-enums", "BOOL", false, false, null, null);
+    }
+
+    /**
+     * Returns a value indicating whether enumerations should be eliminated.
+     *
+     * @return {@code true} if enumerations should be eliminated, {@code false} otherwise.
+     */
+    public static boolean elimEnums() {
+        return Options.get(ElimEnumsOption.class);
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcConfigurationNameOption.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcConfigurationNameOption.java
new file mode 100644
index 0000000000000000000000000000000000000000..159e8ea42c3f1a41d1a57bf0ddf8324cb216a369
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcConfigurationNameOption.java
@@ -0,0 +1,37 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.options;
+
+import org.eclipse.escet.common.app.framework.options.Options;
+import org.eclipse.escet.common.app.framework.options.StringOption;
+
+/** PLC configuration name option. */
+public class PlcConfigurationNameOption extends StringOption {
+    /** Constructor for the {@link PlcConfigurationNameOption} class. */
+    public PlcConfigurationNameOption() {
+        super("PLC configuration name",
+                "CFGNAME is the name to use for the PLC configuration to generate. [DEFAULT=\"Untitled1\"]", 'c',
+                "config-name", "CFGNAME", "Untitled1", false, true,
+                "The name to use for the PLC configuration to generate.", "Configuration name:");
+    }
+
+    /**
+     * Returns the PLC configuration name.
+     *
+     * @return The PLC configuration name.
+     */
+    public static String getCfgName() {
+        return Options.get(PlcConfigurationNameOption.class);
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcFormalFuncInvokeArg.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcFormalFuncInvokeArg.java
new file mode 100644
index 0000000000000000000000000000000000000000..04f7ba206ff8e239636a7ebc124cbd61ca3f0231
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcFormalFuncInvokeArg.java
@@ -0,0 +1,29 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.options;
+
+/**
+ * When should formal function invocation syntax be used in the PLC code, based on the number of arguments of the
+ * function?
+ */
+public enum PlcFormalFuncInvokeArg {
+    /** For all functions. */
+    ALL,
+
+    /** For functions with more than one argument. */
+    MULTI,
+
+    /** For none of the functions. */
+    NONE;
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcFormalFuncInvokeArgOption.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcFormalFuncInvokeArgOption.java
new file mode 100644
index 0000000000000000000000000000000000000000..8999e87c504ad0fa9847c3765276efc9644a8b97
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcFormalFuncInvokeArgOption.java
@@ -0,0 +1,53 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.options;
+
+import org.eclipse.escet.common.app.framework.options.EnumOption;
+import org.eclipse.escet.common.app.framework.options.Options;
+
+/** Formal function invocation (arguments based) option. */
+public class PlcFormalFuncInvokeArgOption extends EnumOption<PlcFormalFuncInvokeArg> {
+    /** Constructor for the {@link PlcFormalFuncInvokeArgOption} class. */
+    public PlcFormalFuncInvokeArgOption() {
+        super("Formal function invocation (arguments based)",
+                "Specify for which functions to use formal invocation syntax in the generated PLC code. Specify "
+                        + "\"all\" for all functions, \"multi\" for functions with more than one argument, or "
+                        + "\"none\" for none of the functions. [DEFAULT=none]",
+                null, "formal-finvoke-arg", "ARG", PlcFormalFuncInvokeArg.NONE, true,
+                "For which functions should formal invocation syntax be used in the generated PLC code?");
+    }
+
+    @Override
+    protected String getDialogText(PlcFormalFuncInvokeArg value) {
+        switch (value) {
+            case ALL:
+                return "For all functions";
+            case MULTI:
+                return "For functions with more than one argument";
+            case NONE:
+                return "For none of the functions";
+            default:
+                throw new RuntimeException("Unknown value: " + value);
+        }
+    }
+
+    /**
+     * For which functions should formal invocation syntax be used in the generated PLC code?
+     *
+     * @return Value indicating for which functions formal invocation syntax should be used in the generated PLC code.
+     */
+    public static PlcFormalFuncInvokeArg getValue() {
+        return Options.get(PlcFormalFuncInvokeArgOption.class);
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcFormalFuncInvokeFunc.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcFormalFuncInvokeFunc.java
new file mode 100644
index 0000000000000000000000000000000000000000..1eb0983ef2df86bd0976dfe3b72bbf1baacf6068
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcFormalFuncInvokeFunc.java
@@ -0,0 +1,28 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.options;
+
+/**
+ * When should formal function invocation syntax be used in the PLC code, based on the kind of function that is invoked?
+ */
+public enum PlcFormalFuncInvokeFunc {
+    /** For all functions. */
+    ALL,
+
+    /** For standard library/conversion functions only. */
+    STD,
+
+    /** For all but standard library/conversion functions. */
+    OTHERS;
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcFormalFuncInvokeFuncOption.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcFormalFuncInvokeFuncOption.java
new file mode 100644
index 0000000000000000000000000000000000000000..06419aa4bad07c5642eec0c1557605df71b321c8
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcFormalFuncInvokeFuncOption.java
@@ -0,0 +1,56 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.options;
+
+import org.eclipse.escet.common.app.framework.options.EnumOption;
+import org.eclipse.escet.common.app.framework.options.Options;
+
+/** Formal function invocation (function kind based) option. */
+public class PlcFormalFuncInvokeFuncOption extends EnumOption<PlcFormalFuncInvokeFunc> {
+    /** Constructor for the {@link PlcFormalFuncInvokeFuncOption} class. */
+    public PlcFormalFuncInvokeFuncOption() {
+        super("Formal function invocation (function kind based)",
+                "Specify for which functions to use formal invocation syntax in the generated PLC code. Specify "
+                        + "\"all\" for all functions, \"std\" for standard library/conversion functions only, "
+                        + "or \"others\" for all but the standard library/conversion functions. [DEFAULT=others]",
+                null, "formal-finvoke-func", "FUNC", PlcFormalFuncInvokeFunc.OTHERS, true,
+                "For which functions should formal invocation syntax be used in the generated PLC code?");
+    }
+
+    @Override
+    protected String getDialogText(PlcFormalFuncInvokeFunc value) {
+        switch (value) {
+            case ALL:
+                return "For all functions";
+
+            case STD:
+                return "For standard library/conversion functions only";
+
+            case OTHERS:
+                return "For all but standard library/conversion functions";
+
+            default:
+                throw new RuntimeException("Unknown value: " + value);
+        }
+    }
+
+    /**
+     * For which functions should formal invocation syntax be used in the generated PLC code?
+     *
+     * @return Value indicating for which functions formal invocation syntax should be used in the generated PLC code.
+     */
+    public static PlcFormalFuncInvokeFunc getValue() {
+        return Options.get(PlcFormalFuncInvokeFuncOption.class);
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcIntTypeSizeOption.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcIntTypeSizeOption.java
index 8d99bb2fb5035dea1a356d1ae64f31409a6d4c71..16c4a1815809c8822d1047390b82e3378cf16a38 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcIntTypeSizeOption.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcIntTypeSizeOption.java
@@ -13,7 +13,6 @@
 
 package org.eclipse.escet.cif.plcgen.options;
 
-import org.eclipse.escet.cif.cif2plc.options.PlcNumberBits;
 import org.eclipse.escet.common.app.framework.exceptions.InvalidOptionException;
 import org.eclipse.escet.common.app.framework.options.EnumOption;
 import org.eclipse.escet.common.app.framework.options.Options;
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcMaxIterOption.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcMaxIterOption.java
new file mode 100644
index 0000000000000000000000000000000000000000..32461f7fd7ed0145224b9007446ad8e88a1402e8
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcMaxIterOption.java
@@ -0,0 +1,88 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.options;
+
+import org.eclipse.escet.common.app.framework.options.IntegerOption;
+import org.eclipse.escet.common.app.framework.options.Options;
+
+/** PLC maximum iterations option. */
+public class PlcMaxIterOption extends IntegerOption {
+    /** Constructor for the {@link PlcMaxIterOption} class. */
+    public PlcMaxIterOption() {
+        super(
+                // name
+                "PLC maximum iterations",
+
+                // description
+                "The maximum number of iterations of the main loop of the main program body, per execution of the "
+                        + "main program body. The number must be positive. Use \"inf\" to allow an infinite number of "
+                        + "iterations (no restriction). [DEFAULT=100]",
+
+                // cmdShort
+                'x',
+
+                // cmdLong
+                "max-iter",
+
+                // cmdValue
+                "ITERS",
+
+                // defaultValue
+                100,
+
+                // minimumValue
+                1,
+
+                // maximumValue
+                Integer.MAX_VALUE,
+
+                // pageIncrementValue
+                10,
+
+                // showInDialog
+                true,
+
+                // optDialogDescr
+                "The maximum number of iterations of the main loop of the main program body, per execution of the "
+                        + "main program body.",
+
+                // optDialogLabelText
+                "Maximum iterations:",
+
+                // hasSpecialValue
+                true,
+
+                // defaultNormalValue
+                100,
+
+                // specialValueSyntax
+                "inf",
+
+                // optDialogSpecialText
+                "Infinite number of iterations (no restriction)",
+
+                // optDialogNormalText
+                "Finite number of iterations");
+    }
+
+    /**
+     * Returns the maximum number of iterations of the main loop of the main program body, per execution of the main
+     * program body.
+     *
+     * @return The maximum number of iterations, or {@code null} for no maximum.
+     */
+    public static Integer getMaxIter() {
+        return Options.get(PlcMaxIterOption.class);
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcNumberBits.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcNumberBits.java
new file mode 100644
index 0000000000000000000000000000000000000000..a76396145b16efa2e22d85e0272435f0f13b2464
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcNumberBits.java
@@ -0,0 +1,61 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.options;
+
+/** The number of bits maximally available for numbers in the PLC. */
+public enum PlcNumberBits {
+    /** Let the generator decide. */
+    AUTO("Automatic", "auto", PlcNumberBits.GENERATOR_SIZE),
+
+    /** 32-bit. */
+    BITS_32("32-bit", "32", 32),
+
+    /** 64-bit. */
+    BITS_64("64-bit", "64", 64);
+
+    /** The text to use in dialogs. */
+    public final String dialogText;
+
+    /** The command line value text. */
+    public final String cmdValueTxt;
+
+    /** Value expressing that the generator should decide the size. */
+    private static final int GENERATOR_SIZE = -1;
+
+    /** Size in number of bits expressed by the literal, or {@link #GENERATOR_SIZE}. */
+    private final int size;
+
+    /**
+     * Constructor for the {@link PlcNumberBits} enum.
+     *
+     * @param dialogText The text to use in dialogs.
+     * @param cmdValueTxt The command line value text.
+     * @param size Size in number of bits expressed by the literal or {@link #GENERATOR_SIZE}.
+     */
+    private PlcNumberBits(String dialogText, String cmdValueTxt, int size) {
+        this.dialogText = dialogText;
+        this.cmdValueTxt = cmdValueTxt;
+        this.size = size;
+    }
+
+    /**
+     * Retrieve the expressed size in bits by the enumeration value.
+     *
+     * @param generatorSize The size in bits to use in case the generator should decide.
+     * @return The size in bits expressed by the enumeration value.
+     */
+    public int getTypeSize(int generatorSize) {
+        return (size == GENERATOR_SIZE) ? generatorSize : size;
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcProjectNameOption.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcProjectNameOption.java
new file mode 100644
index 0000000000000000000000000000000000000000..0484692fefaf27dcbf867da50c1506301fcb94da
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcProjectNameOption.java
@@ -0,0 +1,36 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.options;
+
+import org.eclipse.escet.common.app.framework.options.Options;
+import org.eclipse.escet.common.app.framework.options.StringOption;
+
+/** PLC project name option. */
+public class PlcProjectNameOption extends StringOption {
+    /** Constructor for the {@link PlcProjectNameOption} class. */
+    public PlcProjectNameOption() {
+        super("PLC project name", "PRJNAME is the name to use for the PLC project to generate. [DEFAULT=\"Untitled1\"]",
+                'j', "proj-name", "PRJNAME", "Untitled1", false, true,
+                "The name to use for the PLC project to generate.", "Project name:");
+    }
+
+    /**
+     * Returns the PLC project name.
+     *
+     * @return The PLC project name.
+     */
+    public static String getProjName() {
+        return Options.get(PlcProjectNameOption.class);
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcRealTypeSizeOption.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcRealTypeSizeOption.java
index 59e075f8eb065c289095f19e658b86897bc35799..38e3ba8e89074d4b56ad1d5e43f87fa61972a760 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcRealTypeSizeOption.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcRealTypeSizeOption.java
@@ -13,7 +13,6 @@
 
 package org.eclipse.escet.cif.plcgen.options;
 
-import org.eclipse.escet.cif.cif2plc.options.PlcNumberBits;
 import org.eclipse.escet.common.app.framework.exceptions.InvalidOptionException;
 import org.eclipse.escet.common.app.framework.options.EnumOption;
 import org.eclipse.escet.common.app.framework.options.Options;
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcResourceNameOption.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcResourceNameOption.java
new file mode 100644
index 0000000000000000000000000000000000000000..9e1dc825eb4f8410395a91841218a1b94c3604c2
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcResourceNameOption.java
@@ -0,0 +1,37 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.options;
+
+import org.eclipse.escet.common.app.framework.options.Options;
+import org.eclipse.escet.common.app.framework.options.StringOption;
+
+/** PLC resource name option. */
+public class PlcResourceNameOption extends StringOption {
+    /** Constructor for the {@link PlcResourceNameOption} class. */
+    public PlcResourceNameOption() {
+        super("PLC resource name",
+                "RESNAME is the name to use for the PLC resource to generate. [DEFAULT=\"Untitled1\"]", 'r', "res-name",
+                "RESNAME", "Untitled1", false, true, "The name to use for the PLC resource to generate.",
+                "Resource name:");
+    }
+
+    /**
+     * Returns the PLC resource name.
+     *
+     * @return The PLC resource name.
+     */
+    public static String getResName() {
+        return Options.get(PlcResourceNameOption.class);
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcTaskCycleTimeOption.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcTaskCycleTimeOption.java
new file mode 100644
index 0000000000000000000000000000000000000000..3157845ea4906f818d087db3e0961070061c71a1
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcTaskCycleTimeOption.java
@@ -0,0 +1,41 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.options;
+
+import org.eclipse.escet.common.app.framework.options.IntegerOption;
+import org.eclipse.escet.common.app.framework.options.Options;
+
+/** PLC task cycle time option. */
+public class PlcTaskCycleTimeOption extends IntegerOption {
+    /** Constructor for the {@link PlcTaskCycleTimeOption} class. */
+    public PlcTaskCycleTimeOption() {
+        super("PLC task cycle time",
+                "TASKTIME is the cycle time in milliseconds for the task to generate. Specifying a cycle time enables "
+                        + "periodic task scheduling. The cycle time must be positive. Use \"off\" to disable periodic "
+                        + "task scheduling. [DEFAULT=10]",
+                'i', "task-time", "TASKTIME", 10, 1, Integer.MAX_VALUE, 1, true,
+                "The cycle time in milliseconds for the task to generate.", "Cycle time:", true, 10, "off",
+                "Disable periodic task scheduling", "Enable period task scheduling");
+    }
+
+    /**
+     * Returns the PLC task cycle time (>= 1), or 0 to disable periodic task scheduling.
+     *
+     * @return The PLC task cycle time (>= 1), or 0 to disable periodic task scheduling.
+     */
+    public static int getTaskCycleTime() {
+        Integer rslt = Options.get(PlcTaskCycleTimeOption.class);
+        return (rslt == null) ? 0 : rslt;
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcTaskNameOption.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcTaskNameOption.java
new file mode 100644
index 0000000000000000000000000000000000000000..f23c7dc1388b661b2c5e895e94f493ff58e14d5d
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcTaskNameOption.java
@@ -0,0 +1,36 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.options;
+
+import org.eclipse.escet.common.app.framework.options.Options;
+import org.eclipse.escet.common.app.framework.options.StringOption;
+
+/** PLC task name option. */
+public class PlcTaskNameOption extends StringOption {
+    /** Constructor for the {@link PlcTaskNameOption} class. */
+    public PlcTaskNameOption() {
+        super("PLC task name", "TASKNAME is the name to use for the PLC task to generate. [DEFAULT=\"PlcTask\"]", 'n',
+                "task-name", "TASKNAME", "PlcTask", false, true, "The name to use for the PLC task to generate.",
+                "Task name:");
+    }
+
+    /**
+     * Returns the PLC task name.
+     *
+     * @return The PLC task name.
+     */
+    public static String getTaskName() {
+        return Options.get(PlcTaskNameOption.class);
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcTaskPriorityOption.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcTaskPriorityOption.java
new file mode 100644
index 0000000000000000000000000000000000000000..aca93cff97b572f214f52c42b1434f1684a64639
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/PlcTaskPriorityOption.java
@@ -0,0 +1,37 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.options;
+
+import org.eclipse.escet.common.app.framework.options.IntegerOption;
+import org.eclipse.escet.common.app.framework.options.Options;
+
+/** PLC task priority option. */
+public class PlcTaskPriorityOption extends IntegerOption {
+    /** Constructor for the {@link PlcTaskPriorityOption} class. */
+    public PlcTaskPriorityOption() {
+        super("PLC task priority",
+                "TASKPRIO is the priority of the task to generate, and must be in the range [0..65535]. [DEFAULT=20]",
+                'p', "task-prio", "TASKPRIO", 20, 0, 65535, 1, true, "The priority of the task to generate.",
+                "Priority:");
+    }
+
+    /**
+     * Returns the PLC task priority.
+     *
+     * @return The PLC task priority.
+     */
+    public static int getTaskPrio() {
+        return Options.get(PlcTaskPriorityOption.class);
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/RenameWarningsOption.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/RenameWarningsOption.java
new file mode 100644
index 0000000000000000000000000000000000000000..73a550af7d094a847e1c3b61f07ba58aaae6c203
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/RenameWarningsOption.java
@@ -0,0 +1,62 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.options;
+
+import org.eclipse.escet.common.app.framework.options.BooleanOption;
+import org.eclipse.escet.common.app.framework.options.Options;
+
+/** Rename warnings option. */
+public class RenameWarningsOption extends BooleanOption {
+    /** Constructor for the {@link RenameWarningsOption} class. */
+    public RenameWarningsOption() {
+        super(
+                // name
+                "Rename warnings",
+
+                // description
+                "Whether to print warnings to the console when a PLC name is renamed due to a conflict with another "
+                        + "PLC name (BOOL=yes), or omit the warnings (BOOL=no). [DEFAULT=no]",
+
+                // cmdShort
+                null,
+
+                // cmdLong
+                "warn-rename",
+
+                // cmdValue
+                "BOOL",
+
+                // defaultValue
+                false,
+
+                // showInDialog
+                true,
+
+                // optDialogDescr
+                "Whether to print warnings to the console when a PLC name is renamed due to a conflict with another "
+                        + "PLC name, or omit the warnings.",
+
+                // optDialogCheckboxText
+                "Print rename warnings");
+    }
+
+    /**
+     * Should rename warnings be printed to the console?
+     *
+     * @return {@code true} if rename warnings be printed to the console, {@code false} otherwise.
+     */
+    public static boolean isEnabled() {
+        return Options.get(RenameWarningsOption.class);
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/SimplifyValuesOption.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/SimplifyValuesOption.java
new file mode 100644
index 0000000000000000000000000000000000000000..975cae18bbc36013e45816433f34623e7f2872fd
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/options/SimplifyValuesOption.java
@@ -0,0 +1,35 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.options;
+
+import org.eclipse.escet.common.app.framework.options.BooleanOption;
+import org.eclipse.escet.common.app.framework.options.Options;
+
+/** Simplify values option. */
+public class SimplifyValuesOption extends BooleanOption {
+    /** Constructor for the {@link SimplifyValuesOption} class. */
+    public SimplifyValuesOption() {
+        super("Simplify values", "Whether the simplify values (BOOL=yes), or keep them as is (BOOL=no). [DEFAULT=yes]",
+                null, "simplify-values", "BOOL", true, true, "Should values be simplified?", "Simplify values");
+    }
+
+    /**
+     * Should values be simplified?
+     *
+     * @return {@code true} if values should be simplified, {@code false} otherwise.
+     */
+    public static boolean simplifyValues() {
+        return Options.get(SimplifyValuesOption.class);
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/targets/AbbTarget.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/targets/AbbTarget.java
index 4ab847b1a6764d39f88cc754673d3ae726188384..824f8ac759f5fec1fe6be9dbc1daf7c261a2fea8 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/targets/AbbTarget.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/targets/AbbTarget.java
@@ -13,11 +13,11 @@
 
 package org.eclipse.escet.cif.plcgen.targets;
 
-import org.eclipse.escet.cif.cif2plc.writers.OutputTypeWriter;
 import org.eclipse.escet.cif.plcgen.writers.AbbWriter;
+import org.eclipse.escet.cif.plcgen.writers.OutputTypeWriter;
 
 /** Code generator for the ABB PLC type. */
-public class AbbTarget extends PlcTarget {
+public class AbbTarget extends PlcBaseTarget {
     /** Constructor of the {@link AbbTarget} class. */
     public AbbTarget() {
         // TODO Verify settings of the ABB target.
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/targets/Iec611313Target.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/targets/Iec611313Target.java
index a099c2eb1f8c838dc5239480b0e711031843ff89..8bdc443f39ffda735de1402a7e269ae073866680 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/targets/Iec611313Target.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/targets/Iec611313Target.java
@@ -13,11 +13,11 @@
 
 package org.eclipse.escet.cif.plcgen.targets;
 
-import org.eclipse.escet.cif.cif2plc.writers.Iec611313Writer;
-import org.eclipse.escet.cif.cif2plc.writers.OutputTypeWriter;
+import org.eclipse.escet.cif.plcgen.writers.Iec611313Writer;
+import org.eclipse.escet.cif.plcgen.writers.OutputTypeWriter;
 
 /** Code generator for the IEC 61131-3 PLC type. */
-public class Iec611313Target extends PlcTarget {
+public class Iec611313Target extends PlcBaseTarget {
     /** Constructor of the {@link Iec611313Target} class. */
     public Iec611313Target() {
         super(PlcTargetType.IEC_61131_3);
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/targets/PlcBaseTarget.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/targets/PlcBaseTarget.java
new file mode 100644
index 0000000000000000000000000000000000000000..9a2fae839f4d027d27c1cd4b3f02fea8f7c4d277
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/targets/PlcBaseTarget.java
@@ -0,0 +1,248 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.targets;
+
+import org.eclipse.escet.cif.plcgen.PlcGenSettings;
+import org.eclipse.escet.cif.plcgen.conversion.ModelTextGenerator;
+import org.eclipse.escet.cif.plcgen.generators.CifProcessor;
+import org.eclipse.escet.cif.plcgen.generators.DefaultNameGenerator;
+import org.eclipse.escet.cif.plcgen.generators.DefaultTypeGenerator;
+import org.eclipse.escet.cif.plcgen.generators.DefaultVariableStorage;
+import org.eclipse.escet.cif.plcgen.generators.NameGenerator;
+import org.eclipse.escet.cif.plcgen.generators.PlcCodeStorage;
+import org.eclipse.escet.cif.plcgen.generators.TypeGenerator;
+import org.eclipse.escet.cif.plcgen.generators.VariableStorage;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcProject;
+import org.eclipse.escet.cif.plcgen.model.functions.PlcFuncOperation;
+import org.eclipse.escet.cif.plcgen.model.types.PlcElementaryType;
+import org.eclipse.escet.cif.plcgen.options.PlcNumberBits;
+import org.eclipse.escet.cif.plcgen.writers.OutputTypeWriter;
+
+/** Base class for generating a {@link PlcProject}. */
+public abstract class PlcBaseTarget implements PlcTarget {
+    /** Size of an integer value in a CIF specification. */
+    public static final int CIF_INTEGER_SIZE = 32;
+
+    /** Size of a real value in a CIF specification. */
+    public static final int CIF_REAL_SIZE = 64;
+
+    /** PLC target type for code generation. */
+    public final PlcTargetType targetType;
+
+    /** User-defined integer type size to use by the PLC. */
+    private PlcNumberBits intTypeSize;
+
+    /** User-defined real type size to use by the PLC. */
+    private PlcNumberBits realTypeSize;
+
+    /** Absolute base path to which to write the generated code. */
+    private String outputPath;
+
+    /** Conversion of PLC models to text for the target. */
+    private final ModelTextGenerator modelTextGenerator = new ModelTextGenerator();
+
+    /** Extracts information from the CIF input file, to be used during PLC code generation. */
+    private CifProcessor cifProcessor;
+
+    /** Handles storage and retrieval of globally used variables in the PLC program. */
+    private VariableStorage varStorage;
+
+    /** Handles type storage and conversions. */
+    private TypeGenerator typeGenerator;
+
+    /** Stores and writes generated PLC code. */
+    private PlcCodeStorage codeStorage;
+
+    /** Generate clash-free names in the generated code. */
+    private NameGenerator nameGenerator;
+
+    /**
+     * Constructor of the {@link PlcBaseTarget} class.
+     *
+     * @param targetType PLC target type for code generation.
+     */
+    public PlcBaseTarget(PlcTargetType targetType) {
+        this.targetType = targetType;
+    }
+
+    /**
+     * Initialize the target.
+     *
+     * @param settings Configuration to use.
+     */
+    public void setup(PlcGenSettings settings) {
+        intTypeSize = settings.intTypeSize;
+        realTypeSize = settings.realTypeSize;
+        outputPath = settings.outputPath;
+
+        // Warn the user about getting a possibly too small integer type size.
+        if (settings.intTypeSize.getTypeSize(CIF_INTEGER_SIZE) < CIF_INTEGER_SIZE) {
+            settings.warnOutput.warn(
+                    "Configured integer type size is less than the CIF integer type size. Some values in the program "
+                            + "may be truncated.");
+        } else if (getMaxIntegerTypeSize() < CIF_INTEGER_SIZE) {
+            settings.warnOutput
+                    .warn("Maximum integer type size supported by the PLC is less than the CIF integer type size. Some "
+                            + "values in the program may be truncated.");
+        }
+
+        // Warn the user about getting a possibly too small real type size.
+        if (settings.realTypeSize.getTypeSize(CIF_REAL_SIZE) < CIF_REAL_SIZE) {
+            settings.warnOutput
+                    .warn("Configured real type size is less than the CIF real type size. Some values in the program "
+                            + "may be truncated.");
+        } else if (getMaxRealTypeSize() < CIF_REAL_SIZE) {
+            settings.warnOutput
+                    .warn("Maximum real type size supported by the PLC is less than the CIF real type size. Some "
+                            + "values in the program may be truncated.");
+        }
+    }
+
+    /**
+     * Generate and write the PLC code.
+     *
+     * @param settings Configuration to use.
+     */
+    public void generate(PlcGenSettings settings) {
+        setup(settings);
+
+        nameGenerator = new DefaultNameGenerator(settings);
+        codeStorage = new PlcCodeStorage(this, settings);
+        typeGenerator = new DefaultTypeGenerator(this, settings);
+        varStorage = new DefaultVariableStorage(this);
+        cifProcessor = new CifProcessor(this, settings);
+
+        // Check and normalize the CIF specification, and extract relevant information from it.
+        cifProcessor.process();
+        if (settings.shouldTerminate.get()) {
+            return;
+        }
+
+        // Make the globally used variables ready for use in the PLC code.
+        varStorage.process();
+        if (settings.shouldTerminate.get()) {
+            return;
+        }
+
+        // Prepare the PLC program for getting saved to the file system.
+        codeStorage.finishPlcProgram();
+        if (settings.shouldTerminate.get()) {
+            return;
+        }
+
+        // And write it.
+        codeStorage.writeOutput();
+    }
+
+    /**
+     * Get the writer for writing the generated PLC code to the file system.
+     *
+     * @return The requested PLC code writer.
+     */
+    protected abstract OutputTypeWriter getPlcCodeWriter();
+
+    @Override
+    public PlcTargetType getTargetType() {
+        return targetType;
+    }
+
+    @Override
+    public ModelTextGenerator getModelTextGenerator() {
+        return modelTextGenerator;
+    }
+
+    @Override
+    public CifProcessor getCifProcessor() {
+        return cifProcessor;
+    }
+
+    @Override
+    public VariableStorage getVarStorage() {
+        return varStorage;
+    }
+
+    @Override
+    public TypeGenerator getTypeGenerator() {
+        return typeGenerator;
+    }
+
+    @Override
+    public PlcCodeStorage getCodeStorage() {
+        return codeStorage;
+    }
+
+    @Override
+    public NameGenerator getNameGenerator() {
+        return nameGenerator;
+    }
+
+    @Override
+    public abstract boolean supportsArrays();
+
+    @Override
+    public abstract boolean supportsConstants();
+
+    @Override
+    public abstract boolean supportsEnumerations();
+
+    @Override
+    public boolean supportsOperation(PlcFuncOperation funcOper) {
+        // By default the operation is supported.
+        return true;
+    }
+
+    @Override
+    public boolean supportsInfixNotation(PlcFuncOperation funcOper) {
+        return true;
+    }
+
+    @Override
+    public boolean supportsPower(boolean baseIsInt, boolean exponentIsInt) {
+        return !baseIsInt; // First parameter must always have a real type.
+    }
+
+    /**
+     * Get the size of the largest supported integer type.
+     *
+     * @return Number of bits used for storing the largest supported integer type.
+     */
+    protected abstract int getMaxIntegerTypeSize();
+
+    @Override
+    public PlcElementaryType getIntegerType() {
+        int generatorBestIntSize = Math.min(CIF_INTEGER_SIZE, getMaxIntegerTypeSize());
+        int userSpecifiedIntSize = intTypeSize.getTypeSize(generatorBestIntSize);
+        return PlcElementaryType.getIntTypeBySize(userSpecifiedIntSize);
+    }
+
+    /**
+     * Get the size of the largest supported real type.
+     *
+     * @return Number of bits used for storing the largest supported real type.
+     */
+    protected abstract int getMaxRealTypeSize();
+
+    @Override
+    public PlcElementaryType getRealType() {
+        int generatorBestRealSize = Math.min(CIF_REAL_SIZE, getMaxRealTypeSize());
+        int userSpecifiedRealSize = realTypeSize.getTypeSize(generatorBestRealSize);
+        return PlcElementaryType.getRealTypeBySize(userSpecifiedRealSize);
+    }
+
+    @Override
+    public void writeOutput(PlcProject project) {
+        OutputTypeWriter writer = getPlcCodeWriter();
+        writer.write(project, outputPath);
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/targets/PlcOpenXmlTarget.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/targets/PlcOpenXmlTarget.java
index 63821caac170083e742930ca90073dc41f716cc9..ca0d1ad48ffacd0c29f75639ed481133edbc8fe0 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/targets/PlcOpenXmlTarget.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/targets/PlcOpenXmlTarget.java
@@ -13,11 +13,11 @@
 
 package org.eclipse.escet.cif.plcgen.targets;
 
-import org.eclipse.escet.cif.cif2plc.writers.OutputTypeWriter;
-import org.eclipse.escet.cif.cif2plc.writers.PlcOpenXmlWriter;
+import org.eclipse.escet.cif.plcgen.writers.OutputTypeWriter;
+import org.eclipse.escet.cif.plcgen.writers.PlcOpenXmlWriter;
 
 /** Code generator for the PLCopen XML PLC type. */
-public class PlcOpenXmlTarget extends PlcTarget {
+public class PlcOpenXmlTarget extends PlcBaseTarget {
     /** Constructor of the {@link PlcOpenXmlTarget} class. */
     public PlcOpenXmlTarget() {
         super(PlcTargetType.PLC_OPEN_XML);
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/targets/PlcTarget.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/targets/PlcTarget.java
index ccf1f09082722bbbbeef1bf433a08d9236758400..9321e87a576a45dcb04e974cd3f3e16e18959b37 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/targets/PlcTarget.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/targets/PlcTarget.java
@@ -1,5 +1,5 @@
 //////////////////////////////////////////////////////////////////////////////
-// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
 //
 // See the NOTICE file(s) distributed with this work for additional
 // information regarding copyright ownership.
@@ -13,99 +13,66 @@
 
 package org.eclipse.escet.cif.plcgen.targets;
 
-import org.eclipse.escet.cif.cif2plc.options.PlcNumberBits;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcElementaryType;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcProject;
-import org.eclipse.escet.cif.cif2plc.writers.OutputTypeWriter;
-import org.eclipse.escet.cif.plcgen.PlcGenSettings;
+import org.eclipse.escet.cif.plcgen.conversion.ModelTextGenerator;
 import org.eclipse.escet.cif.plcgen.generators.CifProcessor;
 import org.eclipse.escet.cif.plcgen.generators.NameGenerator;
 import org.eclipse.escet.cif.plcgen.generators.PlcCodeStorage;
 import org.eclipse.escet.cif.plcgen.generators.TypeGenerator;
+import org.eclipse.escet.cif.plcgen.generators.VariableStorage;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcProject;
+import org.eclipse.escet.cif.plcgen.model.functions.PlcFuncOperation;
+import org.eclipse.escet.cif.plcgen.model.types.PlcElementaryType;
 
-/** Base class for generating a {@link PlcProject}. */
-public abstract class PlcTarget {
-    /** Size of an integer value in a CIF specification. */
-    public static final int CIF_INTEGER_SIZE = 32;
-
-    /** Size of a real value in a CIF specification. */
-    public static final int CIF_REAL_SIZE = 64;
-
-    /** PLC target type for code generation. */
-    public final PlcTargetType targetType;
-
-    /** User-defined integer type size to use by the PLC. */
-    private PlcNumberBits intTypeSize;
-
-    /** User-defined real type size to use by the PLC. */
-    private PlcNumberBits realTypeSize;
-
+/** Code generator interface for a {@link PlcBaseTarget}. */
+public interface PlcTarget {
     /**
-     * Constructor of the {@link PlcTarget} class.
+     * Obtain the target type of the target.
      *
-     * @param targetType PLC target type for code generation.
+     * @return The target type of the target.
      */
-    public PlcTarget(PlcTargetType targetType) {
-        this.targetType = targetType;
-    }
+    public abstract PlcTargetType getTargetType();
 
     /**
-     * Generate and write the PLC code.
+     * Retrieve the converter of the PLC model classes to their textual equivalent.
      *
-     * @param settings Configuration to use.
+     * @return The text generator for the PLC model classes.
      */
-    public void generate(PlcGenSettings settings) {
-        intTypeSize = settings.intTypeSize;
-        realTypeSize = settings.realTypeSize;
-
-        // Construct the generators.
-        NameGenerator nameGenerator = new NameGenerator(settings);
-        PlcCodeStorage codeStorage = new PlcCodeStorage(this, settings);
-        TypeGenerator typeGen = new TypeGenerator(this, settings, nameGenerator, codeStorage);
-        CifProcessor cifProcessor = new CifProcessor(this, settings, typeGen, codeStorage, nameGenerator);
+    public abstract ModelTextGenerator getModelTextGenerator();
 
-        // Warn the user about getting a possibly too small integer type size.
-        if (settings.intTypeSize.getTypeSize(PlcTarget.CIF_INTEGER_SIZE) < PlcTarget.CIF_INTEGER_SIZE) {
-            settings.warnOutput.warn(
-                    "Configured integer type size is less than the CIF integer type size. Some values in the program "
-                            + "may be truncated.");
-        } else if (getMaxIntegerTypeSize() < PlcTarget.CIF_INTEGER_SIZE) {
-            settings.warnOutput
-                    .warn("Maximum integer type size supported by the PLC is less than the CIF integer type size. Some "
-                            + "values in the program may be truncated.");
-        }
-
-        // Warn the user about getting a possibly too small real type size.
-        if (settings.realTypeSize.getTypeSize(PlcTarget.CIF_REAL_SIZE) < PlcTarget.CIF_REAL_SIZE) {
-            settings.warnOutput
-                    .warn("Configured real type size is less than the CIF real type size. Some values in the program "
-                            + "may be truncated.");
-        } else if (getMaxRealTypeSize() < PlcTarget.CIF_REAL_SIZE) {
-            settings.warnOutput
-                    .warn("Maximum real type size supported by the PLC is less than the CIF real type size. Some "
-                            + "values in the program may be truncated.");
-        }
+    /**
+     * Retrieve the CIF processor.
+     *
+     * @return The CIF processor.
+     */
+    public abstract CifProcessor getCifProcessor();
 
-        // Perform the conversion.
-        cifProcessor.process();
-        if (settings.shouldTerminate.get()) {
-            return;
-        }
+    /**
+     * Retrieve the variable storage.
+     *
+     * @return The variable storage.
+     */
+    public abstract VariableStorage getVarStorage();
 
-        codeStorage.finishPlcProgram();
-        if (settings.shouldTerminate.get()) {
-            return;
-        }
+    /**
+     * Retrieve the type generator.
+     *
+     * @return The type generator.
+     */
+    public abstract TypeGenerator getTypeGenerator();
 
-        codeStorage.writeOutput();
-    }
+    /**
+     * Retrieve the PLC code storage.
+     *
+     * @return The PLC code storage.
+     */
+    public abstract PlcCodeStorage getCodeStorage();
 
     /**
-     * Get the writer for writing the generated PLC code to the file system.
+     * Retrieve the name generator.
      *
-     * @return The requested PLC code writer.
+     * @return The name generator.
      */
-    public abstract OutputTypeWriter getPlcCodeWriter();
+    public abstract NameGenerator getNameGenerator();
 
     /**
      * Returns whether the target supports arrays.
@@ -129,40 +96,48 @@ public abstract class PlcTarget {
     public abstract boolean supportsEnumerations();
 
     /**
-     * Get the size of the largest supported integer type.
+     * Does the target support the given semantic operation?
      *
-     * @return Number of bits used for storing the largest supported integer type.
+     * @param funcOper Semantics operation being queried.
+     * @return Whether the target supports the given operation.
      */
-    protected abstract int getMaxIntegerTypeSize();
+    public abstract boolean supportsOperation(PlcFuncOperation funcOper);
 
     /**
-     * Get the type of a standard integer value in the PLC.
+     * Does the target support infix notation for the given semantic operation?
      *
-     * @return The type of a standard integer value in the PLC.
+     * @param funcOper Semantics operation being queried.
+     * @return Whether the target support infix notation for the given operation.
+     * @note The result is undefined for operations that are not supported by the target and for operations that do not
+     *     have an infix notation.
      */
-    public PlcElementaryType getIntegerType() {
-        int generatorBestIntSize = Math.min(CIF_INTEGER_SIZE, getMaxIntegerTypeSize());
-        int userSpecifiedIntSize = intTypeSize.getTypeSize(generatorBestIntSize);
-        return PlcElementaryType.getIntTypeBySize(userSpecifiedIntSize);
-    }
+    public abstract boolean supportsInfixNotation(PlcFuncOperation funcOper);
 
     /**
-     * Get the size of the largest supported real type.
+     * Query whether the power function {@code base ** exponent} exists for a given combination of parameter types.
      *
-     * @return Number of bits used for storing the largest supported real type.
+     * @param baseIsInt If {@code true} the test queries for an integer typed base value. If {@code false} the test
+     *     queries for a real typed base value.
+     * @param exponentIsInt If {@code true} the test queries for an integer typed exponent value. If {@code false} the
+     *     test queries for a real typed exponent value.
+     * @return Whether the queried combination of base and exponent value types is supported by the PLC.
+     * @note It is assumed that {@code supportsPower(false, false)} holds.
      */
-    protected abstract int getMaxRealTypeSize();
+    public abstract boolean supportsPower(boolean baseIsInt, boolean exponentIsInt);
+
+    /**
+     * Get the type of a standard integer value in the PLC.
+     *
+     * @return The type of a standard integer value in the PLC.
+     */
+    public abstract PlcElementaryType getIntegerType();
 
     /**
      * Get the type of a standard real value in the PLC.
      *
      * @return The type of a standard real value in the PLC.
      */
-    public PlcElementaryType getRealType() {
-        int generatorBestRealSize = Math.min(CIF_REAL_SIZE, getMaxRealTypeSize());
-        int userSpecifiedRealSize = realTypeSize.getTypeSize(generatorBestRealSize);
-        return PlcElementaryType.getRealTypeBySize(userSpecifiedRealSize);
-    }
+    public abstract PlcElementaryType getRealType();
 
     /**
      * Get replacement string for the CIF input file extension including dot, used to derive an output path.
@@ -170,4 +145,12 @@ public abstract class PlcTarget {
      * @return The replacement string.
      */
     public abstract String getPathSuffixReplacement();
+
+    /**
+     * Write the project to the output.
+     *
+     * @param project Project to write.
+     * @note Depending on the actual write implementation a single file or a directory may be written.
+     */
+    void writeOutput(PlcProject project);
 }
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/targets/SiemensS7Target.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/targets/SiemensS7Target.java
index 761f2152cabc791b8cc071b1631705a3eabb6e7a..5be2db7ef09b3457a4c475491f05e3ee34e7170d 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/targets/SiemensS7Target.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/targets/SiemensS7Target.java
@@ -13,14 +13,16 @@
 
 package org.eclipse.escet.cif.plcgen.targets;
 
+import java.util.EnumSet;
 import java.util.Map;
 
-import org.eclipse.escet.cif.cif2plc.writers.OutputTypeWriter;
+import org.eclipse.escet.cif.plcgen.model.functions.PlcFuncOperation;
+import org.eclipse.escet.cif.plcgen.writers.OutputTypeWriter;
 import org.eclipse.escet.cif.plcgen.writers.S7Writer;
 import org.eclipse.escet.common.java.Assert;
 
 /** Code generator for Siemens S7-300, S7-400, S7-1200, and S7-1500 PLC types. */
-public class SiemensS7Target extends PlcTarget {
+public class SiemensS7Target extends PlcBaseTarget {
     /** Replacement strings for the extension in the CIF input file name to construct an output path for each target. */
     private static final Map<PlcTargetType, String> OUT_SUFFIX_REPLACEMENTS;
 
@@ -78,6 +80,22 @@ public class SiemensS7Target extends PlcTarget {
         return false;
     }
 
+    @Override
+    public boolean supportsPower(boolean baseIsInt, boolean exponentIsInt) {
+        // S7-400 and S7-300 only support power on real types.
+        if (EnumSet.of(PlcTargetType.S7_300, PlcTargetType.S7_400).contains(targetType)) {
+            return !baseIsInt && !exponentIsInt;
+        } else {
+            return super.supportsPower(baseIsInt, exponentIsInt);
+        }
+    }
+
+    @Override
+    public boolean supportsOperation(PlcFuncOperation funcOper) {
+        // S7 doesn't have a function for log10.
+        return funcOper != PlcFuncOperation.STDLIB_LOG;
+    }
+
     @Override
     public int getMaxIntegerTypeSize() {
         return MAX_INTEGER_SIZES.get(targetType);
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/targets/TwinCatTarget.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/targets/TwinCatTarget.java
index e7395f0e62de84314e12030f5c6167b949510615..2f3a6463cc489b1af862945167f7bd9c50b82b5f 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/targets/TwinCatTarget.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/targets/TwinCatTarget.java
@@ -13,11 +13,12 @@
 
 package org.eclipse.escet.cif.plcgen.targets;
 
-import org.eclipse.escet.cif.cif2plc.writers.OutputTypeWriter;
-import org.eclipse.escet.cif.cif2plc.writers.TwinCatWriter;
+import org.eclipse.escet.cif.plcgen.model.functions.PlcFuncOperation;
+import org.eclipse.escet.cif.plcgen.writers.OutputTypeWriter;
+import org.eclipse.escet.cif.plcgen.writers.TwinCatWriter;
 
 /** Code generator for the TwinCAT PLC type. */
-public class TwinCatTarget extends PlcTarget {
+public class TwinCatTarget extends PlcBaseTarget {
     /** Constructor of the {@link TwinCatTarget} class. */
     public TwinCatTarget() {
         super(PlcTargetType.TWINCAT);
@@ -43,6 +44,12 @@ public class TwinCatTarget extends PlcTarget {
         return true;
     }
 
+    @Override
+    public boolean supportsInfixNotation(PlcFuncOperation funcOper) {
+        // The 'a ** b' syntax seemed not to work in TwinCAT 3.1. Use the named function instead.
+        return funcOper != PlcFuncOperation.POWER_OP;
+    }
+
     @Override
     public int getMaxIntegerTypeSize() {
         return 64;
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/writers/AbbWriter.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/writers/AbbWriter.java
index 741773665e9a262b9ad5cd5e651f586c1b5d54e4..15ecab3df4198de280f4e558dbb07caa5351b8d9 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/writers/AbbWriter.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/writers/AbbWriter.java
@@ -13,11 +13,10 @@
 
 package org.eclipse.escet.cif.plcgen.writers;
 
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcConfiguration;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcPou;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcProject;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcTypeDecl;
-import org.eclipse.escet.cif.cif2plc.writers.OutputTypeWriter;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcConfiguration;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcPou;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcProject;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcTypeDecl;
 import org.eclipse.escet.common.app.framework.Paths;
 import org.eclipse.escet.common.box.Box;
 
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/writers/Iec611313Writer.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/writers/Iec611313Writer.java
new file mode 100644
index 0000000000000000000000000000000000000000..4bf72f063c6b37c08bd6c052230fb7258afdc495
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/writers/Iec611313Writer.java
@@ -0,0 +1,81 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.writers;
+
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcConfiguration;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcPou;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcProject;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcTypeDecl;
+import org.eclipse.escet.common.app.framework.Paths;
+import org.eclipse.escet.common.box.Box;
+
+/** IEC 61131-3 writer. */
+public class Iec611313Writer extends OutputTypeWriter {
+    @Override
+    public void write(PlcProject project, String outPath) {
+        ensureDirectory(outPath);
+
+        // Write configurations.
+        for (PlcConfiguration config: project.configurations) {
+            write(config, outPath);
+        }
+
+        // Write POUs.
+        for (PlcPou pou: project.pous) {
+            write(pou, outPath);
+        }
+
+        // Write type declarations.
+        for (PlcTypeDecl typeDecl: project.typeDecls) {
+            write(typeDecl, outPath);
+        }
+    }
+
+    /**
+     * Writes the given configuration to a file in IEC 61131-3 syntax.
+     *
+     * @param config The configuration to write.
+     * @param outPath The absolute local file system path of the directory to which to write the file.
+     */
+    private void write(PlcConfiguration config, String outPath) {
+        String path = Paths.join(outPath, config.name + ".plccfg");
+        Box code = toBox(config);
+        code.writeToFile(path);
+    }
+
+    /**
+     * Writes the given POU to a file in IEC 61131-3 syntax.
+     *
+     * @param pou The POU to write.
+     * @param outPath The absolute local file system path of the directory to which to write the file.
+     */
+    private void write(PlcPou pou, String outPath) {
+        String ext = (pou.retType == null) ? ".plcprog" : ".plcfunc";
+        String path = Paths.join(outPath, pou.name + ext);
+        Box code = toBox(pou);
+        code.writeToFile(path);
+    }
+
+    /**
+     * Writes the given type declaration to a file in IEC 61131-3 syntax.
+     *
+     * @param typeDecl The type declaration to write.
+     * @param outPath The absolute local file system path of the directory to which to write the file.
+     */
+    private void write(PlcTypeDecl typeDecl, String outPath) {
+        String path = Paths.join(outPath, typeDecl.name + ".plctype");
+        Box code = toBox(typeDecl);
+        code.writeToFile(path);
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/writers/OutputTypeWriter.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/writers/OutputTypeWriter.java
new file mode 100644
index 0000000000000000000000000000000000000000..c728bcece0d7991623e29b9976eae0c079375c7b
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/writers/OutputTypeWriter.java
@@ -0,0 +1,403 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2022, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.writers;
+
+import static org.eclipse.escet.common.java.Strings.fmt;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcConfiguration;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcGlobalVarList;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcPou;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcPouInstance;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcProject;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcResource;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcTask;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcTypeDecl;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcVariable;
+import org.eclipse.escet.cif.plcgen.model.expressions.PlcValue;
+import org.eclipse.escet.cif.plcgen.model.types.PlcArrayType;
+import org.eclipse.escet.cif.plcgen.model.types.PlcDerivedType;
+import org.eclipse.escet.cif.plcgen.model.types.PlcElementaryType;
+import org.eclipse.escet.cif.plcgen.model.types.PlcEnumType;
+import org.eclipse.escet.cif.plcgen.model.types.PlcStructType;
+import org.eclipse.escet.cif.plcgen.model.types.PlcType;
+import org.eclipse.escet.common.app.framework.Paths;
+import org.eclipse.escet.common.app.framework.exceptions.InputOutputException;
+import org.eclipse.escet.common.box.Box;
+import org.eclipse.escet.common.box.CodeBox;
+import org.eclipse.escet.common.box.HBox;
+import org.eclipse.escet.common.box.MemoryCodeBox;
+import org.eclipse.escet.common.box.TextBox;
+import org.eclipse.escet.common.java.Assert;
+
+/** Base class for writing PLC code for a given output type. */
+public abstract class OutputTypeWriter {
+    /** The indentation to use for the Structured Text files. */
+    public static final int INDENT = 4;
+
+    /**
+     * Convert the project contents to output acceptable for a PLC output type.
+     *
+     * @param project PLC program code to convert.
+     * @param outputPath The absolute local file system destination to write the converted output.
+     */
+    public abstract void write(PlcProject project, String outputPath);
+
+    /**
+     * Ensure a directory with the given path exists, possibly by creating it.
+     *
+     * @param outPath Path to the directory that should exist after the call.
+     */
+    protected void ensureDirectory(String outPath) {
+        String absPath = Paths.resolve(outPath);
+        Path nioAbsPath = java.nio.file.Paths.get(absPath);
+        if (!Files.isDirectory(nioAbsPath)) {
+            try {
+                Files.createDirectories(nioAbsPath);
+            } catch (IOException ex) {
+                String msg = fmt("Failed to create output directory \"%s\" for the generated PLC code.", outPath);
+                throw new InputOutputException(msg, ex);
+            }
+        }
+    }
+
+    /**
+     * Convert a {@link PlcProject} instance to a {@link Box} text.
+     *
+     * @param project Project to convert.
+     * @return The generated box representation.
+     */
+    protected Box toBox(PlcProject project) {
+        // IEC 61131-3 has no projects, so this syntax is not standard
+        // compliant.
+        CodeBox c = new MemoryCodeBox(INDENT);
+        c.add("PROJECT %s", project.name);
+        c.indent();
+        for (PlcTypeDecl typeDecl: project.typeDecls) {
+            c.add(toBox(typeDecl));
+        }
+        for (PlcPou pou: project.pous) {
+            c.add(toBox(pou));
+        }
+        for (PlcConfiguration configuration: project.configurations) {
+            c.add(toBox(configuration));
+        }
+        c.dedent();
+        c.add("END_PROJECT");
+        return c;
+    }
+
+    /**
+     * Convert a {@link PlcConfiguration} instance to a {@link Box} text.
+     *
+     * @param configuration Configuration to convert.
+     * @return The generated box representation.
+     */
+    protected Box toBox(PlcConfiguration configuration) {
+        CodeBox c = new MemoryCodeBox(INDENT);
+        c.add("CONFIGURATION %s", configuration.name);
+        c.indent();
+        for (PlcGlobalVarList globalVarList: configuration.globalVarLists) {
+            if (globalVarList.variables.isEmpty()) {
+                continue;
+            }
+            c.add(toBox(globalVarList));
+        }
+
+        // Ensure one resource. At least one is required. More resources, means
+        // we have to use 'RESOURCE <name> ON <type>' syntax, and we don't
+        // want to specify the <type>.
+        Assert.check(configuration.resources.size() <= 1);
+        for (PlcResource resource: configuration.resources) {
+            c.add(toBox(resource));
+        }
+
+        c.dedent();
+        c.add("END_CONFIGURATION");
+        return c;
+    }
+
+    /**
+     * Convert a {@link PlcTask} instance to a {@link Box} text.
+     *
+     * @param task Task to convert.
+     * @return The generated box representation.
+     */
+    protected Box toBox(PlcTask task) {
+        // POU instances are boxed by the PLC resource.
+        return new TextBox("TASK %s(INTERVAL := t#%dms, PRIORITY := %d);", task.name, task.cycleTime, task.priority);
+    }
+
+    /**
+     * Convert a {@link PlcResource} instance to a {@link Box} text.
+     *
+     * @param resource Resource to convert.
+     * @return The generated box representation.
+     */
+    protected Box toBox(PlcResource resource) {
+        // We only support a single resource for now, so the 'name' is not
+        // included in the box representation, to avoid having to specify a
+        // resource type name.
+        CodeBox c = new MemoryCodeBox(INDENT);
+        for (PlcGlobalVarList globalVarList: resource.globalVarLists) {
+            if (globalVarList.variables.isEmpty()) {
+                continue;
+            }
+            c.add(toBox(globalVarList));
+        }
+        for (PlcTask task: resource.tasks) {
+            c.add(toBox(task));
+        }
+        for (PlcPouInstance pouInstance: resource.pouInstances) {
+            c.add(toBox(pouInstance, null));
+        }
+        for (PlcTask task: resource.tasks) {
+            for (PlcPouInstance pouInstance: task.pouInstances) {
+                c.add(toBox(pouInstance, task.name));
+            }
+        }
+        return c;
+    }
+
+    /**
+     * Convert a {@link PlcGlobalVarList} instance to a {@link Box} text.
+     *
+     * @param globVarList Global variable list to convert.
+     * @return The generated box representation.
+     */
+    protected Box toBox(PlcGlobalVarList globVarList) {
+        Assert.check(!globVarList.variables.isEmpty()); // Empty VAR_GLOBAL is illegal.
+        CodeBox c = new MemoryCodeBox(INDENT);
+        c.add("VAR_GLOBAL%s // %s", globVarList.constants ? " CONSTANT" : "", globVarList.name);
+        c.indent();
+        for (PlcVariable variable: globVarList.variables) {
+            c.add(toBox(variable));
+        }
+        c.dedent();
+        c.add("END_VAR");
+        return c;
+    }
+
+    /**
+     * Convert a {@link PlcVariable} instance to a {@link Box} text.
+     *
+     * @param variable Variable to convert.
+     * @return The generated box representation.
+     */
+    protected Box toBox(PlcVariable variable) {
+        String addrTxt = (variable.address == null) ? "" : fmt(" AT %s", variable.address);
+        String valueTxt = (variable.value == null) ? "" : fmt(" := %s", toBox(variable.value));
+        String txt = fmt("%s%s: %s%s;", variable.name, addrTxt, toBox(variable.type), valueTxt);
+        return new TextBox(txt);
+    }
+
+    /**
+     * Convert a {@link PlcPouInstance} instance to a {@link Box} text.
+     *
+     * @param pouInstance POU instance to convert.
+     * @return The generated box representation.
+     */
+    protected Box toBox(PlcPouInstance pouInstance) {
+        return toBox(pouInstance, null);
+    }
+
+    /**
+     * Returns a {@link Box} representation of the {@link PlcPouInstance} object.
+     *
+     * @param pouInstance POU instance to convert.
+     * @param taskName The name of the task on which to instantiate the POU, or {@code null} if not applicable.
+     * @return The generated box representation.
+     */
+    protected Box toBox(PlcPouInstance pouInstance, String taskName) {
+        String taskTxt = (taskName == null) ? "" : fmt(" WITH %s", taskName);
+        return new TextBox("PROGRAM %s%s: %s;", pouInstance.name, taskTxt, pouInstance.pou.name);
+    }
+
+    /**
+     * Convert a {@link PlcPou} instance to a {@link Box} text.
+     *
+     * @param pou POU to convert.
+     * @return The generated box representation.
+     */
+    protected Box toBox(PlcPou pou) {
+        CodeBox c = headerToBox(pou);
+        c.add();
+        c.add(pou.body);
+        c.add("END_%s", pou.pouType);
+        return c;
+    }
+
+    /**
+     * Converts the header of the POU to IEC 61131-3 syntax. The header includes the POU type, name, return type, and
+     * variables, but neither the body nor the final closing keyword.
+     *
+     * @param pou POU header to convert.
+     * @return The header of the POU in IEC 61131-3 syntax.
+     */
+    protected CodeBox headerToBox(PlcPou pou) {
+        CodeBox c = new MemoryCodeBox(INDENT);
+        String retTypeTxt = (pou.retType == null) ? "" : fmt(": %s", toBox(pou.retType));
+        c.add("%s %s%s", pou.pouType, pou.name, retTypeTxt);
+        if (!pou.inputVars.isEmpty()) {
+            c.add("VAR_INPUT");
+            c.indent();
+            for (PlcVariable var: pou.inputVars) {
+                c.add(toBox(var));
+            }
+            c.dedent();
+            c.add("END_VAR");
+        }
+        if (!pou.outputVars.isEmpty()) {
+            c.add("VAR_OUTPUT");
+            c.indent();
+            for (PlcVariable var: pou.outputVars) {
+                c.add(toBox(var));
+            }
+            c.dedent();
+            c.add("END_VAR");
+        }
+        if (!pou.localVars.isEmpty()) {
+            c.add("VAR");
+            c.indent();
+            for (PlcVariable var: pou.localVars) {
+                c.add(toBox(var));
+            }
+            c.dedent();
+            c.add("END_VAR");
+        }
+        if (!pou.tempVars.isEmpty()) {
+            c.add("VAR_TEMP");
+            c.indent();
+            for (PlcVariable var: pou.tempVars) {
+                c.add(toBox(var));
+            }
+            c.dedent();
+            c.add("END_VAR");
+        }
+        return c;
+    }
+
+    /**
+     * Convert a {@link PlcValue} instance to a {@link Box} text.
+     *
+     * @param value Value to convert.
+     * @return The generated box representation.
+     */
+    protected Box toBox(PlcValue value) {
+        return new TextBox(value.value);
+    }
+
+    /**
+     * Convert a {@link PlcType} instance to a {@link Box} text.
+     *
+     * @param type Type to convert.
+     * @return The generated box representation.
+     */
+    protected Box toBox(PlcType type) {
+        if (type instanceof PlcArrayType) {
+            return toBox((PlcArrayType)type);
+        } else if (type instanceof PlcDerivedType) {
+            return toBox((PlcDerivedType)type);
+        } else if (type instanceof PlcElementaryType) {
+            return toBox((PlcElementaryType)type);
+        } else if (type instanceof PlcEnumType) {
+            return toBox((PlcEnumType)type);
+        } else if (type instanceof PlcStructType) {
+            return toBox((PlcStructType)type);
+        } else {
+            String typeText = (type == null) ? "null" : type.getClass().toString();
+            throw new AssertionError("Unexpected PlcType, found: " + typeText + ".");
+        }
+    }
+
+    /**
+     * Convert a {@link PlcTypeDecl} instance to a {@link Box} text.
+     *
+     * @param typeDecl Type declaration to convert.
+     * @return The generated box representation.
+     */
+    protected Box toBox(PlcTypeDecl typeDecl) {
+        CodeBox c = new MemoryCodeBox(INDENT);
+        c.add("TYPE %s:", typeDecl.name);
+        c.indent();
+        c.add(new HBox(toBox(typeDecl.type), ";"));
+        c.dedent();
+        c.add("END_TYPE");
+        return c;
+    }
+
+    /**
+     * Convert a {@link PlcEnumType} instance to a {@link Box} text.
+     *
+     * @param enumType Enumeration type to convert.
+     * @return The generated box representation.
+     */
+    protected Box toBox(PlcEnumType enumType) {
+        return new TextBox("(%s)", String.join(", ", enumType.literals));
+    }
+
+    /**
+     * Convert a {@link PlcElementaryType} instance to a {@link Box} text.
+     *
+     * @param elementaryType Elementary type to convert.
+     * @return The generated box representation.
+     */
+    protected Box toBox(PlcElementaryType elementaryType) {
+        return new TextBox(elementaryType.name);
+    }
+
+    /**
+     * Convert a {@link PlcDerivedType} instance to a {@link Box} text.
+     *
+     * @param derivedType Derived type to convert.
+     * @return The generated box representation.
+     */
+    protected Box toBox(PlcDerivedType derivedType) {
+        return new TextBox(derivedType.name);
+    }
+
+    /**
+     * Convert a {@link PlcArrayType} instance to a {@link Box} text.
+     *
+     * @param arrayType Array type to convert.
+     * @return The generated box representation.
+     */
+    protected Box toBox(PlcArrayType arrayType) {
+        HBox b = new HBox();
+        b.add(fmt("ARRAY[%d..%d] of ", arrayType.lower, arrayType.upper));
+        b.add(toBox(arrayType.elemType));
+        return b;
+    }
+
+    /**
+     * Convert a {@link PlcStructType} instance to a {@link Box} text.
+     *
+     * @param structType Struct type to convert.
+     * @return The generated box representation.
+     */
+    protected Box toBox(PlcStructType structType) {
+        CodeBox c = new MemoryCodeBox(INDENT);
+        c.add("STRUCT");
+        c.indent();
+        for (PlcVariable field: structType.fields) {
+            c.add(toBox(field));
+        }
+        c.dedent();
+        c.add("END_STRUCT");
+        return c;
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/writers/PlcOpenXmlWriter.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/writers/PlcOpenXmlWriter.java
new file mode 100644
index 0000000000000000000000000000000000000000..24a3354a10907b6767817ba79d04df9e31650539
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/writers/PlcOpenXmlWriter.java
@@ -0,0 +1,628 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.writers;
+
+import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
+import static org.eclipse.escet.common.java.Strings.fmt;
+import static org.eclipse.escet.common.java.Strings.str;
+
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.time.Instant;
+import java.time.format.DateTimeFormatter;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import javax.xml.validation.Validator;
+
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcConfiguration;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcGlobalVarList;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcPou;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcPouInstance;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcProject;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcResource;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcTask;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcTypeDecl;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcVariable;
+import org.eclipse.escet.cif.plcgen.model.expressions.PlcValue;
+import org.eclipse.escet.cif.plcgen.model.types.PlcArrayType;
+import org.eclipse.escet.cif.plcgen.model.types.PlcDerivedType;
+import org.eclipse.escet.cif.plcgen.model.types.PlcElementaryType;
+import org.eclipse.escet.cif.plcgen.model.types.PlcEnumType;
+import org.eclipse.escet.cif.plcgen.model.types.PlcStructType;
+import org.eclipse.escet.cif.plcgen.model.types.PlcType;
+import org.eclipse.escet.common.app.framework.Paths;
+import org.eclipse.escet.common.app.framework.exceptions.InputOutputException;
+import org.eclipse.escet.common.box.CodeBox;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+/** PLCopen XML (version 2.01) writer. */
+public class PlcOpenXmlWriter extends OutputTypeWriter {
+    /** PLCopen XML version namespace URI. */
+    private static final String PLCOPEN_NS = "http://www.plcopen.org/xml/tc6_0201";
+
+    /** XHTML namespace URI. */
+    private static final String XHTML_NS = "http://www.w3.org/1999/xhtml";
+
+    /**
+     * {@inheritDoc}
+     *
+     * @note Writes a PLCopen XML file at the indicated path.
+     */
+    @Override
+    public void write(PlcProject project, String filePath) {
+        filePath = Paths.resolve(filePath); // Switch to platform-specific file separators.
+
+        // Create document from project.
+        Document doc = transProject(project);
+
+        // Write XML document.
+        writeDocument(doc, filePath);
+
+        // Validate XML file against XSD.
+        validateDocument(filePath);
+    }
+
+    /**
+     * Transforms a PLC project to PLCopen XML.
+     *
+     * @param project The project.
+     * @return The XML document.
+     */
+    private Document transProject(PlcProject project) {
+        // Create document builder.
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+
+        DocumentBuilder builder;
+        try {
+            builder = factory.newDocumentBuilder();
+        } catch (ParserConfigurationException e) {
+            throw new RuntimeException(e);
+        }
+
+        // Create document and get root.
+        DOMImplementation domImpl = builder.getDOMImplementation();
+        Document doc = domImpl.createDocument(PLCOPEN_NS, "project", null);
+        doc.setXmlStandalone(true);
+        Element root = doc.getDocumentElement();
+
+        // Add required elements and project data.
+        Element fileHeader = doc.createElement("fileHeader");
+        root.appendChild(fileHeader);
+        fileHeader.setAttribute("companyName", "Eclipse Foundation");
+        fileHeader.setAttribute("productName", "CIF to Structured Text");
+        fileHeader.setAttribute("productVersion", "0.0"); // Dummy version.
+        Instant instant = Instant.ofEpochMilli(0); // Dummy instant, to allow for automated testing.
+        String formattedDateTime = DateTimeFormatter.ISO_INSTANT.format(instant);
+        fileHeader.setAttribute("creationDateTime", formattedDateTime);
+
+        Element contentHeader = doc.createElement("contentHeader");
+        root.appendChild(contentHeader);
+        contentHeader.setAttribute("name", project.name);
+
+        Element coordInfo = doc.createElement("coordinateInfo");
+        contentHeader.appendChild(coordInfo);
+
+        Element fbd = doc.createElement("fbd");
+        coordInfo.appendChild(fbd);
+
+        Element fbdScaling = doc.createElement("scaling");
+        fbd.appendChild(fbdScaling);
+        fbdScaling.setAttribute("x", "1");
+        fbdScaling.setAttribute("y", "1");
+
+        Element ld = doc.createElement("ld");
+        coordInfo.appendChild(ld);
+
+        Element ldScaling = doc.createElement("scaling");
+        ld.appendChild(ldScaling);
+        ldScaling.setAttribute("x", "1");
+        ldScaling.setAttribute("y", "1");
+
+        Element sfc = doc.createElement("sfc");
+        coordInfo.appendChild(sfc);
+
+        Element sfcScaling = doc.createElement("scaling");
+        sfc.appendChild(sfcScaling);
+        sfcScaling.setAttribute("x", "1");
+        sfcScaling.setAttribute("y", "1");
+
+        Element types = doc.createElement("types");
+        root.appendChild(types);
+
+        Element dataTypes = doc.createElement("dataTypes");
+        types.appendChild(dataTypes);
+
+        Element pous = doc.createElement("pous");
+        types.appendChild(pous);
+
+        Element instances = doc.createElement("instances");
+        root.appendChild(instances);
+
+        Element configurations = doc.createElement("configurations");
+        instances.appendChild(configurations);
+
+        // Add data types.
+        for (PlcTypeDecl typeDecl: project.typeDecls) {
+            transTypeDecl(typeDecl, dataTypes);
+        }
+
+        // Add POUs.
+        for (PlcPou pou: project.pous) {
+            transPou(pou, pous);
+        }
+
+        // Add configurations.
+        for (PlcConfiguration config: project.configurations) {
+            transConfig(config, configurations);
+        }
+
+        // Return document.
+        return doc;
+    }
+
+    /**
+     * Transforms a PLC type declaration to PLCopen XML.
+     *
+     * @param typeDecl The type declaration.
+     * @param parent The parent element in which to generate new elements.
+     */
+    private void transTypeDecl(PlcTypeDecl typeDecl, Element parent) {
+        Element dataType = parent.getOwnerDocument().createElement("dataType");
+        parent.appendChild(dataType);
+
+        dataType.setAttribute("name", typeDecl.name);
+
+        Element baseType = parent.getOwnerDocument().createElement("baseType");
+        dataType.appendChild(baseType);
+
+        transType(typeDecl.type, baseType);
+    }
+
+    /**
+     * Transforms a PLC type to PLCopen XML.
+     *
+     * @param type The type.
+     * @param parent The parent element in which to generate new elements.
+     */
+    private void transType(PlcType type, Element parent) {
+        if (type instanceof PlcElementaryType) {
+            PlcElementaryType etype = (PlcElementaryType)type;
+            Element elem = parent.getOwnerDocument().createElement(etype.name);
+            parent.appendChild(elem);
+        } else if (type instanceof PlcDerivedType) {
+            Element derived = parent.getOwnerDocument().createElement("derived");
+            parent.appendChild(derived);
+
+            PlcDerivedType dtype = (PlcDerivedType)type;
+            derived.setAttribute("name", dtype.name);
+        } else if (type instanceof PlcEnumType) {
+            Element enumElem = parent.getOwnerDocument().createElement("enum");
+            parent.appendChild(enumElem);
+
+            Element values = parent.getOwnerDocument().createElement("values");
+            enumElem.appendChild(values);
+
+            PlcEnumType etype = (PlcEnumType)type;
+            for (String lit: etype.literals) {
+                Element value = parent.getOwnerDocument().createElement("value");
+                values.appendChild(value);
+                value.setAttribute("name", lit);
+            }
+        } else if (type instanceof PlcStructType) {
+            Element struct = parent.getOwnerDocument().createElement("struct");
+            parent.appendChild(struct);
+
+            PlcStructType stype = (PlcStructType)type;
+            for (PlcVariable field: stype.fields) {
+                transVariable(field, struct);
+            }
+        } else if (type instanceof PlcArrayType) {
+            Element array = parent.getOwnerDocument().createElement("array");
+            parent.appendChild(array);
+
+            PlcArrayType atype = (PlcArrayType)type;
+
+            Element dim = parent.getOwnerDocument().createElement("dimension");
+            array.appendChild(dim);
+            dim.setAttribute("lower", str(atype.lower));
+            dim.setAttribute("upper", str(atype.upper));
+
+            Element bt = parent.getOwnerDocument().createElement("baseType");
+            array.appendChild(bt);
+            transType(atype.elemType, bt);
+        } else {
+            throw new RuntimeException("Unknown plc type: " + type);
+        }
+    }
+
+    /**
+     * Transforms a PLC variable to PLCopen XML.
+     *
+     * @param var The variable.
+     * @param parent The parent element in which to generate new elements.
+     */
+    private void transVariable(PlcVariable var, Element parent) {
+        Element varElem = parent.getOwnerDocument().createElement("variable");
+        parent.appendChild(varElem);
+
+        varElem.setAttribute("name", var.name);
+        if (var.address != null) {
+            varElem.setAttribute("address", var.address);
+        }
+
+        Element type = parent.getOwnerDocument().createElement("type");
+        varElem.appendChild(type);
+        transType(var.type, type);
+
+        if (var.value != null) {
+            Element value = parent.getOwnerDocument().createElement("initialValue");
+            varElem.appendChild(value);
+            transValue(var.value, value);
+        }
+    }
+
+    /**
+     * Transforms a PLC value to PLCopen XML.
+     *
+     * @param value The value.
+     * @param parent The parent element in which to generate new elements.
+     */
+    private void transValue(PlcValue value, Element parent) {
+        Element vElem = parent.getOwnerDocument().createElement("simpleValue");
+        parent.appendChild(vElem);
+
+        vElem.setAttribute("value", value.value);
+    }
+
+    /**
+     * Transforms a PLC POU to PLCopen XML.
+     *
+     * @param pou The POU.
+     * @param parent The parent element in which to generate new elements.
+     */
+    private void transPou(PlcPou pou, Element parent) {
+        Element pouElem = parent.getOwnerDocument().createElement("pou");
+        parent.appendChild(pouElem);
+
+        pouElem.setAttribute("name", pou.name);
+        String pouTypeText = null;
+        switch (pou.pouType) {
+            case FUNCTION:
+                pouTypeText = "function";
+                break;
+            case PROGRAM:
+                pouTypeText = "program";
+                break;
+        }
+        pouElem.setAttribute("pouType", pouTypeText);
+
+        Element iface = parent.getOwnerDocument().createElement("interface");
+        pouElem.appendChild(iface);
+
+        if (pou.retType != null) {
+            Element rtElem = parent.getOwnerDocument().createElement("returnType");
+            iface.appendChild(rtElem);
+
+            transType(pou.retType, rtElem);
+        }
+
+        if (!pou.inputVars.isEmpty()) {
+            Element e = parent.getOwnerDocument().createElement("inputVars");
+            iface.appendChild(e);
+
+            for (PlcVariable var: pou.inputVars) {
+                transVariable(var, e);
+            }
+        }
+
+        if (!pou.outputVars.isEmpty()) {
+            Element e = parent.getOwnerDocument().createElement("outputVars");
+            iface.appendChild(e);
+
+            for (PlcVariable var: pou.outputVars) {
+                transVariable(var, e);
+            }
+        }
+
+        if (!pou.localVars.isEmpty()) {
+            Element e = parent.getOwnerDocument().createElement("localVars");
+            iface.appendChild(e);
+
+            for (PlcVariable var: pou.localVars) {
+                transVariable(var, e);
+            }
+        }
+
+        if (!pou.tempVars.isEmpty()) {
+            Element e = parent.getOwnerDocument().createElement("tempVars");
+            iface.appendChild(e);
+
+            for (PlcVariable var: pou.tempVars) {
+                transVariable(var, e);
+            }
+        }
+
+        transBody(pou.body, pouElem);
+    }
+
+    /**
+     * Transforms a PLC POU body to PLCopen XML.
+     *
+     * @param body The body.
+     * @param parent The parent element in which to generate new elements.
+     */
+    private void transBody(CodeBox body, Element parent) {
+        Element bodyElem = parent.getOwnerDocument().createElement("body");
+        parent.appendChild(bodyElem);
+
+        Element st = parent.getOwnerDocument().createElement("ST");
+        bodyElem.appendChild(st);
+
+        Element xhtml = parent.getOwnerDocument().createElementNS(XHTML_NS, "xhtml");
+        st.appendChild(xhtml);
+
+        xhtml.setTextContent(body.toString());
+    }
+
+    /**
+     * Transforms a PLC configuration to PLCopen XML.
+     *
+     * @param config The configuration.
+     * @param parent The parent element in which to generate new elements.
+     */
+    private void transConfig(PlcConfiguration config, Element parent) {
+        Element configElem = parent.getOwnerDocument().createElement("configuration");
+        parent.appendChild(configElem);
+
+        configElem.setAttribute("name", config.name);
+
+        for (PlcResource resource: config.resources) {
+            transResource(resource, configElem);
+        }
+
+        for (PlcGlobalVarList varList: config.globalVarLists) {
+            transGlobalVarList(varList, configElem);
+        }
+    }
+
+    /**
+     * Transforms a PLC global variable list to PLCopen XML.
+     *
+     * @param varList The global variable list.
+     * @param parent The parent element in which to generate new elements.
+     */
+    private void transGlobalVarList(PlcGlobalVarList varList, Element parent) {
+        // Skip if no variables.
+        if (varList.variables.isEmpty()) {
+            return;
+        }
+
+        // We have variables, so add it.
+        Element gv = parent.getOwnerDocument().createElement("globalVars");
+        parent.appendChild(gv);
+
+        gv.setAttribute("name", varList.name);
+        gv.setAttribute("constant", varList.constants ? "true" : "false");
+        for (PlcVariable var: varList.variables) {
+            transVariable(var, gv);
+        }
+    }
+
+    /**
+     * Transforms a PLC resource to PLCopen XML.
+     *
+     * @param resource The resource.
+     * @param parent The parent element in which to generate new elements.
+     */
+    private void transResource(PlcResource resource, Element parent) {
+        Element resElem = parent.getOwnerDocument().createElement("resource");
+        parent.appendChild(resElem);
+
+        resElem.setAttribute("name", resource.name);
+
+        for (PlcTask task: resource.tasks) {
+            transTask(task, resElem);
+        }
+
+        for (PlcGlobalVarList varList: resource.globalVarLists) {
+            transGlobalVarList(varList, resElem);
+        }
+
+        for (PlcPouInstance inst: resource.pouInstances) {
+            transPouInstance(inst, resElem);
+        }
+    }
+
+    /**
+     * Transforms a PLC POU instance to PLCopen XML.
+     *
+     * @param inst The POU instance.
+     * @param parent The parent element in which to generate new elements.
+     * @return The newly created element for the POU instance.
+     */
+    private Element transPouInstance(PlcPouInstance inst, Element parent) {
+        Element instElem = parent.getOwnerDocument().createElement("pouInstance");
+        parent.appendChild(instElem);
+
+        instElem.setAttribute("name", inst.name);
+        instElem.setAttribute("typeName", inst.pou.name);
+
+        return instElem;
+    }
+
+    /**
+     * Transforms a PLC POU instance to PLCopen XML and adds a documentation child element to the POU instance.
+     *
+     * @param inst The POU instance.
+     * @param parent The parent element in which to generate new elements.
+     */
+    private void transPouInstanceWithDoc(PlcPouInstance inst, Element parent) {
+        Element instElem = transPouInstance(inst, parent);
+
+        Element docElem = instElem.getOwnerDocument().createElement("documentation");
+        instElem.appendChild(docElem);
+
+        Element xhtml = docElem.getOwnerDocument().createElementNS(XHTML_NS, "xhtml");
+        docElem.appendChild(xhtml);
+    }
+
+    /**
+     * Transforms a PLC task to PLCopen XML.
+     *
+     * @param task The task.
+     * @param parent The parent element in which to generate new elements.
+     */
+    private void transTask(PlcTask task, Element parent) {
+        Element taskElem = parent.getOwnerDocument().createElement("task");
+        parent.appendChild(taskElem);
+
+        taskElem.setAttribute("name", task.name);
+        // Interval value is vendor specific, TwinCAT and CODESYS use ISO 8601 Durations.
+        taskElem.setAttribute("interval", fmt("PT%.3fS", (float)task.cycleTime / 1000));
+        taskElem.setAttribute("priority", str(task.priority));
+
+        for (PlcPouInstance inst: task.pouInstances) {
+            // Make sure to also include a documentation element as a child of this POU otherwise TwinCAT and CODESYS
+            // give an 'object reference not set' error when creating this task element.
+            transPouInstanceWithDoc(inst, taskElem);
+        }
+    }
+
+    /**
+     * Validates the written PLCopen XML file against the XSD schema.
+     *
+     * @param filePath The absolute local file system path of the PLCopen XML file, with platform specific file
+     *     separators.
+     */
+    private void validateDocument(String filePath) {
+        InputStream schemaStream = null;
+        InputStream xmlStream = null;
+        try {
+            // Get XSD schema source.
+            String schemaName = PlcOpenXmlWriter.class.getPackage().getName();
+            schemaName = schemaName.replace('.', '/') + "/tc6_xml_v201.xsd";
+            ClassLoader classLoader = PlcOpenXmlWriter.class.getClassLoader();
+            schemaStream = classLoader.getResourceAsStream(schemaName);
+            Source schemaSrc = new StreamSource(schemaStream);
+
+            // Get XML file source.
+            xmlStream = new FileInputStream(filePath);
+            xmlStream = new BufferedInputStream(xmlStream);
+            Source xmlSrc = new StreamSource(xmlStream);
+
+            // Get validator.
+            SchemaFactory schemaFactory = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI);
+            Schema schema;
+            try {
+                schema = schemaFactory.newSchema(schemaSrc);
+            } catch (SAXException e) {
+                throw new RuntimeException(e);
+            }
+            Validator validator = schema.newValidator();
+
+            // Validate.
+            try {
+                validator.validate(xmlSrc);
+            } catch (SAXException e) {
+                throw new RuntimeException(e);
+            }
+        } catch (IOException e) {
+            String msg = fmt("Failed to validate \"%s\" due to an I/O error.", filePath);
+            throw new InputOutputException(msg, e);
+        } finally {
+            // Always close streams.
+            if (schemaStream != null) {
+                try {
+                    schemaStream.close();
+                } catch (IOException e) {
+                    // Ignore.
+                }
+            }
+            if (xmlStream != null) {
+                try {
+                    xmlStream.close();
+                } catch (IOException e) {
+                    // Ignore.
+                }
+            }
+        }
+    }
+
+    /**
+     * Writes a PLCopen XML file, given the contents as an XML document.
+     *
+     * @param doc The XML document to use as contents for the file.
+     * @param filePath The absolute local file system path of the PLCopen XML file to write, with platform specific file
+     *     separators.
+     */
+    private void writeDocument(Document doc, String filePath) {
+        // Construct transformer.
+        TransformerFactory xmlTransFactory = TransformerFactory.newInstance();
+        Transformer xmlTrans;
+        try {
+            xmlTrans = xmlTransFactory.newTransformer();
+        } catch (TransformerConfigurationException e) {
+            throw new RuntimeException(e);
+        }
+        xmlTrans.setOutputProperty(OutputKeys.INDENT, "yes");
+        xmlTrans.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
+
+        // Set input/output.
+        DOMSource source = new DOMSource(doc);
+        FileOutputStream xmlStream;
+        try {
+            xmlStream = new FileOutputStream(filePath);
+        } catch (FileNotFoundException ex) {
+            String msg = fmt("Failed to write PLCopen XML file to \"%s\".", filePath);
+            throw new InputOutputException(msg, ex);
+        }
+        StreamResult result = new StreamResult(xmlStream);
+
+        // Transform in-memory tree to file.
+        try {
+            xmlTrans.transform(source, result);
+        } catch (TransformerException e) {
+            throw new RuntimeException(e);
+        }
+
+        // Close the file.
+        try {
+            xmlStream.close();
+        } catch (IOException e) {
+            String msg = fmt("Failed to close file \"%s\".", filePath);
+            throw new InputOutputException(msg, e);
+        }
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/writers/S7Writer.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/writers/S7Writer.java
index 99e680614c1eba224440d9efd44ceeb4acd59a2e..0818728b228170b6a80001093965da8ac219164d 100644
--- a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/writers/S7Writer.java
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/writers/S7Writer.java
@@ -13,7 +13,7 @@
 
 package org.eclipse.escet.cif.plcgen.writers;
 
-import static org.eclipse.escet.cif.cif2plc.plcdata.PlcPouType.PROGRAM;
+import static org.eclipse.escet.cif.plcgen.model.declarations.PlcPouType.PROGRAM;
 import static org.eclipse.escet.cif.plcgen.targets.PlcTargetType.S7_1200;
 import static org.eclipse.escet.cif.plcgen.targets.PlcTargetType.S7_1500;
 import static org.eclipse.escet.common.java.Strings.fmt;
@@ -21,16 +21,15 @@ import static org.eclipse.escet.common.java.Strings.fmt;
 import java.util.EnumSet;
 import java.util.List;
 
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcConfiguration;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcGlobalVarList;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcPou;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcPouType;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcProject;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcResource;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcStructType;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcTypeDecl;
-import org.eclipse.escet.cif.cif2plc.plcdata.PlcVariable;
-import org.eclipse.escet.cif.cif2plc.writers.OutputTypeWriter;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcConfiguration;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcGlobalVarList;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcPou;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcPouType;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcProject;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcResource;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcTypeDecl;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcVariable;
+import org.eclipse.escet.cif.plcgen.model.types.PlcStructType;
 import org.eclipse.escet.cif.plcgen.targets.PlcTargetType;
 import org.eclipse.escet.common.app.framework.Paths;
 import org.eclipse.escet.common.box.Box;
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/writers/TwinCatWriter.java b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/writers/TwinCatWriter.java
new file mode 100644
index 0000000000000000000000000000000000000000..4cf0ad5ee53391f10771ab37aab5605f5a1c0585
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/writers/TwinCatWriter.java
@@ -0,0 +1,638 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.cif.plcgen.writers;
+
+import static org.eclipse.escet.common.java.Lists.first;
+import static org.eclipse.escet.common.java.Lists.list;
+import static org.eclipse.escet.common.java.Lists.listc;
+import static org.eclipse.escet.common.java.Maps.map;
+import static org.eclipse.escet.common.java.Strings.fmt;
+import static org.eclipse.escet.common.java.Strings.str;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcConfiguration;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcGlobalVarList;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcPou;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcPouInstance;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcProject;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcResource;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcTask;
+import org.eclipse.escet.cif.plcgen.model.declarations.PlcTypeDecl;
+import org.eclipse.escet.cif.plcgen.model.types.PlcStructType;
+import org.eclipse.escet.common.app.framework.Paths;
+import org.eclipse.escet.common.app.framework.exceptions.InputOutputException;
+import org.eclipse.escet.common.app.framework.exceptions.InvalidOptionException;
+import org.eclipse.escet.common.box.Box;
+import org.eclipse.escet.common.box.CodeBox;
+import org.eclipse.escet.common.box.HBox;
+import org.eclipse.escet.common.box.MemoryCodeBox;
+import org.eclipse.escet.common.java.Assert;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+/** TwinCAT 3.1 writer. */
+public class TwinCatWriter extends OutputTypeWriter {
+    /** The PLC project to use, {@code null} until available. */
+    private PlcProject project;
+
+    /** The PLC configuration to use, {@code null} until available. */
+    private PlcConfiguration configuration;
+
+    /** The PLC resource to use, {@code null} until available. */
+    private PlcResource resource;
+
+    /** The PLC task to use, {@code null} until available. */
+    private PlcTask task;
+
+    /** The TwinCAT XAE project (.tsproj) file, {@code null} until available. */
+    private File xaeProjFile;
+
+    /** The TwinCAT PLC project (.plcproj) file, {@code null} until available. */
+    private File plcProjFile;
+
+    /** The directory containing the TwinCAT PLC project (.plcproj) file, {@code null} until available. */
+    private File plcProjDirFile;
+
+    /** Mapping from PLC project relative file paths to their XML content. */
+    private Map<String, Document> files = map();
+
+    /** Old code files that are scheduled to be removed (since there are no replacements in {@link #files}). */
+    private List<File> oldCodeFiles = list();
+
+    /**
+     * {@inheritDoc}
+     *
+     * @note Must point to a directory containing an already generated TwinCAT solution.
+     */
+    @Override
+    public void write(PlcProject project, String slnDirPath) {
+        slnDirPath = Paths.resolve(slnDirPath); // Switch to platform-specific file separators.
+
+        this.project = project;
+
+        Assert.check(project.configurations.size() == 1);
+        configuration = first(project.configurations);
+
+        Assert.check(configuration.resources.size() == 1);
+        resource = first(configuration.resources);
+
+        Assert.check(resource.tasks.size() == 1);
+        task = first(resource.tasks);
+
+        if (task.cycleTime == 0) {
+            String msg = "TwinCAT output with periodic task scheduling disabled, is currently not supported.";
+            throw new InvalidOptionException(msg);
+        }
+
+        findTwinCatProjects(slnDirPath);
+
+        // POU instances in the resource are not supported.
+        Assert.check(resource.pouInstances.isEmpty());
+
+        // Update TwinCAT XAE project.
+        updateXaeProj();
+        genCodeFiles();
+        updatePlcProj();
+        updateTask();
+        updateCodeFiles();
+    }
+
+    /**
+     * Finds the projects within the TwinCAT solution.
+     *
+     * @param slnDirPath The absolute local file system path of the directory containing the TwinCAT solution, with
+     *     platform specific file separators.
+     * @throws InvalidOptionException If the solution path does not refer to a directory with the expected files and
+     *     sub-directories.
+     */
+    private void findTwinCatProjects(String slnDirPath) {
+        // Find solution directory.
+        File slnDirFile = new File(slnDirPath);
+        if (!slnDirFile.isDirectory()) {
+            String msg = fmt("TwinCAT solution directory \"%s\" does not exist, or is not a directory.",
+                    slnDirFile.getPath());
+            throw new InvalidOptionException(msg);
+        }
+
+        // Find solution file.
+        String slnDirName = slnDirFile.getName();
+        File slnFile = new File(slnDirFile, slnDirName + ".sln");
+        if (!slnFile.isFile()) {
+            String msg = fmt("TwinCAT solution file \"%s\" does not exist, or is not a file.", slnFile.getPath());
+            throw new InvalidOptionException(msg);
+        }
+
+        // Find TwinCAT XAE project directory.
+        File xaeDirFile = new File(slnDirFile, slnDirName);
+        if (!xaeDirFile.isDirectory()) {
+            String msg = fmt("TwinCAT XAE project directory \"%s\" does not exist, or is not a directory.",
+                    xaeDirFile.getPath());
+            throw new InvalidOptionException(msg);
+        }
+
+        // Find TwinCAT XAE project file.
+        xaeProjFile = new File(xaeDirFile, slnDirName + ".tsproj");
+        if (!xaeProjFile.isFile()) {
+            String msg = fmt("TwinCAT XAE project file \"%s\" does not exist, or is not a file.",
+                    xaeProjFile.getPath());
+            throw new InvalidOptionException(msg);
+        }
+
+        // Find TwinCAT PLC project directory.
+        plcProjDirFile = new File(xaeDirFile, project.name);
+        if (!plcProjDirFile.isDirectory()) {
+            String msg = fmt("TwinCAT PLC project directory \"%s\" does not exist, or is not a directory.",
+                    plcProjDirFile.getPath());
+            throw new InvalidOptionException(msg);
+        }
+
+        // Find TwinCAT PLC project file.
+        plcProjFile = new File(plcProjDirFile, project.name + ".plcproj");
+        if (!plcProjFile.isFile()) {
+            String msg = fmt("TwinCAT PLC project file \"%s\" does not exist, or is not a file.",
+                    plcProjFile.getPath());
+            throw new InvalidOptionException(msg);
+        }
+    }
+
+    /** Update the TwinCAT XAE project (.tsproj) file. */
+    private void updateXaeProj() {
+        // Read project file.
+        Document doc = readXmlFile(xaeProjFile);
+
+        // Find and update task.
+        String query = fmt("//Task/Name[text()='%s']/..", task.name);
+        List<Node> tasks = execXPath(doc, query);
+        if (tasks.size() != 1) {
+            String msg = fmt("Found %d tasks with name \"%s\" in \"%s\".", tasks.size(), task.name,
+                    xaeProjFile.getPath());
+            throw new InvalidOptionException(msg);
+        }
+        Element taskElem = (Element)first(tasks);
+        taskElem.setAttribute("Priority", str(task.priority));
+        taskElem.setAttribute("CycleTime", str(task.cycleTime * 10000));
+
+        // Write project file.
+        writeXmlFile(doc, xaeProjFile);
+    }
+
+    /**
+     * Update the TwinCAT PLC project (.plcproj) file. Also schedules {@link #oldCodeFiles old code files} for removal.
+     */
+    private void updatePlcProj() {
+        // Read project file.
+        Document doc = readXmlFile(plcProjFile);
+
+        // Find compilation item group, or add one.
+        List<Node> compileGroups = execXPath(doc, "//ItemGroup/Compile/..");
+        Element compileGroup;
+        if (compileGroups.isEmpty()) {
+            // Add new ItemGroup for 'Compile' entries.
+            compileGroup = doc.createElement("ItemGroup");
+            doc.getDocumentElement().appendChild(compileGroup);
+        } else {
+            // Reuse first 'ItemGroup' with a 'Compile' in it.
+            compileGroup = (Element)first(compileGroups);
+        }
+
+        // Remove all 'Compile' entries for old code files. Also remove the
+        // actual files on disk.
+        String query = "//ItemGroup/Compile/@Include/..";
+        List<Node> compileNodes = execXPath(doc, query);
+        for (Node compileNode: compileNodes) {
+            // Only remove code files for POUs, DUTs, and GVLs.
+            Element compileElem = (Element)compileNode;
+            String path = compileElem.getAttribute("Include");
+            if (!path.endsWith("TcPOU") && !path.endsWith("TcGVL") && !path.endsWith("TcDUT")) {
+                continue;
+            }
+
+            // Remove XML element.
+            compileNode.getParentNode().removeChild(compileNode);
+
+            // Schedule old code files for removal, if no new code file.
+            boolean remove = !files.containsKey(path);
+            path = Paths.join(plcProjDirFile.getPath(), path);
+            File codeFile = new File(path);
+            if (remove && codeFile.exists()) {
+                oldCodeFiles.add(codeFile);
+            }
+        }
+
+        // Find/add compilation instructions for all new code files.
+        for (String path: files.keySet()) {
+            query = fmt("//ItemGroup/Compile[@Include='%s']", path);
+            List<Node> compiles = execXPath(doc, query);
+            if (compiles.isEmpty()) {
+                // Add new 'Compile' entry.
+                Element compileElem = doc.createElement("Compile");
+                compileGroup.appendChild(compileElem);
+                compileElem.setAttribute("Include", path);
+
+                // Add new 'SubType' entry.
+                Element subTypeElem = doc.createElement("SubType");
+                compileElem.appendChild(subTypeElem);
+                subTypeElem.setTextContent("Code");
+            }
+        }
+
+        // Ensure code directories are included in the project.
+        for (String folder: list("DUTs", "GVLs", "POUs")) {
+            query = fmt("//ItemGroup/Folder[@Include='%s']", folder);
+            List<Node> tasks = execXPath(doc, query);
+            if (tasks.isEmpty()) {
+                Element folderElem = doc.createElement("Folder");
+                compileGroup.appendChild(folderElem);
+                folderElem.setAttribute("Include", folder);
+            }
+        }
+
+        // Write project file.
+        writeXmlFile(doc, plcProjFile);
+    }
+
+    /** Update the TwinCAT task (.TcTTO) file. */
+    private void updateTask() {
+        // Read task file.
+        File taskFile = new File(plcProjDirFile, fmt("%s.TcTTO", task.name));
+        Document doc = readXmlFile(taskFile);
+
+        // Update cycle time.
+        List<Node> cycleNodes = execXPath(doc, "//Task/CycleTime");
+        for (Node cycleNode: cycleNodes) {
+            cycleNode.setTextContent(str(task.cycleTime * 1000));
+        }
+
+        // Update priority.
+        List<Node> prioNodes = execXPath(doc, "//Task/Priority");
+        for (Node prioNode: prioNodes) {
+            prioNode.setTextContent(str(task.priority));
+        }
+
+        // Find task.
+        Element taskElem = null;
+        NodeList nodes = doc.getDocumentElement().getChildNodes();
+        for (int i = 0; i < nodes.getLength(); i++) {
+            Node node = nodes.item(i);
+            if (node.getNodeName().equals("Task")) {
+                taskElem = (Element)node;
+                break;
+            }
+        }
+        if (taskElem == null) {
+            throw new RuntimeException("Task not found.");
+        }
+
+        // Find/add 'PouCall'.
+        Element callElem = null;
+        nodes = taskElem.getChildNodes();
+        for (int i = 0; i < nodes.getLength(); i++) {
+            Node node = nodes.item(i);
+            if (node.getNodeName().equals("PouCall")) {
+                callElem = (Element)node;
+                break;
+            }
+        }
+
+        // Find/add POU calls for all POU instances.
+        for (PlcPouInstance pouInst: task.pouInstances) {
+            // TwinCAT does not have a different name for a POU and its
+            // instance.
+            Assert.check(pouInst.name.equals(pouInst.pou.name));
+
+            // Find 'PouCall/Name' for POU instance.
+            String query = fmt("//Task/PouCall/Name[text()='%s']", pouInst.name);
+            List<Node> callNodes = execXPath(doc, query);
+
+            // Add 'PouCall/Name' if not found.
+            if (callNodes.isEmpty()) {
+                // Ensure we have a 'PouCall' element.
+                if (callElem == null) {
+                    callElem = doc.createElement("PouCall");
+                    taskElem.appendChild(callElem);
+                }
+
+                // Add 'Name' element.
+                Element nameElem = doc.createElement("Name");
+                callElem.appendChild(nameElem);
+                nameElem.setTextContent(pouInst.name);
+            }
+        }
+
+        // Write task file.
+        writeXmlFile(doc, taskFile);
+    }
+
+    /**
+     * Read a TwinCAT XML file.
+     *
+     * @param file The XML file. Must represent and absolute local file system path.
+     * @return The XML document resulting from parsing the project file.
+     */
+    private Document readXmlFile(File file) {
+        // Paranoia check.
+        Assert.check(file.isAbsolute());
+
+        // Create builder.
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        DocumentBuilder builder;
+        try {
+            builder = factory.newDocumentBuilder();
+        } catch (ParserConfigurationException e) {
+            throw new RuntimeException(e);
+        }
+
+        // Parse file.
+        try {
+            return builder.parse(file);
+        } catch (SAXException e) {
+            String msg = fmt("TwinCAT file \"%s\" could not be read.", file.getPath());
+            throw new InvalidOptionException(msg, e);
+        } catch (IOException e) {
+            String msg = fmt("TwinCAT file \"%s\" could not be read.", file.getPath());
+            throw new InputOutputException(msg, e);
+        }
+    }
+
+    /**
+     * Write a TwinCAT file.
+     *
+     * @param doc The XML document to write to the file.
+     * @param file The file to which to write. Must represent and absolute local file system path.
+     */
+    private void writeXmlFile(Document doc, File file) {
+        // Paranoia check.
+        Assert.check(file.isAbsolute());
+
+        // Write file.
+        TransformerFactory factory = TransformerFactory.newInstance();
+        Transformer transformer;
+        try {
+            transformer = factory.newTransformer();
+        } catch (TransformerConfigurationException e) {
+            throw new RuntimeException(e);
+        }
+        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+        String indentAmountKey = "{http://xml.apache.org/xslt}indent-amount";
+        transformer.setOutputProperty(indentAmountKey, "2");
+
+        DOMSource source = new DOMSource(doc);
+        StreamResult result = new StreamResult(file);
+        try {
+            transformer.transform(source, result);
+        } catch (TransformerException e) {
+            String msg = fmt("Failed to write TwinCAT file \"%s\".", file.getPath());
+            throw new InputOutputException(msg, e);
+        }
+    }
+
+    /**
+     * Executes an XPath query on the given XML node.
+     *
+     * @param node The start node of the query.
+     * @param query The query in XPath syntax.
+     * @return The nodes resulting from the query.
+     */
+    private List<Node> execXPath(Node node, String query) {
+        // Create XPath expression.
+        XPathFactory xPathfactory = XPathFactory.newInstance();
+        XPath xpath = xPathfactory.newXPath();
+        XPathExpression expr;
+        try {
+            expr = xpath.compile(query);
+        } catch (XPathExpressionException e) {
+            throw new RuntimeException(e);
+        }
+
+        // Evaluate expression.
+        NodeList nodes;
+        try {
+            nodes = (NodeList)expr.evaluate(node, XPathConstants.NODESET);
+        } catch (XPathExpressionException e) {
+            throw new RuntimeException(e);
+        }
+
+        // Return as a list of nodes.
+        List<Node> rslt = listc(nodes.getLength());
+        for (int i = 0; i < nodes.getLength(); i++) {
+            rslt.add(nodes.item(i));
+        }
+        return rslt;
+    }
+
+    /** Generate code files. */
+    private void genCodeFiles() {
+        for (PlcPou pou: project.pous) {
+            genCodeFile(pou);
+        }
+        for (PlcTypeDecl tdecl: project.typeDecls) {
+            genCodeFile(tdecl);
+        }
+        for (PlcGlobalVarList varList: configuration.globalVarLists) {
+            genCodeFile(varList);
+        }
+        for (PlcGlobalVarList varList: resource.globalVarLists) {
+            genCodeFile(varList);
+        }
+    }
+
+    /**
+     * Generates code file for a PLC POU.
+     *
+     * @param pou The PLC POU.
+     */
+    private void genCodeFile(PlcPou pou) {
+        // Generate XML document.
+        Document doc = createXmlDoc();
+
+        Element rootElem = doc.createElement("TcPlcObject");
+        doc.appendChild(rootElem);
+        rootElem.setAttribute("Version", "1.1.0.1");
+        rootElem.setAttribute("ProductVersion", "3.1.0.18");
+
+        Element pouElem = doc.createElement("POU");
+        rootElem.appendChild(pouElem);
+        pouElem.setAttribute("Name", pou.name);
+
+        Element declElem = doc.createElement("Declaration");
+        pouElem.appendChild(declElem);
+
+        String headerTxt = headerToBox(pou).toString();
+        declElem.appendChild(doc.createCDATASection(headerTxt));
+
+        Element implElem = doc.createElement("Implementation");
+        pouElem.appendChild(implElem);
+
+        Element stElem = doc.createElement("ST");
+        implElem.appendChild(stElem);
+
+        stElem.appendChild(doc.createCDATASection(pou.body.toString()));
+
+        Element opElem = doc.createElement("ObjectProperties");
+        pouElem.appendChild(opElem);
+
+        // Store new file.
+        String fileName = fmt("POUs\\%s.TcPOU", pou.name);
+        Document prevDoc = files.put(fileName, doc);
+        Assert.check(prevDoc == null);
+    }
+
+    /**
+     * Generates code file for a PLC type declaration.
+     *
+     * @param typeDecl The PLC type declaration.
+     */
+    private void genCodeFile(PlcTypeDecl typeDecl) {
+        // Generate XML document.
+        Document doc = createXmlDoc();
+
+        Element rootElem = doc.createElement("TcPlcObject");
+        doc.appendChild(rootElem);
+        rootElem.setAttribute("Version", "1.1.0.1");
+        rootElem.setAttribute("ProductVersion", "3.1.0.18");
+
+        Element pouElem = doc.createElement("DUT");
+        rootElem.appendChild(pouElem);
+        pouElem.setAttribute("Name", typeDecl.name);
+
+        Element declElem = doc.createElement("Declaration");
+        pouElem.appendChild(declElem);
+
+        String txt = toBox(typeDecl).toString();
+        declElem.appendChild(doc.createCDATASection(txt));
+
+        Element opElem = doc.createElement("ObjectProperties");
+        pouElem.appendChild(opElem);
+
+        // Store new file.
+        String fileName = fmt("DUTs\\%s.TcDUT", typeDecl.name);
+        Document prevDoc = files.put(fileName, doc);
+        Assert.check(prevDoc == null);
+    }
+
+    /**
+     * Generates code file for a PLC global variable list.
+     *
+     * @param varList The PLC global variable list.
+     */
+    private void genCodeFile(PlcGlobalVarList varList) {
+        // Skip empty variable lists.
+        if (varList.variables.isEmpty()) {
+            return;
+        }
+
+        // Generate XML document.
+        Document doc = createXmlDoc();
+
+        Element rootElem = doc.createElement("TcPlcObject");
+        doc.appendChild(rootElem);
+        rootElem.setAttribute("Version", "1.1.0.1");
+        rootElem.setAttribute("ProductVersion", "3.1.0.18");
+
+        Element pouElem = doc.createElement("GVL");
+        rootElem.appendChild(pouElem);
+        pouElem.setAttribute("Name", varList.name);
+
+        Element declElem = doc.createElement("Declaration");
+        pouElem.appendChild(declElem);
+
+        declElem.appendChild(doc.createCDATASection(toBox(varList).toString()));
+
+        Element opElem = doc.createElement("ObjectProperties");
+        pouElem.appendChild(opElem);
+
+        // Store new file.
+        String fileName = fmt("GVLs\\%s.TcGVL", varList.name);
+        Document prevDoc = files.put(fileName, doc);
+        Assert.check(prevDoc == null);
+    }
+
+    /** Removes old code files, and (over)writes the new code files. */
+    private void updateCodeFiles() {
+        // Remove old code files.
+        for (File oldFile: oldCodeFiles) {
+            boolean success = oldFile.delete();
+            if (!success) {
+                String msg = fmt("Could not remove TwinCAT code file \"%s\".", oldFile.getPath());
+                throw new InputOutputException(msg);
+            }
+        }
+
+        // (Over)write new code files.
+        for (Entry<String, Document> entry: files.entrySet()) {
+            String path = Paths.join(plcProjDirFile.getPath(), entry.getKey());
+            File entryFile = new File(path);
+            writeXmlFile(entry.getValue(), entryFile);
+        }
+    }
+
+    /**
+     * Creates and returns a fresh new XML document.
+     *
+     * @return The XML document.
+     */
+    private Document createXmlDoc() {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        DocumentBuilder builder;
+        try {
+            builder = factory.newDocumentBuilder();
+        } catch (ParserConfigurationException e) {
+            throw new RuntimeException(e);
+        }
+        return builder.newDocument();
+    }
+
+    @Override
+    protected Box toBox(PlcTypeDecl typeDecl) {
+        // Converts the type declaration to a textual representation in IEC 61131-3 syntax. The output is TwinCAT
+        // specific, in that it implements a workaround for a bug in TwinCAT, where structs in type declarations
+        // may not be terminated with a semicolon.
+        CodeBox c = new MemoryCodeBox(INDENT);
+        c.add("TYPE %s:", typeDecl.name);
+        c.indent();
+        if (typeDecl.type instanceof PlcStructType) {
+            // Special TwinCAT workaround.
+            c.add(toBox(typeDecl.type));
+        } else {
+            c.add(new HBox(toBox(typeDecl.type), ";"));
+        }
+        c.dedent();
+        c.add("END_TYPE");
+        return c;
+    }
+}
diff --git a/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/writers/tc6_xml_v201.xsd b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/writers/tc6_xml_v201.xsd
new file mode 100644
index 0000000000000000000000000000000000000000..9aca224f93b3552c6e4095eaf5d96d6e27c39c18
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/writers/tc6_xml_v201.xsd
@@ -0,0 +1,1756 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:ppx="http://www.plcopen.org/xml/tc6_0201" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:ns1="http://www.plcopen.org/xml/tc6.xsd" targetNamespace="http://www.plcopen.org/xml/tc6_0201" elementFormDefault="qualified" attributeFormDefault="unqualified">
+	<xsd:element name="project">
+		<xsd:annotation>
+			<xsd:documentation>The complete project</xsd:documentation>
+		</xsd:annotation>
+		<xsd:complexType>
+			<xsd:sequence>
+				<xsd:element name="fileHeader">
+					<xsd:complexType>
+						<xsd:attribute name="companyName" type="xsd:string" use="required"/>
+						<xsd:attribute name="companyURL" type="xsd:anyURI" use="optional"/>
+						<xsd:attribute name="productName" type="xsd:string" use="required"/>
+						<xsd:attribute name="productVersion" type="xsd:string" use="required"/>
+						<xsd:attribute name="productRelease" type="xsd:string" use="optional"/>
+						<xsd:attribute name="creationDateTime" type="xsd:dateTime" use="required"/>
+						<xsd:attribute name="contentDescription" type="xsd:string" use="optional"/>
+					</xsd:complexType>
+				</xsd:element>
+				<xsd:element name="contentHeader">
+					<xsd:complexType>
+						<xsd:sequence>
+							<xsd:element name="Comment" type="xsd:string" minOccurs="0"/>
+							<xsd:element name="coordinateInfo">
+								<xsd:complexType>
+									<xsd:sequence>
+										<xsd:element name="pageSize" minOccurs="0">
+											<xsd:complexType>
+												<xsd:attribute name="x" type="xsd:decimal" use="required"/>
+												<xsd:attribute name="y" type="xsd:decimal" use="required"/>
+											</xsd:complexType>
+										</xsd:element>
+										<xsd:element name="fbd">
+											<xsd:complexType>
+												<xsd:sequence>
+													<xsd:element name="scaling">
+														<xsd:complexType>
+															<xsd:attribute name="x" type="xsd:decimal" use="required"/>
+															<xsd:attribute name="y" type="xsd:decimal" use="required"/>
+														</xsd:complexType>
+													</xsd:element>
+												</xsd:sequence>
+											</xsd:complexType>
+										</xsd:element>
+										<xsd:element name="ld">
+											<xsd:complexType>
+												<xsd:sequence>
+													<xsd:element name="scaling">
+														<xsd:complexType>
+															<xsd:attribute name="x" type="xsd:decimal" use="required"/>
+															<xsd:attribute name="y" type="xsd:decimal" use="required"/>
+														</xsd:complexType>
+													</xsd:element>
+												</xsd:sequence>
+											</xsd:complexType>
+										</xsd:element>
+										<xsd:element name="sfc">
+											<xsd:complexType>
+												<xsd:sequence>
+													<xsd:element name="scaling">
+														<xsd:complexType>
+															<xsd:attribute name="x" type="xsd:decimal" use="required"/>
+															<xsd:attribute name="y" type="xsd:decimal" use="required"/>
+														</xsd:complexType>
+													</xsd:element>
+												</xsd:sequence>
+											</xsd:complexType>
+										</xsd:element>
+									</xsd:sequence>
+								</xsd:complexType>
+							</xsd:element>
+							<xsd:element name="addDataInfo" type="ppx:addDataInfo" minOccurs="0"/>
+							<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+						</xsd:sequence>
+						<xsd:attribute name="name" type="xsd:string" use="required"/>
+						<xsd:attribute name="version" type="xsd:string" use="optional"/>
+						<xsd:attribute name="modificationDateTime" type="xsd:dateTime" use="optional"/>
+						<xsd:attribute name="organization" type="xsd:string" use="optional"/>
+						<xsd:attribute name="author" type="xsd:string" use="optional"/>
+						<xsd:attribute name="language" type="xsd:language" use="optional">
+							<xsd:annotation>
+								<xsd:documentation>Documentation language of the project e.g. "en-US"</xsd:documentation>
+							</xsd:annotation>
+						</xsd:attribute>
+					</xsd:complexType>
+				</xsd:element>
+				<xsd:element name="types">
+					<xsd:complexType>
+						<xsd:sequence>
+							<xsd:element name="dataTypes">
+								<xsd:complexType>
+									<xsd:sequence>
+										<xsd:element name="dataType" minOccurs="0" maxOccurs="unbounded">
+											<xsd:complexType>
+												<xsd:sequence>
+													<xsd:element name="baseType" type="ppx:dataType"/>
+													<xsd:element name="initialValue" type="ppx:value" minOccurs="0"/>
+													<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+													<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0">
+														<xsd:annotation>
+															<xsd:documentation>Additional userspecific information to the element</xsd:documentation>
+														</xsd:annotation>
+													</xsd:element>
+												</xsd:sequence>
+												<xsd:attribute name="name" type="xsd:string" use="required"/>
+											</xsd:complexType>
+										</xsd:element>
+									</xsd:sequence>
+								</xsd:complexType>
+							</xsd:element>
+							<xsd:element name="pous">
+								<xsd:complexType>
+									<xsd:sequence>
+										<xsd:element name="pou" minOccurs="0" maxOccurs="unbounded">
+											<xsd:complexType>
+												<xsd:sequence>
+													<xsd:element name="interface" minOccurs="0">
+														<xsd:complexType>
+															<xsd:sequence>
+																<xsd:element name="returnType" type="ppx:dataType" minOccurs="0"/>
+																<xsd:choice minOccurs="0" maxOccurs="unbounded">
+																	<xsd:element name="localVars">
+																		<xsd:complexType>
+																			<xsd:complexContent>
+																				<xsd:extension base="ppx:varList"/>
+																			</xsd:complexContent>
+																		</xsd:complexType>
+																	</xsd:element>
+																	<xsd:element name="tempVars">
+																		<xsd:complexType>
+																			<xsd:complexContent>
+																				<xsd:extension base="ppx:varList"/>
+																			</xsd:complexContent>
+																		</xsd:complexType>
+																	</xsd:element>
+																	<xsd:element name="inputVars">
+																		<xsd:complexType>
+																			<xsd:complexContent>
+																				<xsd:extension base="ppx:varList"/>
+																			</xsd:complexContent>
+																		</xsd:complexType>
+																	</xsd:element>
+																	<xsd:element name="outputVars">
+																		<xsd:complexType>
+																			<xsd:complexContent>
+																				<xsd:extension base="ppx:varList"/>
+																			</xsd:complexContent>
+																		</xsd:complexType>
+																	</xsd:element>
+																	<xsd:element name="inOutVars">
+																		<xsd:complexType>
+																			<xsd:complexContent>
+																				<xsd:extension base="ppx:varList"/>
+																			</xsd:complexContent>
+																		</xsd:complexType>
+																	</xsd:element>
+																	<xsd:element name="externalVars">
+																		<xsd:complexType>
+																			<xsd:complexContent>
+																				<xsd:extension base="ppx:varList"/>
+																			</xsd:complexContent>
+																		</xsd:complexType>
+																	</xsd:element>
+																	<xsd:element name="globalVars">
+																		<xsd:complexType>
+																			<xsd:complexContent>
+																				<xsd:extension base="ppx:varList"/>
+																			</xsd:complexContent>
+																		</xsd:complexType>
+																	</xsd:element>
+																	<xsd:element name="accessVars" type="ppx:varList"/>
+																</xsd:choice>
+																<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+																<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0">
+																	<xsd:annotation>
+																		<xsd:documentation>Additional userspecific information to the element</xsd:documentation>
+																	</xsd:annotation>
+																</xsd:element>
+															</xsd:sequence>
+														</xsd:complexType>
+													</xsd:element>
+													<xsd:element name="actions" minOccurs="0">
+														<xsd:complexType>
+															<xsd:sequence>
+																<xsd:element name="action" minOccurs="0" maxOccurs="unbounded">
+																	<xsd:complexType>
+																		<xsd:sequence>
+																			<xsd:element name="body" type="ppx:body"/>
+																			<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+																			<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0">
+																				<xsd:annotation>
+																					<xsd:documentation>Additional userspecific information to the element</xsd:documentation>
+																				</xsd:annotation>
+																			</xsd:element>
+																		</xsd:sequence>
+																		<xsd:attribute name="name" type="xsd:string" use="required"/>
+																		<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+																	</xsd:complexType>
+																</xsd:element>
+															</xsd:sequence>
+														</xsd:complexType>
+													</xsd:element>
+													<xsd:element name="transitions" minOccurs="0">
+														<xsd:complexType>
+															<xsd:sequence>
+																<xsd:element name="transition" minOccurs="0" maxOccurs="unbounded">
+																	<xsd:complexType>
+																		<xsd:sequence>
+																			<xsd:element name="body" type="ppx:body"/>
+																			<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+																			<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0">
+																				<xsd:annotation>
+																					<xsd:documentation>Additional userspecific information to the element</xsd:documentation>
+																				</xsd:annotation>
+																			</xsd:element>
+																		</xsd:sequence>
+																		<xsd:attribute name="name" type="xsd:string" use="required"/>
+																		<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+																	</xsd:complexType>
+																</xsd:element>
+															</xsd:sequence>
+														</xsd:complexType>
+													</xsd:element>
+													<xsd:element name="body" type="ppx:body" minOccurs="0" maxOccurs="unbounded"/>
+													<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+													<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0">
+														<xsd:annotation>
+															<xsd:documentation>Additional userspecific information to the element</xsd:documentation>
+														</xsd:annotation>
+													</xsd:element>
+												</xsd:sequence>
+												<xsd:attribute name="name" type="xsd:string" use="required"/>
+												<xsd:attribute name="pouType" type="ppx:pouType" use="required"/>
+												<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+											</xsd:complexType>
+										</xsd:element>
+									</xsd:sequence>
+								</xsd:complexType>
+							</xsd:element>
+						</xsd:sequence>
+					</xsd:complexType>
+				</xsd:element>
+				<xsd:element name="instances">
+					<xsd:complexType>
+						<xsd:sequence>
+							<xsd:element name="configurations">
+								<xsd:complexType>
+									<xsd:sequence>
+										<xsd:element name="configuration" minOccurs="0" maxOccurs="unbounded">
+											<xsd:complexType>
+												<xsd:annotation>
+													<xsd:documentation>Represents a group of resources and global variables</xsd:documentation>
+												</xsd:annotation>
+												<xsd:sequence>
+													<xsd:element name="resource" minOccurs="0" maxOccurs="unbounded">
+														<xsd:complexType>
+															<xsd:annotation>
+																<xsd:documentation>Represents a group of programs and tasks and global variables</xsd:documentation>
+															</xsd:annotation>
+															<xsd:sequence>
+																<xsd:element name="task" minOccurs="0" maxOccurs="unbounded">
+																	<xsd:complexType>
+																		<xsd:annotation>
+																			<xsd:documentation>Represents a periodic or triggered task</xsd:documentation>
+																		</xsd:annotation>
+																		<xsd:sequence>
+																			<xsd:element name="pouInstance" type="ppx:pouInstance" minOccurs="0" maxOccurs="unbounded"/>
+																			<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+																			<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0">
+																				<xsd:annotation>
+																					<xsd:documentation>Additional userspecific information to the element</xsd:documentation>
+																				</xsd:annotation>
+																			</xsd:element>
+																		</xsd:sequence>
+																		<xsd:attribute name="name" type="xsd:string" use="required"/>
+																		<xsd:attribute name="single" type="xsd:string" use="optional"/>
+																		<xsd:attribute name="interval" type="xsd:string" use="optional">
+																			<xsd:annotation>
+																				<xsd:documentation>Vendor specific: Either a constant duration as defined in the IEC or variable name.</xsd:documentation>
+																			</xsd:annotation>
+																		</xsd:attribute>
+																		<xsd:attribute name="priority" use="required">
+																			<xsd:simpleType>
+																				<xsd:restriction base="xsd:integer">
+																					<xsd:minInclusive value="0"/>
+																					<xsd:maxInclusive value="65535"/>
+																				</xsd:restriction>
+																			</xsd:simpleType>
+																		</xsd:attribute>
+																		<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+																	</xsd:complexType>
+																</xsd:element>
+																<xsd:element name="globalVars" type="ppx:varList" minOccurs="0" maxOccurs="unbounded"/>
+																<xsd:element name="pouInstance" type="ppx:pouInstance" minOccurs="0" maxOccurs="unbounded"/>
+																<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+																<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0">
+																	<xsd:annotation>
+																		<xsd:documentation>Additional userspecific information to the element</xsd:documentation>
+																	</xsd:annotation>
+																</xsd:element>
+															</xsd:sequence>
+															<xsd:attribute name="name" type="xsd:string" use="required"/>
+															<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+														</xsd:complexType>
+													</xsd:element>
+													<xsd:element name="globalVars" type="ppx:varList" minOccurs="0" maxOccurs="unbounded"/>
+													<xsd:element name="accessVars" type="ppx:varListAccess" minOccurs="0"/>
+													<xsd:element name="configVars" type="ppx:varListConfig" minOccurs="0"/>
+													<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+													<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0">
+														<xsd:annotation>
+															<xsd:documentation>Additional userspecific information to the element</xsd:documentation>
+														</xsd:annotation>
+													</xsd:element>
+												</xsd:sequence>
+												<xsd:attribute name="name" type="xsd:string" use="required"/>
+												<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+											</xsd:complexType>
+										</xsd:element>
+									</xsd:sequence>
+								</xsd:complexType>
+							</xsd:element>
+						</xsd:sequence>
+					</xsd:complexType>
+				</xsd:element>
+				<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+				<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0">
+					<xsd:annotation>
+						<xsd:documentation>Additional userspecific information to the element</xsd:documentation>
+					</xsd:annotation>
+				</xsd:element>
+			</xsd:sequence>
+		</xsd:complexType>
+	</xsd:element>
+	<xsd:complexType name="dataType">
+		<xsd:annotation>
+			<xsd:documentation>A generic data type</xsd:documentation>
+		</xsd:annotation>
+		<xsd:choice>
+			<xsd:group ref="ppx:elementaryTypes"/>
+			<xsd:group ref="ppx:derivedTypes"/>
+			<xsd:group ref="ppx:extended"/>
+		</xsd:choice>
+	</xsd:complexType>
+	<xsd:complexType name="rangeSigned">
+		<xsd:annotation>
+			<xsd:documentation>Defines a range with signed bounds</xsd:documentation>
+		</xsd:annotation>
+		<xsd:attribute name="lower" type="xsd:string" use="required"/>
+		<xsd:attribute name="upper" type="xsd:string" use="required"/>
+	</xsd:complexType>
+	<xsd:complexType name="rangeUnsigned">
+		<xsd:annotation>
+			<xsd:documentation>Defines a range with unsigned bounds</xsd:documentation>
+		</xsd:annotation>
+		<xsd:attribute name="lower" type="xsd:string" use="required"/>
+		<xsd:attribute name="upper" type="xsd:string" use="required"/>
+	</xsd:complexType>
+	<xsd:complexType name="value">
+		<xsd:annotation>
+			<xsd:documentation>A generic value</xsd:documentation>
+		</xsd:annotation>
+		<xsd:choice>
+			<xsd:element name="simpleValue">
+				<xsd:complexType>
+					<xsd:annotation>
+						<xsd:documentation>Value that can be represented as a single token string </xsd:documentation>
+					</xsd:annotation>
+					<xsd:attribute name="value" type="xsd:string" use="optional"/>
+				</xsd:complexType>
+			</xsd:element>
+			<xsd:element name="arrayValue">
+				<xsd:complexType>
+					<xsd:annotation>
+						<xsd:documentation>Array value consisting of a list of occurrances - value pairs</xsd:documentation>
+					</xsd:annotation>
+					<xsd:sequence minOccurs="0" maxOccurs="unbounded">
+						<xsd:element name="value">
+							<xsd:complexType>
+								<xsd:complexContent>
+									<xsd:extension base="ppx:value">
+										<xsd:attribute name="repetitionValue" type="xsd:string" use="optional" default="1"/>
+									</xsd:extension>
+								</xsd:complexContent>
+							</xsd:complexType>
+						</xsd:element>
+					</xsd:sequence>
+				</xsd:complexType>
+			</xsd:element>
+			<xsd:element name="structValue">
+				<xsd:complexType>
+					<xsd:annotation>
+						<xsd:documentation>Struct value consisting of a list of member - value pairs</xsd:documentation>
+					</xsd:annotation>
+					<xsd:sequence minOccurs="0" maxOccurs="unbounded">
+						<xsd:element name="value">
+							<xsd:complexType>
+								<xsd:complexContent>
+									<xsd:extension base="ppx:value">
+										<xsd:attribute name="member" type="xsd:string" use="required"/>
+									</xsd:extension>
+								</xsd:complexContent>
+							</xsd:complexType>
+						</xsd:element>
+					</xsd:sequence>
+				</xsd:complexType>
+			</xsd:element>
+		</xsd:choice>
+	</xsd:complexType>
+	<xsd:complexType name="body">
+		<xsd:annotation>
+			<xsd:documentation>Implementation part of a POU, action or transistion</xsd:documentation>
+		</xsd:annotation>
+		<xsd:sequence>
+			<xsd:choice>
+				<xsd:element name="IL" type="ppx:formattedText"/>
+				<xsd:element name="ST" type="ppx:formattedText"/>
+				<xsd:element name="FBD">
+					<xsd:complexType>
+						<xsd:choice minOccurs="0" maxOccurs="unbounded">
+							<xsd:group ref="ppx:commonObjects"/>
+							<xsd:group ref="ppx:fbdObjects"/>
+						</xsd:choice>
+					</xsd:complexType>
+				</xsd:element>
+				<xsd:element name="LD">
+					<xsd:complexType>
+						<xsd:choice minOccurs="0" maxOccurs="unbounded">
+							<xsd:group ref="ppx:commonObjects"/>
+							<xsd:group ref="ppx:fbdObjects"/>
+							<xsd:group ref="ppx:ldObjects"/>
+						</xsd:choice>
+					</xsd:complexType>
+				</xsd:element>
+				<xsd:element name="SFC">
+					<xsd:complexType>
+						<xsd:choice minOccurs="0" maxOccurs="unbounded">
+							<xsd:group ref="ppx:commonObjects"/>
+							<xsd:group ref="ppx:fbdObjects"/>
+							<xsd:group ref="ppx:ldObjects"/>
+							<xsd:group ref="ppx:sfcObjects"/>
+						</xsd:choice>
+					</xsd:complexType>
+				</xsd:element>
+			</xsd:choice>
+			<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+			<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0">
+				<xsd:annotation>
+					<xsd:documentation>Additional userspecific information to the element</xsd:documentation>
+				</xsd:annotation>
+			</xsd:element>
+		</xsd:sequence>
+		<xsd:attribute name="WorksheetName" type="xsd:string" use="optional"/>
+		<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+	</xsd:complexType>
+	<xsd:complexType name="varList">
+		<xsd:annotation>
+			<xsd:documentation>List of variable declarations that share the same memory attributes (CONSTANT, RETAIN, NON_RETAIN, PERSISTENT)</xsd:documentation>
+		</xsd:annotation>
+		<xsd:complexContent>
+			<xsd:extension base="ppx:varListPlain">
+				<xsd:attribute name="name" type="xsd:string" use="optional"/>
+				<xsd:attribute name="constant" type="xsd:boolean" use="optional" default="false"/>
+				<xsd:attribute name="retain" type="xsd:boolean" use="optional" default="false"/>
+				<xsd:attribute name="nonretain" type="xsd:boolean" use="optional" default="false"/>
+				<xsd:attribute name="persistent" type="xsd:boolean" use="optional" default="false"/>
+				<xsd:attribute name="nonpersistent" type="xsd:boolean" use="optional" default="false"/>
+			</xsd:extension>
+		</xsd:complexContent>
+	</xsd:complexType>
+	<xsd:complexType name="varListPlain">
+		<xsd:annotation>
+			<xsd:documentation>List of variable declarations without attributes</xsd:documentation>
+		</xsd:annotation>
+		<xsd:sequence>
+			<xsd:element name="variable" minOccurs="0" maxOccurs="unbounded">
+				<xsd:complexType>
+					<xsd:annotation>
+						<xsd:documentation>Declaration of a variable</xsd:documentation>
+					</xsd:annotation>
+					<xsd:sequence>
+						<xsd:element name="type" type="ppx:dataType"/>
+						<xsd:element name="initialValue" type="ppx:value" minOccurs="0"/>
+						<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+						<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+					</xsd:sequence>
+					<xsd:attribute name="name" type="xsd:string" use="required"/>
+					<xsd:attribute name="address" type="xsd:string" use="optional"/>
+					<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+				</xsd:complexType>
+			</xsd:element>
+			<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+			<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:complexType name="varListAccess">
+		<xsd:annotation>
+			<xsd:documentation>List of access variable declarations</xsd:documentation>
+		</xsd:annotation>
+		<xsd:sequence>
+			<xsd:element name="accessVariable" minOccurs="0" maxOccurs="unbounded">
+				<xsd:complexType>
+					<xsd:annotation>
+						<xsd:documentation>Declaration of an access variable</xsd:documentation>
+					</xsd:annotation>
+					<xsd:sequence>
+						<xsd:element name="type" type="ppx:dataType"/>
+						<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+						<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+					</xsd:sequence>
+					<xsd:attribute name="alias" type="xsd:string" use="required">
+						<xsd:annotation>
+							<xsd:documentation>Name that is visible to the communication partner</xsd:documentation>
+						</xsd:annotation>
+					</xsd:attribute>
+					<xsd:attribute name="instancePathAndName" type="xsd:string" use="required">
+						<xsd:annotation>
+							<xsd:documentation>Variable name including instance path inside the configuration</xsd:documentation>
+						</xsd:annotation>
+					</xsd:attribute>
+					<xsd:attribute name="direction" type="ppx:accessType" use="optional"/>
+				</xsd:complexType>
+			</xsd:element>
+			<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+			<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:complexType name="varListConfig">
+		<xsd:annotation>
+			<xsd:documentation>List of VAR_CONFIG variables</xsd:documentation>
+		</xsd:annotation>
+		<xsd:sequence>
+			<xsd:element name="configVariable" minOccurs="0" maxOccurs="unbounded">
+				<xsd:complexType>
+					<xsd:annotation>
+						<xsd:documentation>Declaration of an access variable</xsd:documentation>
+					</xsd:annotation>
+					<xsd:sequence>
+						<xsd:element name="type" type="ppx:dataType"/>
+						<xsd:element name="initialValue" type="ppx:value" minOccurs="0"/>
+						<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+						<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+					</xsd:sequence>
+					<xsd:attribute name="instancePathAndName" type="xsd:string" use="required">
+						<xsd:annotation>
+							<xsd:documentation>Variable name including instance path</xsd:documentation>
+						</xsd:annotation>
+					</xsd:attribute>
+					<xsd:attribute name="address" type="xsd:string" use="optional"/>
+				</xsd:complexType>
+			</xsd:element>
+			<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+			<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:complexType name="position">
+		<xsd:annotation>
+			<xsd:documentation>Defines a graphical position in X, Y coordinates</xsd:documentation>
+		</xsd:annotation>
+		<xsd:attribute name="x" type="xsd:decimal" use="required"/>
+		<xsd:attribute name="y" type="xsd:decimal" use="required"/>
+	</xsd:complexType>
+	<xsd:complexType name="connection">
+		<xsd:annotation>
+			<xsd:documentation>Describes a connection between the consumer element (eg. input variable of a function block) and the producer element (eg. output variable of a function block). It may contain a list of positions that describes the path of the connection.</xsd:documentation>
+		</xsd:annotation>
+		<xsd:sequence>
+			<xsd:element name="position" type="ppx:position" minOccurs="0" maxOccurs="unbounded">
+				<xsd:annotation>
+					<xsd:documentation>All positions of the directed connection path. If any positions are given, the list has to contain the first (input pin of the consumer element) as well as the last (output pin of the producer element).</xsd:documentation>
+				</xsd:annotation>
+			</xsd:element>
+			<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+		</xsd:sequence>
+		<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+		<xsd:attribute name="refLocalId" type="xsd:unsignedLong" use="required">
+			<xsd:annotation>
+				<xsd:documentation>Identifies the element the connection starts from.</xsd:documentation>
+			</xsd:annotation>
+		</xsd:attribute>
+		<xsd:attribute name="formalParameter" type="xsd:string" use="optional">
+			<xsd:annotation>
+				<xsd:documentation>If present:
+	  This attribute denotes the name of the VAR_OUTPUT / VAR_IN_OUTparameter of the pou block that is the start of the connection.
+	  If not present:
+	  If the refLocalId attribute refers to a pou block, the start of the connection is the first output of this block, which is not ENO.
+	  If the refLocalId attribute refers to any other element type, the start of the connection is the elements single native output. </xsd:documentation>
+			</xsd:annotation>
+		</xsd:attribute>
+	</xsd:complexType>
+	<xsd:complexType name="connectionPointIn">
+		<xsd:annotation>
+			<xsd:documentation>Defines a connection point on the consumer side</xsd:documentation>
+		</xsd:annotation>
+		<xsd:sequence>
+			<xsd:element name="relPosition" type="ppx:position" minOccurs="0">
+				<xsd:annotation>
+					<xsd:documentation>Relative position of the connection pin. Origin is the anchor position of the block.</xsd:documentation>
+				</xsd:annotation>
+			</xsd:element>
+			<xsd:choice minOccurs="0">
+				<xsd:element name="connection" type="ppx:connection" maxOccurs="unbounded"/>
+				<xsd:element name="expression" type="xsd:string">
+					<xsd:annotation>
+						<xsd:documentation>The operand is a valid iec variable e.g. avar[0] or an iec expression or multiple token text e.g. a + b (*sum*). An iec 61131-3 parser has to be used to extract variable information.</xsd:documentation>
+					</xsd:annotation>
+				</xsd:element>
+			</xsd:choice>
+			<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+		</xsd:sequence>
+		<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+	</xsd:complexType>
+	<xsd:complexType name="connectionPointOut">
+		<xsd:annotation>
+			<xsd:documentation>Defines a connection point on the producer side</xsd:documentation>
+		</xsd:annotation>
+		<xsd:sequence>
+			<xsd:element name="relPosition" type="ppx:position" minOccurs="0">
+				<xsd:annotation>
+					<xsd:documentation>Relative position of the connection pin. Origin is the anchor position of the block.</xsd:documentation>
+				</xsd:annotation>
+			</xsd:element>
+			<xsd:element name="expression" type="xsd:string" minOccurs="0">
+				<xsd:annotation>
+					<xsd:documentation>The operand is a valid iec variable e.g. avar[0].</xsd:documentation>
+				</xsd:annotation>
+			</xsd:element>
+			<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+		</xsd:sequence>
+		<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+	</xsd:complexType>
+	<xsd:complexType name="pouInstance">
+		<xsd:annotation>
+			<xsd:documentation>Represents a program or function block instance either running with or without a task</xsd:documentation>
+		</xsd:annotation>
+		<xsd:sequence>
+			<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+			<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+		</xsd:sequence>
+		<xsd:attribute name="name" type="xsd:string" use="required"/>
+		<xsd:attribute name="typeName" type="xsd:string" use="required"/>
+		<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+	</xsd:complexType>
+	<xsd:complexType name="formattedText">
+		<xsd:annotation>
+			<xsd:documentation>Formatted text according to parts of XHTML 1.1</xsd:documentation>
+		</xsd:annotation>
+		<xsd:sequence>
+			<xsd:any namespace="http://www.w3.org/1999/xhtml" processContents="lax"/>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:complexType name="addData">
+		<xsd:annotation>
+			<xsd:documentation>Application specific data defined in external schemata </xsd:documentation>
+		</xsd:annotation>
+		<xsd:sequence>
+			<xsd:element name="data" minOccurs="0" maxOccurs="unbounded">
+				<xsd:complexType>
+					<xsd:sequence>
+						<xsd:any namespace="##any" processContents="lax"/>
+					</xsd:sequence>
+					<xsd:attribute name="name" type="xsd:anyURI" use="required">
+						<xsd:annotation>
+							<xsd:documentation>Uniquely identifies the additional data element.</xsd:documentation>
+						</xsd:annotation>
+					</xsd:attribute>
+					<xsd:attribute name="handleUnknown" use="required">
+						<xsd:annotation>
+							<xsd:documentation>Recommended processor handling for unknown data elements.
+Specifies if the processor should try to preserve the additional data element, dismiss the element (e.g. because the data is invalid if not updated correctly) or use the processors default behaviour for unknown data.</xsd:documentation>
+						</xsd:annotation>
+						<xsd:simpleType>
+							<xsd:restriction base="xsd:NMTOKEN">
+								<xsd:enumeration value="preserve"/>
+								<xsd:enumeration value="discard"/>
+								<xsd:enumeration value="implementation"/>
+							</xsd:restriction>
+						</xsd:simpleType>
+					</xsd:attribute>
+				</xsd:complexType>
+			</xsd:element>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:complexType name="addDataInfo">
+		<xsd:annotation>
+			<xsd:documentation>List of additional data elements used in the document with description</xsd:documentation>
+		</xsd:annotation>
+		<xsd:sequence>
+			<xsd:element name="info" minOccurs="0" maxOccurs="unbounded">
+				<xsd:complexType>
+					<xsd:sequence>
+						<xsd:element name="description" type="ppx:formattedText" minOccurs="0"/>
+					</xsd:sequence>
+					<xsd:attribute name="name" type="xsd:anyURI" use="required">
+						<xsd:annotation>
+							<xsd:documentation>Unique name of the additional data element.</xsd:documentation>
+						</xsd:annotation>
+					</xsd:attribute>
+					<xsd:attribute name="version" type="xsd:decimal">
+						<xsd:annotation>
+							<xsd:documentation>Version of additional data, eg. schema version.</xsd:documentation>
+						</xsd:annotation>
+					</xsd:attribute>
+					<xsd:attribute name="vendor" type="xsd:anyURI" use="required">
+						<xsd:annotation>
+							<xsd:documentation>Vendor responsible for the definition of the additional data element.</xsd:documentation>
+						</xsd:annotation>
+					</xsd:attribute>
+				</xsd:complexType>
+			</xsd:element>
+		</xsd:sequence>
+	</xsd:complexType>
+	<xsd:group name="elementaryTypes">
+		<xsd:annotation>
+			<xsd:documentation>Collection of elementary IEC 61131-3 datatypes</xsd:documentation>
+		</xsd:annotation>
+		<xsd:choice>
+			<xsd:element name="BOOL"/>
+			<xsd:element name="BYTE"/>
+			<xsd:element name="WORD"/>
+			<xsd:element name="DWORD"/>
+			<xsd:element name="LWORD"/>
+			<xsd:element name="SINT"/>
+			<xsd:element name="INT"/>
+			<xsd:element name="DINT"/>
+			<xsd:element name="LINT"/>
+			<xsd:element name="USINT"/>
+			<xsd:element name="UINT"/>
+			<xsd:element name="UDINT"/>
+			<xsd:element name="ULINT"/>
+			<xsd:element name="REAL"/>
+			<xsd:element name="LREAL"/>
+			<xsd:element name="TIME"/>
+			<xsd:element name="DATE"/>
+			<xsd:element name="DT"/>
+			<xsd:element name="TOD"/>
+			<xsd:element name="string">
+				<xsd:complexType>
+					<xsd:annotation>
+						<xsd:documentation>The single byte character string type</xsd:documentation>
+					</xsd:annotation>
+					<xsd:attribute name="length" type="xsd:string" use="optional"/>
+				</xsd:complexType>
+			</xsd:element>
+			<xsd:element name="wstring">
+				<xsd:complexType>
+					<xsd:annotation>
+						<xsd:documentation>The wide character (WORD) string type</xsd:documentation>
+					</xsd:annotation>
+					<xsd:attribute name="length" type="xsd:string" use="optional"/>
+				</xsd:complexType>
+			</xsd:element>
+			<xsd:element name="ANY"/>
+			<xsd:element name="ANY_DERIVED"/>
+			<xsd:element name="ANY_ELEMENTARY"/>
+			<xsd:element name="ANY_MAGNITUDE"/>
+			<xsd:element name="ANY_NUM"/>
+			<xsd:element name="ANY_REAL"/>
+			<xsd:element name="ANY_INT"/>
+			<xsd:element name="ANY_BIT"/>
+			<xsd:element name="ANY_STRING"/>
+			<xsd:element name="ANY_DATE"/>
+		</xsd:choice>
+	</xsd:group>
+	<xsd:group name="derivedTypes">
+		<xsd:annotation>
+			<xsd:documentation>Collection of derived IEC 61131-3 datatypes</xsd:documentation>
+		</xsd:annotation>
+		<xsd:choice>
+			<xsd:element name="array">
+				<xsd:complexType>
+					<xsd:sequence>
+						<xsd:element name="dimension" type="ppx:rangeSigned" maxOccurs="unbounded"/>
+						<xsd:element name="baseType" type="ppx:dataType"/>
+					</xsd:sequence>
+				</xsd:complexType>
+			</xsd:element>
+			<xsd:element name="derived">
+				<xsd:annotation>
+					<xsd:documentation>Reference to a user defined datatype or POU. Variable declarations use this type to declare e.g. function block instances.</xsd:documentation>
+				</xsd:annotation>
+				<xsd:complexType>
+					<xsd:annotation>
+						<xsd:documentation>The user defined alias type</xsd:documentation>
+					</xsd:annotation>
+					<xsd:sequence>
+						<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+					</xsd:sequence>
+					<xsd:attribute name="name" type="xsd:string" use="required"/>
+				</xsd:complexType>
+			</xsd:element>
+			<xsd:element name="enum">
+				<xsd:complexType>
+					<xsd:sequence>
+						<xsd:element name="values">
+							<xsd:complexType>
+								<xsd:sequence maxOccurs="unbounded">
+									<xsd:element name="value">
+										<xsd:complexType>
+											<xsd:annotation>
+												<xsd:documentation>An enumeration value used to build up enumeration types</xsd:documentation>
+											</xsd:annotation>
+											<xsd:attribute name="name" type="xsd:string" use="required"/>
+											<xsd:attribute name="value" type="xsd:string" use="optional"/>
+										</xsd:complexType>
+									</xsd:element>
+								</xsd:sequence>
+							</xsd:complexType>
+						</xsd:element>
+						<xsd:element name="baseType" type="ppx:dataType" minOccurs="0"/>
+					</xsd:sequence>
+				</xsd:complexType>
+			</xsd:element>
+			<xsd:element name="struct" type="ppx:varListPlain"/>
+			<xsd:element name="subrangeSigned">
+				<xsd:complexType>
+					<xsd:sequence>
+						<xsd:element name="range" type="ppx:rangeSigned"/>
+						<xsd:element name="baseType" type="ppx:dataType"/>
+					</xsd:sequence>
+				</xsd:complexType>
+			</xsd:element>
+			<xsd:element name="subrangeUnsigned">
+				<xsd:complexType>
+					<xsd:sequence>
+						<xsd:element name="range" type="ppx:rangeUnsigned"/>
+						<xsd:element name="baseType" type="ppx:dataType"/>
+					</xsd:sequence>
+				</xsd:complexType>
+			</xsd:element>
+		</xsd:choice>
+	</xsd:group>
+	<xsd:group name="extended">
+		<xsd:annotation>
+			<xsd:documentation>Collection of datatypes not defined in IEC 61131-3</xsd:documentation>
+		</xsd:annotation>
+		<xsd:choice>
+			<xsd:element name="pointer">
+				<xsd:complexType>
+					<xsd:sequence>
+						<xsd:element name="baseType" type="ppx:dataType"/>
+					</xsd:sequence>
+				</xsd:complexType>
+			</xsd:element>
+		</xsd:choice>
+	</xsd:group>
+	<xsd:group name="commonObjects">
+		<xsd:annotation>
+			<xsd:documentation>Collection of objects which have no direct iec scope and can be used in any graphical body.</xsd:documentation>
+		</xsd:annotation>
+		<xsd:choice>
+			<xsd:element name="comment">
+				<xsd:complexType>
+					<xsd:sequence>
+						<xsd:element name="position" type="ppx:position"/>
+						<xsd:element name="content" type="ppx:formattedText"/>
+						<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+						<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+					</xsd:sequence>
+					<xsd:attribute name="localId" type="xsd:unsignedLong" use="required"/>
+					<xsd:attribute name="height" type="xsd:decimal" use="required"/>
+					<xsd:attribute name="width" type="xsd:decimal" use="required"/>
+					<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+				</xsd:complexType>
+			</xsd:element>
+			<xsd:element name="error">
+				<xsd:complexType mixed="false">
+					<xsd:annotation>
+						<xsd:documentation>Describes a graphical object representing a conversion error. Used to keep information which can not be interpreted by the importing system</xsd:documentation>
+					</xsd:annotation>
+					<xsd:sequence>
+						<xsd:element name="position" type="ppx:position"/>
+						<xsd:element name="content" type="ppx:formattedText"/>
+						<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+						<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+					</xsd:sequence>
+					<xsd:attribute name="localId" type="xsd:unsignedLong" use="required"/>
+					<xsd:attribute name="height" type="xsd:decimal" use="required"/>
+					<xsd:attribute name="width" type="xsd:decimal" use="required"/>
+					<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+				</xsd:complexType>
+			</xsd:element>
+			<xsd:element name="connector">
+				<xsd:complexType>
+					<xsd:annotation>
+						<xsd:documentation>Describes a graphical object representing a variable, literal or expression used as r-value</xsd:documentation>
+					</xsd:annotation>
+					<xsd:sequence>
+						<xsd:element name="position" type="ppx:position"/>
+						<xsd:element name="connectionPointIn" type="ppx:connectionPointIn" minOccurs="0"/>
+						<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+						<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+					</xsd:sequence>
+					<xsd:attribute name="name" type="xsd:string" use="required">
+						<xsd:annotation>
+							<xsd:documentation>The operand is a valid iec variable e.g. avar[0]</xsd:documentation>
+						</xsd:annotation>
+					</xsd:attribute>
+					<xsd:attribute name="localId" type="xsd:unsignedLong" use="required"/>
+					<xsd:attribute name="height" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="width" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+				</xsd:complexType>
+			</xsd:element>
+			<xsd:element name="continuation">
+				<xsd:annotation>
+					<xsd:documentation>Counterpart of the connector element</xsd:documentation>
+				</xsd:annotation>
+				<xsd:complexType>
+					<xsd:annotation>
+						<xsd:documentation>Describes a graphical object representing a variable, literal or expression used as r-value</xsd:documentation>
+					</xsd:annotation>
+					<xsd:sequence>
+						<xsd:element name="position" type="ppx:position"/>
+						<xsd:element name="connectionPointOut" type="ppx:connectionPointOut" minOccurs="0"/>
+						<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+						<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+					</xsd:sequence>
+					<xsd:attribute name="name" type="xsd:string" use="required">
+						<xsd:annotation>
+							<xsd:documentation>The operand is a valid iec variable e.g. avar[0]</xsd:documentation>
+						</xsd:annotation>
+					</xsd:attribute>
+					<xsd:attribute name="localId" type="xsd:unsignedLong" use="required"/>
+					<xsd:attribute name="height" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="width" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+				</xsd:complexType>
+			</xsd:element>
+			<xsd:element name="actionBlock">
+				<xsd:complexType>
+					<xsd:sequence>
+						<xsd:element name="position" type="ppx:position"/>
+						<xsd:element name="connectionPointIn" type="ppx:connectionPointIn" minOccurs="0"/>
+						<xsd:element name="action" minOccurs="0" maxOccurs="unbounded">
+							<xsd:complexType>
+								<xsd:annotation>
+									<xsd:documentation>Association of an action with qualifier</xsd:documentation>
+								</xsd:annotation>
+								<xsd:sequence>
+									<xsd:element name="relPosition" type="ppx:position">
+										<xsd:annotation>
+											<xsd:documentation>Relative position of the action. Origin is the anchor position of the action block.</xsd:documentation>
+										</xsd:annotation>
+									</xsd:element>
+									<xsd:element name="reference" minOccurs="0">
+										<xsd:annotation>
+											<xsd:documentation>Name of an action or boolean variable.</xsd:documentation>
+										</xsd:annotation>
+										<xsd:complexType>
+											<xsd:attribute name="name" type="xsd:string" use="required"/>
+										</xsd:complexType>
+									</xsd:element>
+									<xsd:element name="inline" type="ppx:body" minOccurs="0">
+										<xsd:annotation>
+											<xsd:documentation>Inline implementation of an action body.</xsd:documentation>
+										</xsd:annotation>
+									</xsd:element>
+									<xsd:element name="connectionPointOut" type="ppx:connectionPointOut" minOccurs="0"/>
+									<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+									<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+								</xsd:sequence>
+								<xsd:attribute name="localId" type="xsd:unsignedLong" use="required"/>
+								<xsd:attribute name="qualifier" use="optional" default="N">
+									<xsd:simpleType>
+										<xsd:restriction base="xsd:NMTOKEN">
+											<xsd:enumeration value="P1"/>
+											<xsd:enumeration value="N"/>
+											<xsd:enumeration value="P0"/>
+											<xsd:enumeration value="R"/>
+											<xsd:enumeration value="S"/>
+											<xsd:enumeration value="L"/>
+											<xsd:enumeration value="D"/>
+											<xsd:enumeration value="P"/>
+											<xsd:enumeration value="DS"/>
+											<xsd:enumeration value="DL"/>
+											<xsd:enumeration value="SD"/>
+											<xsd:enumeration value="SL"/>
+										</xsd:restriction>
+									</xsd:simpleType>
+								</xsd:attribute>
+								<xsd:attribute name="width" type="xsd:decimal" use="optional"/>
+								<xsd:attribute name="height" type="xsd:decimal" use="optional"/>
+								<xsd:attribute name="duration" type="xsd:string" use="optional"/>
+								<xsd:attribute name="indicator" type="xsd:string" use="optional"/>
+								<xsd:attribute name="executionOrderId" type="xsd:unsignedLong" use="optional">
+									<xsd:annotation>
+										<xsd:documentation>Used to identify the order of execution. Also used to identify one special block if there are several blocks with the same name.</xsd:documentation>
+									</xsd:annotation>
+								</xsd:attribute>
+								<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+							</xsd:complexType>
+						</xsd:element>
+						<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+						<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+					</xsd:sequence>
+					<xsd:attribute name="localId" type="xsd:unsignedLong" use="required"/>
+					<xsd:attribute name="negated" type="xsd:boolean" use="optional" default="false"/>
+					<xsd:attribute name="width" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="height" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="executionOrderId" type="xsd:unsignedLong" use="optional">
+						<xsd:annotation>
+							<xsd:documentation>Used to identify the order of execution. Also used to identify one special block if there are several blocks with the same name.</xsd:documentation>
+						</xsd:annotation>
+					</xsd:attribute>
+					<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+				</xsd:complexType>
+			</xsd:element>
+			<xsd:element name="vendorElement">
+				<xsd:complexType>
+					<xsd:annotation>
+						<xsd:documentation>Describes a graphical object representing a call statement</xsd:documentation>
+					</xsd:annotation>
+					<xsd:sequence>
+						<xsd:element name="position" type="ppx:position">
+							<xsd:annotation>
+								<xsd:documentation>Anchor position of the box. Top left corner excluding the instance name.</xsd:documentation>
+							</xsd:annotation>
+						</xsd:element>
+						<xsd:element name="alternativeText" type="ppx:formattedText">
+							<xsd:annotation>
+								<xsd:documentation>An alternative text to be displayed in generic representation of unknown elements.</xsd:documentation>
+							</xsd:annotation>
+						</xsd:element>
+						<xsd:element name="inputVariables" minOccurs="0">
+							<xsd:annotation>
+								<xsd:documentation>The list of used input variables (consumers)</xsd:documentation>
+							</xsd:annotation>
+							<xsd:complexType>
+								<xsd:sequence>
+									<xsd:element name="variable" minOccurs="0" maxOccurs="unbounded">
+										<xsd:complexType>
+											<xsd:annotation>
+												<xsd:documentation>Describes an inputVariable of a Function or a FunctionBlock</xsd:documentation>
+											</xsd:annotation>
+											<xsd:sequence>
+												<xsd:element name="connectionPointIn" type="ppx:connectionPointIn"/>
+												<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+											</xsd:sequence>
+											<xsd:attribute name="formalParameter" type="xsd:string" use="required"/>
+											<xsd:attribute name="negated" type="xsd:boolean" use="optional" default="false"/>
+											<xsd:attribute name="edge" type="ppx:edgeModifierType" use="optional" default="none"/>
+											<xsd:attribute name="storage" type="ppx:storageModifierType" use="optional" default="none"/>
+											<xsd:attribute name="hidden" type="xsd:boolean" use="optional" default="false"/>
+										</xsd:complexType>
+									</xsd:element>
+								</xsd:sequence>
+							</xsd:complexType>
+						</xsd:element>
+						<xsd:element name="inOutVariables" minOccurs="0">
+							<xsd:annotation>
+								<xsd:documentation>The list of used inOut variables</xsd:documentation>
+							</xsd:annotation>
+							<xsd:complexType>
+								<xsd:sequence>
+									<xsd:element name="variable" minOccurs="0" maxOccurs="unbounded">
+										<xsd:complexType>
+											<xsd:annotation>
+												<xsd:documentation>Describes a inOutVariable of a Function or a FunctionBlock</xsd:documentation>
+											</xsd:annotation>
+											<xsd:sequence>
+												<xsd:element name="connectionPointIn" type="ppx:connectionPointIn" minOccurs="0"/>
+												<xsd:element name="connectionPointOut" type="ppx:connectionPointOut" minOccurs="0"/>
+												<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+											</xsd:sequence>
+											<xsd:attribute name="formalParameter" type="xsd:string" use="required"/>
+											<xsd:attribute name="negated" type="xsd:boolean" use="optional" default="false"/>
+											<xsd:attribute name="edge" type="ppx:edgeModifierType" use="optional" default="none"/>
+											<xsd:attribute name="storage" type="ppx:storageModifierType" use="optional" default="none"/>
+											<xsd:attribute name="hidden" type="xsd:boolean" use="optional" default="false"/>
+										</xsd:complexType>
+									</xsd:element>
+								</xsd:sequence>
+							</xsd:complexType>
+						</xsd:element>
+						<xsd:element name="outputVariables" minOccurs="0">
+							<xsd:annotation>
+								<xsd:documentation>The list of used output variables (producers)</xsd:documentation>
+							</xsd:annotation>
+							<xsd:complexType>
+								<xsd:sequence>
+									<xsd:element name="variable" minOccurs="0" maxOccurs="unbounded">
+										<xsd:complexType>
+											<xsd:annotation>
+												<xsd:documentation>Describes a outputVariable of a Function or a FunctionBlock</xsd:documentation>
+											</xsd:annotation>
+											<xsd:sequence>
+												<xsd:element name="connectionPointOut" type="ppx:connectionPointOut" minOccurs="0"/>
+												<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+											</xsd:sequence>
+											<xsd:attribute name="formalParameter" type="xsd:string" use="required"/>
+											<xsd:attribute name="negated" type="xsd:boolean" use="optional" default="false"/>
+											<xsd:attribute name="edge" type="ppx:edgeModifierType" use="optional" default="none"/>
+											<xsd:attribute name="storage" type="ppx:storageModifierType" use="optional" default="none"/>
+											<xsd:attribute name="hidden" type="xsd:boolean" use="optional" default="false"/>
+										</xsd:complexType>
+									</xsd:element>
+								</xsd:sequence>
+							</xsd:complexType>
+						</xsd:element>
+						<xsd:element name="addData" type="ppx:addData">
+							<xsd:annotation>
+								<xsd:documentation>Additional, vendor specific data for the element. Also defines the vendor specific meaning of the element.</xsd:documentation>
+							</xsd:annotation>
+						</xsd:element>
+					</xsd:sequence>
+					<xsd:attribute name="localId" type="xsd:unsignedLong" use="required"/>
+					<xsd:attribute name="width" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="height" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="executionOrderId" type="xsd:unsignedLong" use="optional">
+						<xsd:annotation>
+							<xsd:documentation>Used to identify the order of execution. Also used to identify one special block if there are several blocks with the same name.</xsd:documentation>
+						</xsd:annotation>
+					</xsd:attribute>
+					<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+				</xsd:complexType>
+			</xsd:element>
+		</xsd:choice>
+	</xsd:group>
+	<xsd:group name="fbdObjects">
+		<xsd:annotation>
+			<xsd:documentation>Collection of objects which are defined in fbd. They can be used in all graphical bodies.</xsd:documentation>
+		</xsd:annotation>
+		<xsd:choice>
+			<xsd:element name="block">
+				<xsd:complexType>
+					<xsd:annotation>
+						<xsd:documentation>Describes a graphical object representing a call statement</xsd:documentation>
+					</xsd:annotation>
+					<xsd:sequence>
+						<xsd:element name="position" type="ppx:position">
+							<xsd:annotation>
+								<xsd:documentation>Anchor position of the box. Top left corner excluding the instance name.</xsd:documentation>
+							</xsd:annotation>
+						</xsd:element>
+						<xsd:element name="inputVariables">
+							<xsd:annotation>
+								<xsd:documentation>The list of used input variables (consumers)</xsd:documentation>
+							</xsd:annotation>
+							<xsd:complexType>
+								<xsd:sequence>
+									<xsd:element name="variable" minOccurs="0" maxOccurs="unbounded">
+										<xsd:complexType>
+											<xsd:annotation>
+												<xsd:documentation>Describes an inputVariable of a Function or a FunctionBlock</xsd:documentation>
+											</xsd:annotation>
+											<xsd:sequence>
+												<xsd:element name="connectionPointIn" type="ppx:connectionPointIn"/>
+												<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+											</xsd:sequence>
+											<xsd:attribute name="formalParameter" type="xsd:string" use="required"/>
+											<xsd:attribute name="negated" type="xsd:boolean" use="optional" default="false"/>
+											<xsd:attribute name="edge" type="ppx:edgeModifierType" use="optional" default="none"/>
+											<xsd:attribute name="storage" type="ppx:storageModifierType" use="optional" default="none"/>
+											<xsd:attribute name="hidden" type="xsd:boolean" use="optional" default="false"/>
+										</xsd:complexType>
+									</xsd:element>
+								</xsd:sequence>
+							</xsd:complexType>
+						</xsd:element>
+						<xsd:element name="inOutVariables">
+							<xsd:annotation>
+								<xsd:documentation>The list of used inOut variables</xsd:documentation>
+							</xsd:annotation>
+							<xsd:complexType>
+								<xsd:sequence>
+									<xsd:element name="variable" minOccurs="0" maxOccurs="unbounded">
+										<xsd:complexType>
+											<xsd:annotation>
+												<xsd:documentation>Describes a inOutVariable of a Function or a FunctionBlock</xsd:documentation>
+											</xsd:annotation>
+											<xsd:sequence>
+												<xsd:element name="connectionPointIn" type="ppx:connectionPointIn" minOccurs="0"/>
+												<xsd:element name="connectionPointOut" type="ppx:connectionPointOut" minOccurs="0"/>
+												<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+											</xsd:sequence>
+											<xsd:attribute name="formalParameter" type="xsd:string" use="required"/>
+											<xsd:attribute name="negated" type="xsd:boolean" use="optional" default="false"/>
+											<xsd:attribute name="edge" type="ppx:edgeModifierType" use="optional" default="none"/>
+											<xsd:attribute name="storage" type="ppx:storageModifierType" use="optional" default="none"/>
+											<xsd:attribute name="hidden" type="xsd:boolean" use="optional" default="false"/>
+										</xsd:complexType>
+									</xsd:element>
+								</xsd:sequence>
+							</xsd:complexType>
+						</xsd:element>
+						<xsd:element name="outputVariables">
+							<xsd:annotation>
+								<xsd:documentation>The list of used output variables (producers)</xsd:documentation>
+							</xsd:annotation>
+							<xsd:complexType>
+								<xsd:sequence>
+									<xsd:element name="variable" minOccurs="0" maxOccurs="unbounded">
+										<xsd:complexType>
+											<xsd:annotation>
+												<xsd:documentation>Describes a outputVariable of a Function or a FunctionBlock</xsd:documentation>
+											</xsd:annotation>
+											<xsd:sequence>
+												<xsd:element name="connectionPointOut" type="ppx:connectionPointOut" minOccurs="0"/>
+												<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+											</xsd:sequence>
+											<xsd:attribute name="formalParameter" type="xsd:string" use="required"/>
+											<xsd:attribute name="negated" type="xsd:boolean" use="optional" default="false"/>
+											<xsd:attribute name="edge" type="ppx:edgeModifierType" use="optional" default="none"/>
+											<xsd:attribute name="storage" type="ppx:storageModifierType" use="optional" default="none"/>
+											<xsd:attribute name="hidden" type="xsd:boolean" use="optional" default="false"/>
+										</xsd:complexType>
+									</xsd:element>
+								</xsd:sequence>
+							</xsd:complexType>
+						</xsd:element>
+						<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+						<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+					</xsd:sequence>
+					<xsd:attribute name="localId" type="xsd:unsignedLong" use="required"/>
+					<xsd:attribute name="width" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="height" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="typeName" type="xsd:string" use="required"/>
+					<xsd:attribute name="instanceName" type="xsd:string" use="optional"/>
+					<xsd:attribute name="executionOrderId" type="xsd:unsignedLong" use="optional">
+						<xsd:annotation>
+							<xsd:documentation>Used to identify the order of execution. Also used to identify one special block if there are several blocks with the same name.</xsd:documentation>
+						</xsd:annotation>
+					</xsd:attribute>
+					<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+				</xsd:complexType>
+			</xsd:element>
+			<xsd:element name="inVariable">
+				<xsd:annotation>
+					<xsd:documentation>Expression used as producer</xsd:documentation>
+				</xsd:annotation>
+				<xsd:complexType>
+					<xsd:annotation>
+						<xsd:documentation>Describes a graphical object representing a variable, literal or expression used as r-value</xsd:documentation>
+					</xsd:annotation>
+					<xsd:sequence>
+						<xsd:element name="position" type="ppx:position"/>
+						<xsd:element name="connectionPointOut" type="ppx:connectionPointOut" minOccurs="0"/>
+						<xsd:element name="expression" type="xsd:string">
+							<xsd:annotation>
+								<xsd:documentation>The operand is a valid iec variable e.g. avar[0].</xsd:documentation>
+							</xsd:annotation>
+						</xsd:element>
+						<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+						<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+					</xsd:sequence>
+					<xsd:attribute name="localId" type="xsd:unsignedLong" use="required"/>
+					<xsd:attribute name="height" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="width" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="executionOrderId" type="xsd:unsignedLong" use="optional"/>
+					<xsd:attribute name="negated" type="xsd:boolean" use="optional" default="false"/>
+					<xsd:attribute name="edge" type="ppx:edgeModifierType" use="optional" default="none"/>
+					<xsd:attribute name="storage" type="ppx:storageModifierType" use="optional" default="none"/>
+					<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+				</xsd:complexType>
+			</xsd:element>
+			<xsd:element name="outVariable">
+				<xsd:annotation>
+					<xsd:documentation>Expression used as consumer</xsd:documentation>
+				</xsd:annotation>
+				<xsd:complexType>
+					<xsd:annotation>
+						<xsd:documentation>Describes a graphical object representing a variable or expression used as l-value</xsd:documentation>
+					</xsd:annotation>
+					<xsd:sequence>
+						<xsd:element name="position" type="ppx:position"/>
+						<xsd:element name="connectionPointIn" type="ppx:connectionPointIn" minOccurs="0"/>
+						<xsd:element name="expression" type="xsd:string">
+							<xsd:annotation>
+								<xsd:documentation>The operand is a valid iec variable e.g. avar[0].</xsd:documentation>
+							</xsd:annotation>
+						</xsd:element>
+						<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+						<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+					</xsd:sequence>
+					<xsd:attribute name="localId" type="xsd:unsignedLong" use="required"/>
+					<xsd:attribute name="height" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="width" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="executionOrderId" type="xsd:unsignedLong" use="optional"/>
+					<xsd:attribute name="negated" type="xsd:boolean" use="optional" default="false"/>
+					<xsd:attribute name="edge" type="ppx:edgeModifierType" use="optional" default="none"/>
+					<xsd:attribute name="storage" type="ppx:storageModifierType" use="optional" default="none"/>
+					<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+				</xsd:complexType>
+			</xsd:element>
+			<xsd:element name="inOutVariable">
+				<xsd:annotation>
+					<xsd:documentation>Expression used as producer and consumer</xsd:documentation>
+				</xsd:annotation>
+				<xsd:complexType>
+					<xsd:annotation>
+						<xsd:documentation>Describes a graphical object representing a variable which can be used as l-value and r-value at the same time</xsd:documentation>
+					</xsd:annotation>
+					<xsd:sequence>
+						<xsd:element name="position" type="ppx:position"/>
+						<xsd:element name="connectionPointIn" type="ppx:connectionPointIn" minOccurs="0"/>
+						<xsd:element name="connectionPointOut" type="ppx:connectionPointOut" minOccurs="0"/>
+						<xsd:element name="expression" type="xsd:string">
+							<xsd:annotation>
+								<xsd:documentation>The operand is a valid iec variable e.g. avar[0].</xsd:documentation>
+							</xsd:annotation>
+						</xsd:element>
+						<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+						<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+					</xsd:sequence>
+					<xsd:attribute name="localId" type="xsd:unsignedLong" use="required"/>
+					<xsd:attribute name="height" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="width" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="executionOrderId" type="xsd:unsignedLong" use="optional"/>
+					<xsd:attribute name="negatedIn" type="xsd:boolean" use="optional" default="false"/>
+					<xsd:attribute name="edgeIn" type="ppx:edgeModifierType" use="optional" default="none"/>
+					<xsd:attribute name="storageIn" type="ppx:storageModifierType" use="optional" default="none"/>
+					<xsd:attribute name="negatedOut" type="xsd:boolean" use="optional" default="false"/>
+					<xsd:attribute name="edgeOut" type="ppx:edgeModifierType" use="optional" default="none"/>
+					<xsd:attribute name="storageOut" type="ppx:storageModifierType" use="optional" default="none"/>
+					<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+				</xsd:complexType>
+			</xsd:element>
+			<xsd:element name="label">
+				<xsd:complexType>
+					<xsd:annotation>
+						<xsd:documentation>Describes a graphical object representing a jump label</xsd:documentation>
+					</xsd:annotation>
+					<xsd:sequence>
+						<xsd:element name="position" type="ppx:position"/>
+						<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+						<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+					</xsd:sequence>
+					<xsd:attribute name="localId" type="xsd:unsignedLong" use="required"/>
+					<xsd:attribute name="height" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="width" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="label" type="xsd:string" use="required"/>
+					<xsd:attribute name="executionOrderId" type="xsd:unsignedLong" use="optional"/>
+					<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+				</xsd:complexType>
+			</xsd:element>
+			<xsd:element name="jump">
+				<xsd:complexType>
+					<xsd:annotation>
+						<xsd:documentation>Describes a graphical object representing a jump statement</xsd:documentation>
+					</xsd:annotation>
+					<xsd:sequence>
+						<xsd:element name="position" type="ppx:position"/>
+						<xsd:element name="connectionPointIn" type="ppx:connectionPointIn" minOccurs="0"/>
+						<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+						<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+					</xsd:sequence>
+					<xsd:attribute name="localId" type="xsd:unsignedLong" use="required"/>
+					<xsd:attribute name="height" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="width" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="label" type="xsd:string" use="required"/>
+					<xsd:attribute name="executionOrderId" type="xsd:unsignedLong" use="optional"/>
+					<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+				</xsd:complexType>
+			</xsd:element>
+			<xsd:element name="return">
+				<xsd:complexType>
+					<xsd:annotation>
+						<xsd:documentation>Describes a graphical object representing areturn statement</xsd:documentation>
+					</xsd:annotation>
+					<xsd:sequence>
+						<xsd:element name="position" type="ppx:position"/>
+						<xsd:element name="connectionPointIn" type="ppx:connectionPointIn" minOccurs="0"/>
+						<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+						<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+					</xsd:sequence>
+					<xsd:attribute name="localId" type="xsd:unsignedLong" use="required"/>
+					<xsd:attribute name="height" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="width" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="executionOrderId" type="xsd:unsignedLong" use="optional"/>
+					<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+				</xsd:complexType>
+			</xsd:element>
+		</xsd:choice>
+	</xsd:group>
+	<xsd:group name="ldObjects">
+		<xsd:annotation>
+			<xsd:documentation>Collection of objects which are defined in ld and are an extension to fbd. They can be used in ld and sfc bodies</xsd:documentation>
+		</xsd:annotation>
+		<xsd:choice>
+			<xsd:element name="leftPowerRail">
+				<xsd:complexType>
+					<xsd:annotation>
+						<xsd:documentation>Describes a graphical object representing a left powerrail</xsd:documentation>
+					</xsd:annotation>
+					<xsd:sequence>
+						<xsd:element name="position" type="ppx:position"/>
+						<xsd:element name="connectionPointOut" minOccurs="0" maxOccurs="unbounded">
+							<xsd:complexType>
+								<xsd:complexContent>
+									<xsd:extension base="ppx:connectionPointOut">
+										<xsd:attribute name="formalParameter" type="xsd:string" use="required"/>
+									</xsd:extension>
+								</xsd:complexContent>
+							</xsd:complexType>
+						</xsd:element>
+						<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+						<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+					</xsd:sequence>
+					<xsd:attribute name="localId" type="xsd:unsignedLong" use="required"/>
+					<xsd:attribute name="height" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="width" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="executionOrderId" type="xsd:unsignedLong" use="optional">
+						<xsd:annotation>
+							<xsd:documentation>Used to identify the order of execution. Also used to identify one special block if there are several blocks with the same name.</xsd:documentation>
+						</xsd:annotation>
+					</xsd:attribute>
+					<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+				</xsd:complexType>
+			</xsd:element>
+			<xsd:element name="rightPowerRail">
+				<xsd:complexType>
+					<xsd:annotation>
+						<xsd:documentation>Describes a graphical object representing a right powerrail</xsd:documentation>
+					</xsd:annotation>
+					<xsd:sequence>
+						<xsd:element name="position" type="ppx:position"/>
+						<xsd:element name="connectionPointIn" type="ppx:connectionPointIn" minOccurs="0" maxOccurs="unbounded"/>
+						<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+						<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+					</xsd:sequence>
+					<xsd:attribute name="localId" type="xsd:unsignedLong" use="required"/>
+					<xsd:attribute name="height" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="width" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="executionOrderId" type="xsd:unsignedLong" use="optional">
+						<xsd:annotation>
+							<xsd:documentation>Used to identify the order of execution. Also used to identify one special block if there are several blocks with the same name.</xsd:documentation>
+						</xsd:annotation>
+					</xsd:attribute>
+					<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+				</xsd:complexType>
+			</xsd:element>
+			<xsd:element name="coil">
+				<xsd:complexType>
+					<xsd:annotation>
+						<xsd:documentation>Describes a graphical object representing a boolean variable which can be used as l-value and r-value at the same time</xsd:documentation>
+					</xsd:annotation>
+					<xsd:sequence>
+						<xsd:element name="position" type="ppx:position"/>
+						<xsd:element name="connectionPointIn" type="ppx:connectionPointIn" minOccurs="0"/>
+						<xsd:element name="connectionPointOut" type="ppx:connectionPointOut" minOccurs="0"/>
+						<xsd:element name="variable" type="xsd:string">
+							<xsd:annotation>
+								<xsd:documentation>The operand is a valid boolean  iec variable e.g. avar[0]</xsd:documentation>
+							</xsd:annotation>
+						</xsd:element>
+						<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+						<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+					</xsd:sequence>
+					<xsd:attribute name="localId" type="xsd:unsignedLong" use="required"/>
+					<xsd:attribute name="height" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="width" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="executionOrderId" type="xsd:unsignedLong" use="optional"/>
+					<xsd:attribute name="negated" type="xsd:boolean" use="optional" default="false"/>
+					<xsd:attribute name="edge" type="ppx:edgeModifierType" use="optional" default="none"/>
+					<xsd:attribute name="storage" type="ppx:storageModifierType" use="optional" default="none"/>
+					<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+				</xsd:complexType>
+			</xsd:element>
+			<xsd:element name="contact">
+				<xsd:complexType>
+					<xsd:annotation>
+						<xsd:documentation>Describes a graphical object representing a variable which can be used as l-value and r-value at the same time</xsd:documentation>
+					</xsd:annotation>
+					<xsd:sequence>
+						<xsd:element name="position" type="ppx:position"/>
+						<xsd:element name="connectionPointIn" type="ppx:connectionPointIn" minOccurs="0"/>
+						<xsd:element name="connectionPointOut" type="ppx:connectionPointOut" minOccurs="0"/>
+						<xsd:element name="variable" type="xsd:string">
+							<xsd:annotation>
+								<xsd:documentation>The operand is a valid boolean iec variable e.g. avar[0]</xsd:documentation>
+							</xsd:annotation>
+						</xsd:element>
+						<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+						<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+					</xsd:sequence>
+					<xsd:attribute name="localId" type="xsd:unsignedLong" use="required"/>
+					<xsd:attribute name="height" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="width" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="executionOrderId" type="xsd:unsignedLong" use="optional"/>
+					<xsd:attribute name="negated" type="xsd:boolean" use="optional" default="false"/>
+					<xsd:attribute name="edge" type="ppx:edgeModifierType" use="optional" default="none"/>
+					<xsd:attribute name="storage" type="ppx:storageModifierType" use="optional" default="none"/>
+					<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+				</xsd:complexType>
+			</xsd:element>
+		</xsd:choice>
+	</xsd:group>
+	<xsd:group name="sfcObjects">
+		<xsd:annotation>
+			<xsd:documentation>Collection of objects which are defined in sfc. They can only be used in sfc bodies</xsd:documentation>
+		</xsd:annotation>
+		<xsd:choice>
+			<xsd:element name="step">
+				<xsd:annotation>
+					<xsd:documentation>A single step in a SFC Sequence. Actions are associated with a step by using an actionBlock element with a connection to the step element</xsd:documentation>
+				</xsd:annotation>
+				<xsd:complexType>
+					<xsd:annotation>
+						<xsd:documentation>Contains actions</xsd:documentation>
+					</xsd:annotation>
+					<xsd:sequence>
+						<xsd:element name="position" type="ppx:position"/>
+						<xsd:element name="connectionPointIn" type="ppx:connectionPointIn" minOccurs="0"/>
+						<xsd:element name="connectionPointOut" minOccurs="0">
+							<xsd:complexType>
+								<xsd:complexContent>
+									<xsd:extension base="ppx:connectionPointOut">
+										<xsd:attribute name="formalParameter" type="xsd:string" use="required"/>
+									</xsd:extension>
+								</xsd:complexContent>
+							</xsd:complexType>
+						</xsd:element>
+						<xsd:element name="connectionPointOutAction" minOccurs="0">
+							<xsd:complexType>
+								<xsd:complexContent>
+									<xsd:extension base="ppx:connectionPointOut">
+										<xsd:attribute name="formalParameter" type="xsd:string" use="required"/>
+									</xsd:extension>
+								</xsd:complexContent>
+							</xsd:complexType>
+						</xsd:element>
+						<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+						<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+					</xsd:sequence>
+					<xsd:attribute name="localId" type="xsd:unsignedLong" use="required"/>
+					<xsd:attribute name="height" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="width" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="name" type="xsd:string" use="required"/>
+					<xsd:attribute name="initialStep" type="xsd:boolean" use="optional" default="false"/>
+					<xsd:attribute name="negated" type="xsd:boolean" use="optional" default="false"/>
+					<xsd:attribute name="executionOrderId" type="xsd:unsignedLong" use="optional">
+						<xsd:annotation>
+							<xsd:documentation>Used to identify the order of execution. Also used to identify one special block if there are several blocks with the same name.</xsd:documentation>
+						</xsd:annotation>
+					</xsd:attribute>
+					<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+				</xsd:complexType>
+			</xsd:element>
+			<xsd:element name="macroStep">
+				<xsd:complexType>
+					<xsd:sequence>
+						<xsd:element name="position" type="ppx:position"/>
+						<xsd:element name="connectionPointIn" type="ppx:connectionPointIn" minOccurs="0"/>
+						<xsd:element name="connectionPointOut" type="ppx:connectionPointOut" minOccurs="0"/>
+						<xsd:element name="body" type="ppx:body" minOccurs="0"/>
+						<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+						<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+					</xsd:sequence>
+					<xsd:attribute name="localId" type="xsd:unsignedLong" use="required"/>
+					<xsd:attribute name="height" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="width" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="name" type="xsd:string" use="optional"/>
+					<xsd:attribute name="executionOrderId" type="xsd:unsignedLong" use="optional">
+						<xsd:annotation>
+							<xsd:documentation>Used to identify the order of execution. Also used to identify one special block if there are several blocks with the same name.</xsd:documentation>
+						</xsd:annotation>
+					</xsd:attribute>
+					<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+				</xsd:complexType>
+			</xsd:element>
+			<xsd:element name="jumpStep">
+				<xsd:annotation>
+					<xsd:documentation>Jump to a step, macro step or simultaneous divergence. Acts like a step. Predecessor should be a transition.</xsd:documentation>
+				</xsd:annotation>
+				<xsd:complexType>
+					<xsd:sequence>
+						<xsd:element name="position" type="ppx:position"/>
+						<xsd:element name="connectionPointIn" type="ppx:connectionPointIn" minOccurs="0"/>
+						<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+						<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+					</xsd:sequence>
+					<xsd:attribute name="localId" type="xsd:unsignedLong" use="required"/>
+					<xsd:attribute name="height" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="width" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="targetName" type="xsd:string" use="required"/>
+					<xsd:attribute name="executionOrderId" type="xsd:unsignedLong" use="optional">
+						<xsd:annotation>
+							<xsd:documentation>Used to identify the order of execution. Also used to identify one special block if there are several blocks with the same name.</xsd:documentation>
+						</xsd:annotation>
+					</xsd:attribute>
+					<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+				</xsd:complexType>
+			</xsd:element>
+			<xsd:element name="transition">
+				<xsd:complexType>
+					<xsd:sequence>
+						<xsd:element name="position" type="ppx:position"/>
+						<xsd:element name="connectionPointIn" type="ppx:connectionPointIn" minOccurs="0"/>
+						<xsd:element name="connectionPointOut" type="ppx:connectionPointOut" minOccurs="0"/>
+						<xsd:element name="condition" minOccurs="0">
+							<xsd:complexType>
+								<xsd:choice>
+									<xsd:element name="reference">
+										<xsd:complexType>
+											<xsd:attribute name="name" type="xsd:string" use="required"/>
+										</xsd:complexType>
+									</xsd:element>
+									<xsd:element name="connectionPointIn" type="ppx:connectionPointIn"/>
+									<xsd:element name="inline">
+										<xsd:complexType>
+											<xsd:complexContent>
+												<xsd:extension base="ppx:body">
+													<xsd:attribute name="name" type="xsd:string" use="required"/>
+												</xsd:extension>
+											</xsd:complexContent>
+										</xsd:complexType>
+									</xsd:element>
+								</xsd:choice>
+								<xsd:attribute name="negated" type="xsd:boolean" use="optional" default="false"/>
+							</xsd:complexType>
+						</xsd:element>
+						<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+						<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+					</xsd:sequence>
+					<xsd:attribute name="localId" type="xsd:unsignedLong" use="required"/>
+					<xsd:attribute name="height" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="width" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="priority" type="xsd:unsignedLong" use="optional">
+						<xsd:annotation>
+							<xsd:documentation>The priority of a transition is evaluated, if the transition is connected to a selectionDivergence element.</xsd:documentation>
+						</xsd:annotation>
+					</xsd:attribute>
+					<xsd:attribute name="executionOrderId" type="xsd:unsignedLong" use="optional">
+						<xsd:annotation>
+							<xsd:documentation>Used to identify the order of execution. Also used to identify one special block if there are several blocks with the same name.</xsd:documentation>
+						</xsd:annotation>
+					</xsd:attribute>
+					<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+				</xsd:complexType>
+			</xsd:element>
+			<xsd:element name="selectionDivergence">
+				<xsd:complexType>
+					<xsd:sequence>
+						<xsd:element name="position" type="ppx:position"/>
+						<xsd:element name="connectionPointIn" type="ppx:connectionPointIn" minOccurs="0"/>
+						<xsd:element name="connectionPointOut" minOccurs="0" maxOccurs="unbounded">
+							<xsd:complexType>
+								<xsd:complexContent>
+									<xsd:extension base="ppx:connectionPointOut">
+										<xsd:attribute name="formalParameter" type="xsd:string" use="required"/>
+									</xsd:extension>
+								</xsd:complexContent>
+							</xsd:complexType>
+						</xsd:element>
+						<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+						<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+					</xsd:sequence>
+					<xsd:attribute name="localId" type="xsd:unsignedLong" use="required"/>
+					<xsd:attribute name="height" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="width" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+				</xsd:complexType>
+			</xsd:element>
+			<xsd:element name="selectionConvergence">
+				<xsd:complexType>
+					<xsd:sequence>
+						<xsd:element name="position" type="ppx:position"/>
+						<xsd:element name="connectionPointIn" minOccurs="0" maxOccurs="unbounded">
+							<xsd:complexType>
+								<xsd:complexContent>
+									<xsd:extension base="ppx:connectionPointIn"/>
+								</xsd:complexContent>
+							</xsd:complexType>
+						</xsd:element>
+						<xsd:element name="connectionPointOut" type="ppx:connectionPointOut" minOccurs="0"/>
+						<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+						<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+					</xsd:sequence>
+					<xsd:attribute name="localId" type="xsd:unsignedLong" use="required"/>
+					<xsd:attribute name="height" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="width" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+				</xsd:complexType>
+			</xsd:element>
+			<xsd:element name="simultaneousDivergence">
+				<xsd:complexType>
+					<xsd:sequence>
+						<xsd:element name="position" type="ppx:position"/>
+						<xsd:element name="connectionPointIn" type="ppx:connectionPointIn" minOccurs="0"/>
+						<xsd:element name="connectionPointOut" minOccurs="0" maxOccurs="unbounded">
+							<xsd:complexType>
+								<xsd:complexContent>
+									<xsd:extension base="ppx:connectionPointOut">
+										<xsd:attribute name="formalParameter" type="xsd:string" use="required"/>
+									</xsd:extension>
+								</xsd:complexContent>
+							</xsd:complexType>
+						</xsd:element>
+						<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+						<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+					</xsd:sequence>
+					<xsd:attribute name="localId" type="xsd:unsignedLong" use="required"/>
+					<xsd:attribute name="height" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="width" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="name" type="xsd:string" use="optional"/>
+					<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+				</xsd:complexType>
+			</xsd:element>
+			<xsd:element name="simultaneousConvergence">
+				<xsd:complexType>
+					<xsd:sequence>
+						<xsd:element name="position" type="ppx:position"/>
+						<xsd:element name="connectionPointIn" type="ppx:connectionPointIn" minOccurs="0" maxOccurs="unbounded"/>
+						<xsd:element name="connectionPointOut" type="ppx:connectionPointOut" minOccurs="0"/>
+						<xsd:element name="addData" type="ppx:addData" minOccurs="0"/>
+						<xsd:element name="documentation" type="ppx:formattedText" minOccurs="0"/>
+					</xsd:sequence>
+					<xsd:attribute name="localId" type="xsd:unsignedLong" use="required"/>
+					<xsd:attribute name="height" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="width" type="xsd:decimal" use="optional"/>
+					<xsd:attribute name="globalId" type="xsd:ID" use="optional"/>
+				</xsd:complexType>
+			</xsd:element>
+		</xsd:choice>
+	</xsd:group>
+	<xsd:simpleType name="edgeModifierType">
+		<xsd:annotation>
+			<xsd:documentation>Defines the edge detection behaviour of a variable</xsd:documentation>
+		</xsd:annotation>
+		<xsd:restriction base="xsd:string">
+			<xsd:enumeration value="none"/>
+			<xsd:enumeration value="falling"/>
+			<xsd:enumeration value="rising"/>
+		</xsd:restriction>
+	</xsd:simpleType>
+	<xsd:simpleType name="storageModifierType">
+		<xsd:annotation>
+			<xsd:documentation>Defines the storage mode (S/R) behaviour of a variable</xsd:documentation>
+		</xsd:annotation>
+		<xsd:restriction base="xsd:string">
+			<xsd:enumeration value="none"/>
+			<xsd:enumeration value="set"/>
+			<xsd:enumeration value="reset"/>
+		</xsd:restriction>
+	</xsd:simpleType>
+	<xsd:simpleType name="accessType">
+		<xsd:annotation>
+			<xsd:documentation>Defines the different access types to an accessVariable</xsd:documentation>
+		</xsd:annotation>
+		<xsd:restriction base="xsd:NMTOKEN">
+			<xsd:enumeration value="readOnly"/>
+			<xsd:enumeration value="readWrite"/>
+		</xsd:restriction>
+	</xsd:simpleType>
+	<xsd:simpleType name="pouType">
+		<xsd:annotation>
+			<xsd:documentation>Defines the different types of a POU</xsd:documentation>
+		</xsd:annotation>
+		<xsd:restriction base="xsd:NMTOKEN">
+			<xsd:enumeration value="function"/>
+			<xsd:enumeration value="functionBlock"/>
+			<xsd:enumeration value="program"/>
+		</xsd:restriction>
+	</xsd:simpleType>
+</xsd:schema>
diff --git a/cif/org.eclipse.escet.cif.prettyprinter/.settings/org.eclipse.jdt.core.prefs b/cif/org.eclipse.escet.cif.prettyprinter/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/cif/org.eclipse.escet.cif.prettyprinter/.settings/org.eclipse.jdt.core.prefs
+++ b/cif/org.eclipse.escet.cif.prettyprinter/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/cif/org.eclipse.escet.cif.prettyprinter/.settings/org.eclipse.jdt.ui.prefs b/cif/org.eclipse.escet.cif.prettyprinter/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/cif/org.eclipse.escet.cif.prettyprinter/.settings/org.eclipse.jdt.ui.prefs
+++ b/cif/org.eclipse.escet.cif.prettyprinter/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/cif/org.eclipse.escet.cif.prettyprinter/.settings/org.eclipse.ltk.core.refactoring.prefs b/cif/org.eclipse.escet.cif.prettyprinter/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.prettyprinter/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/cif/org.eclipse.escet.cif.prettyprinter/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.prettyprinter/META-INF/MANIFEST.MF
index a29c5e7176ceb54d9ec5a04c6fb984dc80faaff3..61cdefd117b6c5aa57698e659b8f0876cc3c80e8 100644
--- a/cif/org.eclipse.escet.cif.prettyprinter/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.prettyprinter/META-INF/MANIFEST.MF
@@ -2,15 +2,15 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET CIF Pretty Printer (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.cif.prettyprinter;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.cif.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.common.box;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.cif.common;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.cif.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.common.box;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.cif.common;bundle-version="0.10.0",
  org.apache.commons.lang3;bundle-version="3.1.0",
- org.eclipse.escet.common.emf;bundle-version="0.9.0"
+ org.eclipse.escet.common.emf;bundle-version="0.10.0"
 Export-Package: org.eclipse.escet.cif.prettyprinter
 Automatic-Module-Name: org.eclipse.escet.cif.prettyprinter
diff --git a/cif/org.eclipse.escet.cif.simulator.debug/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.simulator.debug/META-INF/MANIFEST.MF
index 767df5cbb235d9dd1d2e2b3e2bbf2850f34c40b9..a6c74aa81aefb17c8ecd193a4c5e3af0318f107b 100644
--- a/cif/org.eclipse.escet.cif.simulator.debug/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.simulator.debug/META-INF/MANIFEST.MF
@@ -2,29 +2,29 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET CIF Simulator Debug Project (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.cif.simulator.debug;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.cif.io;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.cif.cif2cif;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel.java;bundle-version="0.9.0",
- org.eclipse.escet.cif.common;bundle-version="0.9.0",
- org.eclipse.escet.common.box;bundle-version="0.9.0",
- org.eclipse.escet.common.emf;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.cif.io;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.cif.cif2cif;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel.java;bundle-version="0.10.0",
+ org.eclipse.escet.cif.common;bundle-version="0.10.0",
+ org.eclipse.escet.common.box;bundle-version="0.10.0",
+ org.eclipse.escet.common.emf;bundle-version="0.10.0",
  org.apache.commons.math3;bundle-version="3.5.0",
- org.eclipse.escet.common.eclipse.ui;bundle-version="0.9.0",
+ org.eclipse.escet.common.eclipse.ui;bundle-version="0.10.0",
  org.eclipse.core.resources;bundle-version="3.13.600",
  org.apache.commons.io;bundle-version="2.6.0",
- org.eclipse.escet.common.svg;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
- org.eclipse.escet.cif.parser;bundle-version="0.9.0",
- org.eclipse.escet.cif.prettyprinter;bundle-version="0.9.0",
- org.eclipse.escet.cif.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
+ org.eclipse.escet.common.svg;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.cif.parser;bundle-version="0.10.0",
+ org.eclipse.escet.cif.prettyprinter;bundle-version="0.10.0",
+ org.eclipse.escet.cif.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
  org.w3c.dom.svg;bundle-version="1.1.0",
  org.w3c.css.sac;bundle-version="1.3.1",
  org.apache.batik.css;bundle-version="1.14.0",
@@ -37,6 +37,7 @@ Require-Bundle: org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
  org.apache.batik.parser;bundle-version="1.14.0",
  org.knowm.xchart;bundle-version="3.6.5",
  org.apache.commons.lang3;bundle-version="3.1.0",
- org.eclipse.escet.cif.simulator;bundle-version="0.9.0",
- org.junit
+ org.eclipse.escet.cif.simulator;bundle-version="0.10.0",
+ org.junit,
+ org.apache.commons.commons-text;bundle-version="1.10.0"
 Automatic-Module-Name: org.eclipse.escet.cif.simulator.debug
diff --git a/cif/org.eclipse.escet.cif.simulator.debug/debug-cif-simulator-generated-code.launch b/cif/org.eclipse.escet.cif.simulator.debug/debug-cif-simulator-generated-code.launch
index ddd56c9b2414be0a8f204d95255a1612a3b9ba3d..8fcc5537c979e0e946a4db7ee33801c0a428a873 100644
--- a/cif/org.eclipse.escet.cif.simulator.debug/debug-cif-simulator-generated-code.launch
+++ b/cif/org.eclipse.escet.cif.simulator.debug/debug-cif-simulator-generated-code.launch
@@ -12,17 +12,19 @@
     <booleanAttribute key="default" value="true"/>
     <booleanAttribute key="includeOptional" value="true"/>
     <stringAttribute key="location" value="${workspace_loc}/../junit-workspace"/>
+    <booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
     <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
-        <listEntry value="/org.eclipse.escet.cif.simulator.debug/src/cifcode/DebugSimulator.java"/>
+        <listEntry value="/org.eclipse.escet.cif.simulator.debug"/>
     </listAttribute>
     <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
-        <listEntry value="1"/>
+        <listEntry value="4"/>
     </listAttribute>
     <stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value=""/>
     <booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
     <stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
     <stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/>
     <booleanAttribute key="org.eclipse.jdt.launching.ATTR_ATTR_USE_ARGFILE" value="false"/>
+    <booleanAttribute key="org.eclipse.jdt.launching.ATTR_SHOW_CODEDETAILS_IN_EXCEPTION_MESSAGES" value="true"/>
     <stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17"/>
     <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="cifcode.DebugSimulator"/>
     <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.escet.cif.simulator.debug"/>
diff --git a/cif/org.eclipse.escet.cif.simulator/.settings/org.eclipse.jdt.core.prefs b/cif/org.eclipse.escet.cif.simulator/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/cif/org.eclipse.escet.cif.simulator/.settings/org.eclipse.jdt.core.prefs
+++ b/cif/org.eclipse.escet.cif.simulator/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/cif/org.eclipse.escet.cif.simulator/.settings/org.eclipse.jdt.ui.prefs b/cif/org.eclipse.escet.cif.simulator/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/cif/org.eclipse.escet.cif.simulator/.settings/org.eclipse.jdt.ui.prefs
+++ b/cif/org.eclipse.escet.cif.simulator/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/cif/org.eclipse.escet.cif.simulator/.settings/org.eclipse.ltk.core.refactoring.prefs b/cif/org.eclipse.escet.cif.simulator/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.simulator/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/cif/org.eclipse.escet.cif.simulator/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.simulator/META-INF/MANIFEST.MF
index 4840fb175f18f2dd7e7f6f0b271546d28417f74c..7cddea0a62e7aa8f946812083e3ac544be6315cb 100644
--- a/cif/org.eclipse.escet.cif.simulator/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.simulator/META-INF/MANIFEST.MF
@@ -2,29 +2,29 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET CIF Simulator (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.cif.simulator;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.cif.io;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.cif.cif2cif;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel.java;bundle-version="0.9.0",
- org.eclipse.escet.cif.common;bundle-version="0.9.0",
- org.eclipse.escet.common.box;bundle-version="0.9.0",
- org.eclipse.escet.common.emf;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.cif.io;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.cif.cif2cif;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel.java;bundle-version="0.10.0",
+ org.eclipse.escet.cif.common;bundle-version="0.10.0",
+ org.eclipse.escet.common.box;bundle-version="0.10.0",
+ org.eclipse.escet.common.emf;bundle-version="0.10.0",
  org.apache.commons.math3;bundle-version="3.5.0",
- org.eclipse.escet.common.eclipse.ui;bundle-version="0.9.0",
+ org.eclipse.escet.common.eclipse.ui;bundle-version="0.10.0",
  org.eclipse.core.resources;bundle-version="3.13.600",
  org.apache.commons.io;bundle-version="2.6.0",
- org.eclipse.escet.common.svg;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
- org.eclipse.escet.cif.parser;bundle-version="0.9.0",
- org.eclipse.escet.cif.prettyprinter;bundle-version="0.9.0",
- org.eclipse.escet.cif.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
+ org.eclipse.escet.common.svg;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.cif.parser;bundle-version="0.10.0",
+ org.eclipse.escet.cif.prettyprinter;bundle-version="0.10.0",
+ org.eclipse.escet.cif.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
  org.w3c.dom.svg;bundle-version="1.1.0",
  org.w3c.css.sac;bundle-version="1.3.1",
  org.apache.batik.css;bundle-version="1.14.0",
@@ -36,7 +36,8 @@ Require-Bundle: org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
  org.apache.batik.awt.util;bundle-version="1.14.0",
  org.apache.batik.parser;bundle-version="1.14.0",
  org.knowm.xchart;bundle-version="3.6.5",
- org.apache.commons.lang3;bundle-version="3.1.0"
+ org.apache.commons.lang3;bundle-version="3.1.0",
+ org.apache.commons.commons-text;bundle-version="1.10.0"
 Export-Package: org.eclipse.escet.cif.simulator,
  org.eclipse.escet.cif.simulator.compiler,
  org.eclipse.escet.cif.simulator.input,
diff --git a/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/AssignmentCodeGenerator.java b/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/AssignmentCodeGenerator.java
index 3bae7b5361c9acd7a85a2ab610024da23f482699..c1449804c8979229db957cda20759240b8ecd94b 100644
--- a/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/AssignmentCodeGenerator.java
+++ b/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/AssignmentCodeGenerator.java
@@ -13,7 +13,7 @@
 
 package org.eclipse.escet.cif.simulator.compiler;
 
-import static org.apache.commons.lang3.StringEscapeUtils.escapeJava;
+import static org.apache.commons.text.StringEscapeUtils.escapeJava;
 import static org.eclipse.escet.cif.common.CifTextUtils.exprToStr;
 import static org.eclipse.escet.cif.common.CifTextUtils.typeToStr;
 import static org.eclipse.escet.cif.common.CifTypeUtils.checkTypeCompat;
diff --git a/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/AutomatonNormalCodeGenerator.java b/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/AutomatonNormalCodeGenerator.java
index ae7ed77909b2b514b4f4810c4cea8b0c57d649dd..31e570ba1f3d55c448b53e5c5cbe617bec312ca4 100644
--- a/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/AutomatonNormalCodeGenerator.java
+++ b/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/AutomatonNormalCodeGenerator.java
@@ -13,7 +13,7 @@
 
 package org.eclipse.escet.cif.simulator.compiler;
 
-import static org.apache.commons.lang3.StringEscapeUtils.escapeJava;
+import static org.apache.commons.text.StringEscapeUtils.escapeJava;
 import static org.eclipse.escet.cif.common.CifTextUtils.exprToStr;
 import static org.eclipse.escet.cif.common.CifTextUtils.exprsToStr;
 import static org.eclipse.escet.cif.common.CifTextUtils.getAbsName;
diff --git a/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/CifSvgCodeGenerator.java b/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/CifSvgCodeGenerator.java
index 1e48ce94f8529f252dee0d06043908e5083e5359..5d4640ee566c44800a1a295cc34ccd9f31e974ee 100644
--- a/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/CifSvgCodeGenerator.java
+++ b/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/CifSvgCodeGenerator.java
@@ -13,7 +13,7 @@
 
 package org.eclipse.escet.cif.simulator.compiler;
 
-import static org.apache.commons.lang3.StringEscapeUtils.escapeJava;
+import static org.apache.commons.text.StringEscapeUtils.escapeJava;
 import static org.eclipse.escet.cif.common.CifTextUtils.exprToStr;
 import static org.eclipse.escet.cif.common.CifTextUtils.getAbsName;
 import static org.eclipse.escet.cif.common.CifTypeUtils.normalizeType;
diff --git a/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/DebugSimulatorCodeGenerator.java b/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/DebugSimulatorCodeGenerator.java
index af8d0f4b20f43b4c18f0e4c20dca90ee8d8b6a2f..0fa63f209c8786e438dfb7cf48d945ac5c426199 100644
--- a/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/DebugSimulatorCodeGenerator.java
+++ b/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/DebugSimulatorCodeGenerator.java
@@ -21,7 +21,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 
-import org.apache.commons.lang3.StringEscapeUtils;
+import org.apache.commons.text.StringEscapeUtils;
 import org.eclipse.escet.common.app.framework.Paths;
 import org.eclipse.escet.common.app.framework.options.Option;
 import org.eclipse.escet.common.app.framework.options.OptionValue;
diff --git a/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/EventCodeGenerator.java b/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/EventCodeGenerator.java
index be8d344cdd46f894629e32eb5f9d23a947ebd6e9..431142d047206674c7c39d78b48ed3a913d8a680 100644
--- a/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/EventCodeGenerator.java
+++ b/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/EventCodeGenerator.java
@@ -13,7 +13,7 @@
 
 package org.eclipse.escet.cif.simulator.compiler;
 
-import static org.apache.commons.lang3.StringEscapeUtils.escapeJava;
+import static org.apache.commons.text.StringEscapeUtils.escapeJava;
 import static org.eclipse.escet.cif.common.CifTextUtils.getAbsName;
 import static org.eclipse.escet.cif.common.CifTextUtils.invToStr;
 import static org.eclipse.escet.cif.simulator.compiler.CifCompilerContext.EVENT_CLS_PREFIX;
diff --git a/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/FuncCodeGenerator.java b/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/FuncCodeGenerator.java
index c408bc9ef07f8df6faa78b04bbba8817ad2ad281..da029590bfbb753f0f2ae6ee530090dd80e20c13 100644
--- a/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/FuncCodeGenerator.java
+++ b/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/FuncCodeGenerator.java
@@ -13,7 +13,7 @@
 
 package org.eclipse.escet.cif.simulator.compiler;
 
-import static org.apache.commons.lang3.StringEscapeUtils.escapeJava;
+import static org.apache.commons.text.StringEscapeUtils.escapeJava;
 import static org.eclipse.escet.cif.common.CifTextUtils.exprToStr;
 import static org.eclipse.escet.cif.common.CifTextUtils.exprsToStr;
 import static org.eclipse.escet.cif.common.CifTextUtils.getAbsName;
diff --git a/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/InitPredCodeGenerator.java b/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/InitPredCodeGenerator.java
index 49d542432d4449dcebc180dca79d5992d961d9d8..71530c215e48ed273a6e4a18ac66b481cf1a3f83 100644
--- a/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/InitPredCodeGenerator.java
+++ b/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/InitPredCodeGenerator.java
@@ -13,7 +13,7 @@
 
 package org.eclipse.escet.cif.simulator.compiler;
 
-import static org.apache.commons.lang3.StringEscapeUtils.escapeJava;
+import static org.apache.commons.text.StringEscapeUtils.escapeJava;
 import static org.eclipse.escet.cif.common.CifTextUtils.exprToStr;
 import static org.eclipse.escet.cif.common.CifTextUtils.getAbsName;
 import static org.eclipse.escet.cif.simulator.compiler.ExprCodeGenerator.gencodeExpr;
diff --git a/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/LiteralCodeGenerator.java b/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/LiteralCodeGenerator.java
index 40b283146ed39acb871300767f98c399ed1c2c76..a3231dd0367ea67908b292a8fde140627e66cf7f 100644
--- a/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/LiteralCodeGenerator.java
+++ b/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/LiteralCodeGenerator.java
@@ -26,7 +26,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 
-import org.apache.commons.lang3.StringEscapeUtils;
+import org.apache.commons.text.StringEscapeUtils;
 import org.eclipse.escet.cif.common.CifTextUtils;
 import org.eclipse.escet.cif.common.CifTypeUtils;
 import org.eclipse.escet.cif.common.RangeCompat;
diff --git a/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/OdeStateEventsCodeGenerator.java b/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/OdeStateEventsCodeGenerator.java
index d08df1e998764fa0dcec08ecfb64b1f6faf69281..371e045b75f4cf200486d6093eaf5bfbfc2f9df5 100644
--- a/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/OdeStateEventsCodeGenerator.java
+++ b/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/OdeStateEventsCodeGenerator.java
@@ -13,7 +13,7 @@
 
 package org.eclipse.escet.cif.simulator.compiler;
 
-import static org.apache.commons.lang3.StringEscapeUtils.escapeJava;
+import static org.apache.commons.text.StringEscapeUtils.escapeJava;
 import static org.eclipse.escet.cif.common.CifTextUtils.exprToStr;
 import static org.eclipse.escet.cif.common.CifValueUtils.isTimeConstant;
 import static org.eclipse.escet.cif.simulator.compiler.CifCompilerContext.CONT_SUB_STATE_FIELD_NAME;
diff --git a/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/PrintCodeGenerator.java b/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/PrintCodeGenerator.java
index 3b534921542c4353b095855e33e0269b06972701..e156ac7e0241e2cf9530969bda44f1e0c605996c 100644
--- a/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/PrintCodeGenerator.java
+++ b/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/PrintCodeGenerator.java
@@ -13,7 +13,7 @@
 
 package org.eclipse.escet.cif.simulator.compiler;
 
-import static org.apache.commons.lang3.StringEscapeUtils.escapeJava;
+import static org.apache.commons.text.StringEscapeUtils.escapeJava;
 import static org.eclipse.escet.cif.common.CifTextUtils.exprToStr;
 import static org.eclipse.escet.cif.common.CifTypeUtils.normalizeType;
 import static org.eclipse.escet.cif.simulator.compiler.ExprCodeGenerator.gencodeExpr;
diff --git a/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/StateInitCodeGenerator.java b/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/StateInitCodeGenerator.java
index 4baf6fc0d5c98b219e73c554db4ce1076e4eee0d..72682187231e745739c50daeb347a5c5ece257aa 100644
--- a/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/StateInitCodeGenerator.java
+++ b/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/StateInitCodeGenerator.java
@@ -13,7 +13,7 @@
 
 package org.eclipse.escet.cif.simulator.compiler;
 
-import static org.apache.commons.lang3.StringEscapeUtils.escapeJava;
+import static org.apache.commons.text.StringEscapeUtils.escapeJava;
 import static org.eclipse.escet.cif.common.CifTextUtils.exprToStr;
 import static org.eclipse.escet.cif.common.CifTextUtils.exprsToStr;
 import static org.eclipse.escet.cif.common.CifTextUtils.getAbsName;
@@ -29,7 +29,7 @@ import static org.eclipse.escet.common.java.Strings.fmt;
 
 import java.util.List;
 
-import org.apache.commons.lang3.StringEscapeUtils;
+import org.apache.commons.text.StringEscapeUtils;
 import org.eclipse.escet.cif.common.CifLocationUtils;
 import org.eclipse.escet.cif.common.CifTextUtils;
 import org.eclipse.escet.cif.common.StateInitOrderer;
diff --git a/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/StateInvPredCodeGenerator.java b/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/StateInvPredCodeGenerator.java
index f48809d4fef4a0efa300bba01087e0838a722b71..77f5f1562352204ec23fd6a9ba25e4ce4c60f43f 100644
--- a/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/StateInvPredCodeGenerator.java
+++ b/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/StateInvPredCodeGenerator.java
@@ -13,7 +13,7 @@
 
 package org.eclipse.escet.cif.simulator.compiler;
 
-import static org.apache.commons.lang3.StringEscapeUtils.escapeJava;
+import static org.apache.commons.text.StringEscapeUtils.escapeJava;
 import static org.eclipse.escet.cif.common.CifTextUtils.exprToStr;
 import static org.eclipse.escet.cif.common.CifTextUtils.getAbsName;
 import static org.eclipse.escet.cif.common.CifTextUtils.invToStr;
diff --git a/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/UrgEdgesCodeGenerator.java b/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/UrgEdgesCodeGenerator.java
index d2eb20d94e7fccefec85785fcb6cf92c2900a1d1..2270c957b04d2f2b0a852c145b861d8523379349 100644
--- a/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/UrgEdgesCodeGenerator.java
+++ b/cif/org.eclipse.escet.cif.simulator/src/org/eclipse/escet/cif/simulator/compiler/UrgEdgesCodeGenerator.java
@@ -13,7 +13,7 @@
 
 package org.eclipse.escet.cif.simulator.compiler;
 
-import static org.apache.commons.lang3.StringEscapeUtils.escapeJava;
+import static org.apache.commons.text.StringEscapeUtils.escapeJava;
 import static org.eclipse.escet.cif.common.CifTextUtils.exprsToStr;
 import static org.eclipse.escet.cif.simulator.compiler.ExprCodeGenerator.gencodePreds;
 
diff --git a/cif/org.eclipse.escet.cif.simulator/test-cif-simulator-tank.launch b/cif/org.eclipse.escet.cif.simulator/test-cif-simulator-tank.launch
new file mode 100644
index 0000000000000000000000000000000000000000..fe16f1cf178476a3fb95bd72816ab7740f37e806
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.simulator/test-cif-simulator-tank.launch
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.pde.ui.RuntimeWorkbench">
+    <setAttribute key="additional_plugins">
+        <setEntry value="org.apache.felix.scr:2.2.6:default:false:2:true"/>
+        <setEntry value="org.eclipse.core.runtime:3.26.100.v20221021-0005:default:false:default:true"/>
+        <setEntry value="org.eclipse.equinox.common:3.17.100.v20230202-1341:default:false:2:true"/>
+        <setEntry value="org.eclipse.equinox.event:1.6.200.v20230120-0604:default:false:2:true"/>
+        <setEntry value="org.eclipse.equinox.simpleconfigurator:1.4.200.v20221111-1340:default:false:1:true"/>
+    </setAttribute>
+    <booleanAttribute key="append.args" value="true"/>
+    <stringAttribute key="application" value="org.eclipse.escet.common.app.framework.application"/>
+    <booleanAttribute key="askclear" value="false"/>
+    <booleanAttribute key="automaticAdd" value="false"/>
+    <booleanAttribute key="automaticValidate" value="true"/>
+    <stringAttribute key="bootstrap" value=""/>
+    <stringAttribute key="checked" value="[NONE]"/>
+    <booleanAttribute key="clearConfig" value="true"/>
+    <booleanAttribute key="clearws" value="false"/>
+    <booleanAttribute key="clearwslog" value="true"/>
+    <stringAttribute key="configLocation" value="${workspace_loc}/.metadata/.plugins/org.eclipse.pde.core/test-cif-simulator-tank"/>
+    <booleanAttribute key="default" value="false"/>
+    <stringAttribute key="featureDefaultLocation" value="workspace"/>
+    <stringAttribute key="featurePluginResolution" value="workspace"/>
+    <booleanAttribute key="includeOptional" value="true"/>
+    <stringAttribute key="location" value=""/>
+    <booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
+    <booleanAttribute key="org.eclipse.jdt.launching.ATTR_ATTR_USE_ARGFILE" value="false"/>
+    <booleanAttribute key="org.eclipse.jdt.launching.ATTR_SHOW_CODEDETAILS_IN_EXCEPTION_MESSAGES" value="true"/>
+    <stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17"/>
+    <stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-consoleLog  org.eclipse.escet.cif.simulator org.eclipse.escet.cif.simulator.CifSimulatorApp --option-dialog=1 --stateviz=1 --plotviz=1 -i auto -a first --frame-rate=20 --speed=1 --trajdata=on ${resource_loc:/org.eclipse.escet.cif.examples/examples/hybrid/tank/tank.cif} --trajdata-file=${resource_loc:/org.eclipse.escet.cif.simulator/test}/output/tank.cif.trajdata"/>
+    <stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
+    <stringAttribute key="pde.version" value="3.3"/>
+    <stringAttribute key="product" value="org.eclipse.escet.product.branding.product"/>
+    <stringAttribute key="productFile" value="\org.eclipse.escet.product\escet.product"/>
+    <booleanAttribute key="restart" value="true"/>
+    <setAttribute key="selected_features">
+        <setEntry value="org.eclipse.escet.product.feature:default"/>
+    </setAttribute>
+    <booleanAttribute key="show_selected_only" value="false"/>
+    <booleanAttribute key="tracing" value="false"/>
+    <booleanAttribute key="useCustomFeatures" value="true"/>
+    <booleanAttribute key="useDefaultConfig" value="true"/>
+    <booleanAttribute key="useDefaultConfigArea" value="true"/>
+    <booleanAttribute key="useProduct" value="false"/>
+    <booleanAttribute key="usefeatures" value="false"/>
+</launchConfiguration>
diff --git a/cif/org.eclipse.escet.cif.simulator/test/output/.gitignore b/cif/org.eclipse.escet.cif.simulator/test/output/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..9b71d5ea52636d22641d80194ba5a3512bcf2f02
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.simulator/test/output/.gitignore
@@ -0,0 +1,14 @@
+################################################################################
+# Copyright (c) 2021, 2023 Contributors to the Eclipse Foundation
+#
+# See the NOTICE file(s) distributed with this work for additional
+# information regarding copyright ownership.
+#
+# This program and the accompanying materials are made available under the terms
+# of the MIT License which is available at https://opensource.org/licenses/MIT
+#
+# SPDX-License-Identifier: MIT
+################################################################################# 
+
+*
+!.gitignore
diff --git a/cif/org.eclipse.escet.cif.tests.utils/.settings/org.eclipse.jdt.core.prefs b/cif/org.eclipse.escet.cif.tests.utils/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/cif/org.eclipse.escet.cif.tests.utils/.settings/org.eclipse.jdt.core.prefs
+++ b/cif/org.eclipse.escet.cif.tests.utils/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/cif/org.eclipse.escet.cif.tests.utils/.settings/org.eclipse.jdt.ui.prefs b/cif/org.eclipse.escet.cif.tests.utils/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/cif/org.eclipse.escet.cif.tests.utils/.settings/org.eclipse.jdt.ui.prefs
+++ b/cif/org.eclipse.escet.cif.tests.utils/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/cif/org.eclipse.escet.cif.tests.utils/.settings/org.eclipse.ltk.core.refactoring.prefs b/cif/org.eclipse.escet.cif.tests.utils/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests.utils/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/cif/org.eclipse.escet.cif.tests.utils/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.tests.utils/META-INF/MANIFEST.MF
index a3274a43707a87eb338278658c55bce416c3c36b..26f981af3bd4fa6de599f9693199a87df779da32 100644
--- a/cif/org.eclipse.escet.cif.tests.utils/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.tests.utils/META-INF/MANIFEST.MF
@@ -2,10 +2,10 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET CIF Tests Utils (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.cif.tests.utils;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Automatic-Module-Name: org.eclipse.escet.cif.tests.utils
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
 Export-Package: org.eclipse.escet.cif.tests.utils
-Require-Bundle: org.eclipse.escet.common.java;bundle-version="0.9.0"
+Require-Bundle: org.eclipse.escet.common.java;bundle-version="0.10.0"
diff --git a/cif/org.eclipse.escet.cif.tests/.settings/org.eclipse.jdt.core.prefs b/cif/org.eclipse.escet.cif.tests/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/cif/org.eclipse.escet.cif.tests/.settings/org.eclipse.jdt.core.prefs
+++ b/cif/org.eclipse.escet.cif.tests/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/cif/org.eclipse.escet.cif.tests/.settings/org.eclipse.jdt.ui.prefs b/cif/org.eclipse.escet.cif.tests/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/cif/org.eclipse.escet.cif.tests/.settings/org.eclipse.jdt.ui.prefs
+++ b/cif/org.eclipse.escet.cif.tests/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/cif/org.eclipse.escet.cif.tests/.settings/org.eclipse.ltk.core.refactoring.prefs b/cif/org.eclipse.escet.cif.tests/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/cif/org.eclipse.escet.cif.tests/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.tests/META-INF/MANIFEST.MF
index 378d09d55631d54785ebcf7309d48134492f636f..8562109a7383a05e1f4517a0817c424332d9dcd7 100644
--- a/cif/org.eclipse.escet.cif.tests/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.tests/META-INF/MANIFEST.MF
@@ -2,41 +2,41 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET CIF Tests (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.cif.tests;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
 Require-Bundle: org.junit;bundle-version="4.12.0",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.tooldef.interpreter;bundle-version="0.9.0",
- org.eclipse.escet.cif.tooldefs;bundle-version="0.9.0",
- org.eclipse.escet.cif.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.cif.cif2cif;bundle-version="0.9.0",
- org.eclipse.escet.cif.eventbased;bundle-version="0.9.0",
- org.eclipse.escet.cif.cif2yed;bundle-version="0.9.0",
- org.eclipse.escet.cif.cif2mcrl2;bundle-version="0.9.0",
- org.eclipse.escet.cif.codegen;bundle-version="0.9.0",
- org.eclipse.escet.cif.cif2plc;bundle-version="0.9.0",
- org.eclipse.escet.cif.cif2supremica;bundle-version="0.9.0",
- org.eclipse.escet.cif.cif2uppaal;bundle-version="0.9.0",
- org.eclipse.escet.cif.datasynth;bundle-version="0.9.0",
- org.eclipse.escet.cif.eventdisabler;bundle-version="0.9.0",
- org.eclipse.escet.cif.explorer;bundle-version="0.9.0",
- org.eclipse.escet.cif.merger;bundle-version="0.9.0",
- org.eclipse.escet.cif.simulator;bundle-version="0.9.0",
- org.eclipse.escet.cif.cif2cif.app;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.cif.controllercheck;bundle-version="0.9.0",
- org.eclipse.escet.cif.io;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
- org.eclipse.escet.cif.parser;bundle-version="0.9.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.cif.common;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel.java;bundle-version="0.9.0",
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.tooldef.interpreter;bundle-version="0.10.0",
+ org.eclipse.escet.cif.tooldefs;bundle-version="0.10.0",
+ org.eclipse.escet.cif.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.cif.cif2cif;bundle-version="0.10.0",
+ org.eclipse.escet.cif.eventbased;bundle-version="0.10.0",
+ org.eclipse.escet.cif.cif2yed;bundle-version="0.10.0",
+ org.eclipse.escet.cif.cif2mcrl2;bundle-version="0.10.0",
+ org.eclipse.escet.cif.codegen;bundle-version="0.10.0",
+ org.eclipse.escet.cif.cif2plc;bundle-version="0.10.0",
+ org.eclipse.escet.cif.cif2supremica;bundle-version="0.10.0",
+ org.eclipse.escet.cif.cif2uppaal;bundle-version="0.10.0",
+ org.eclipse.escet.cif.datasynth;bundle-version="0.10.0",
+ org.eclipse.escet.cif.eventdisabler;bundle-version="0.10.0",
+ org.eclipse.escet.cif.explorer;bundle-version="0.10.0",
+ org.eclipse.escet.cif.merger;bundle-version="0.10.0",
+ org.eclipse.escet.cif.simulator;bundle-version="0.10.0",
+ org.eclipse.escet.cif.cif2cif.app;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.cif.controllercheck;bundle-version="0.10.0",
+ org.eclipse.escet.cif.io;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.cif.parser;bundle-version="0.10.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.cif.common;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel.java;bundle-version="0.10.0",
  org.apache.commons.lang3;bundle-version="3.1.0",
- org.eclipse.escet.cif.plcgen;bundle-version="0.9.0",
- org.eclipse.escet.cif.checkers;bundle-version="0.9.0"
+ org.eclipse.escet.cif.plcgen;bundle-version="0.10.0",
+ org.eclipse.escet.cif.checkers;bundle-version="0.10.0"
 Export-Package: org.eclipse.escet.cif.tests,
  org.eclipse.escet.cif.tests.checkers.checks
 Automatic-Module-Name: org.eclipse.escet.cif.tests
diff --git a/cif/org.eclipse.escet.cif.tests/tests/checks/ExprNoSpecificExprsCheckLevel1.cif b/cif/org.eclipse.escet.cif.tests/tests/checks/ExprNoSpecificExprsCheckLevel1.cif
index 0db6f80fa7f6d988e806a6372fd648c0416906aa..bb483d4e5c85bcf6f1945493902280d501c1ed90 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/checks/ExprNoSpecificExprsCheckLevel1.cif
+++ b/cif/org.eclipse.escet.cif.tests/tests/checks/ExprNoSpecificExprsCheckLevel1.cif
@@ -317,7 +317,7 @@ end
 
 // SWITCH_EXPRS.
 group SWITCH_EXPRS:
-  invariant switch 5: case 5: true else false end;
+  invariant switch 5: case 5: true end;
 end
 
 // TIME_VAR_REFS.
diff --git a/cif/org.eclipse.escet.cif.tests/tests/checks/ExprNoSpecificExprsCheckLevel1.cif.check.err b/cif/org.eclipse.escet.cif.tests/tests/checks/ExprNoSpecificExprsCheckLevel1.cif.check.err
index a6fed72a055871005c20f3216db1ab66e452aa1c..cb2151cc5ac8171e9f15e892fc22ab935a4fcb42 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/checks/ExprNoSpecificExprsCheckLevel1.cif.check.err
+++ b/cif/org.eclipse.escet.cif.tests/tests/checks/ExprNoSpecificExprsCheckLevel1.cif.check.err
@@ -154,8 +154,8 @@ ERROR: CIF checks tester failed due to unsatisfied preconditions:
      - invariant SLICE_EXPRS_LIST: [true, false][:-1][0];
                                     ^     ^
    * In group "SWITCH_EXPRS":
-     - invariant switch 5: case 5: true else false end;
-                                   ^         ^
+     - invariant switch 5: case 5: true end;
+                                   ^
    * In constant "TUPLE_FIELD_REFS_NAMED.c":
      - const tuple(bool a; bool b) c = (true, false);
                                         ^     ^
@@ -468,7 +468,7 @@ ERROR: CIF checks tester failed due to unsatisfied preconditions:
      - invariant switch self: else true end;
                  ^
    * In group "SWITCH_EXPRS":
-     - invariant switch 5: case 5: true else false end;
+     - invariant switch 5: case 5: true end;
                  ^
 
   --------------------------------
@@ -560,7 +560,7 @@ ERROR: CIF checks tester failed due to unsatisfied preconditions:
      - invariant SLICE_EXPRS_STRING: "ab"[:-1][0] = "a";
                                             ^  ^
    * In group "SWITCH_EXPRS":
-     - invariant switch 5: case 5: true else false end;
+     - invariant switch 5: case 5: true end;
                         ^       ^
    * In group "TIME_VAR_REFS":
      - invariant time > 0;
diff --git a/cif/org.eclipse.escet.cif.tests/tests/checks/ExprNoSpecificExprsCheckLevel2.cif b/cif/org.eclipse.escet.cif.tests/tests/checks/ExprNoSpecificExprsCheckLevel2.cif
index 0db6f80fa7f6d988e806a6372fd648c0416906aa..bb483d4e5c85bcf6f1945493902280d501c1ed90 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/checks/ExprNoSpecificExprsCheckLevel2.cif
+++ b/cif/org.eclipse.escet.cif.tests/tests/checks/ExprNoSpecificExprsCheckLevel2.cif
@@ -317,7 +317,7 @@ end
 
 // SWITCH_EXPRS.
 group SWITCH_EXPRS:
-  invariant switch 5: case 5: true else false end;
+  invariant switch 5: case 5: true end;
 end
 
 // TIME_VAR_REFS.
diff --git a/cif/org.eclipse.escet.cif.tests/tests/checks/ExprNoSpecificExprsCheckLevel3.cif b/cif/org.eclipse.escet.cif.tests/tests/checks/ExprNoSpecificExprsCheckLevel3.cif
index 0db6f80fa7f6d988e806a6372fd648c0416906aa..bb483d4e5c85bcf6f1945493902280d501c1ed90 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/checks/ExprNoSpecificExprsCheckLevel3.cif
+++ b/cif/org.eclipse.escet.cif.tests/tests/checks/ExprNoSpecificExprsCheckLevel3.cif
@@ -317,7 +317,7 @@ end
 
 // SWITCH_EXPRS.
 group SWITCH_EXPRS:
-  invariant switch 5: case 5: true else false end;
+  invariant switch 5: case 5: true end;
 end
 
 // TIME_VAR_REFS.
diff --git a/cif/org.eclipse.escet.cif.tests/tests/checks/ExprNoSpecificExprsCheckLevel4.cif b/cif/org.eclipse.escet.cif.tests/tests/checks/ExprNoSpecificExprsCheckLevel4.cif
index 0db6f80fa7f6d988e806a6372fd648c0416906aa..bb483d4e5c85bcf6f1945493902280d501c1ed90 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/checks/ExprNoSpecificExprsCheckLevel4.cif
+++ b/cif/org.eclipse.escet.cif.tests/tests/checks/ExprNoSpecificExprsCheckLevel4.cif
@@ -317,7 +317,7 @@ end
 
 // SWITCH_EXPRS.
 group SWITCH_EXPRS:
-  invariant switch 5: case 5: true else false end;
+  invariant switch 5: case 5: true end;
 end
 
 // TIME_VAR_REFS.
diff --git a/cif/org.eclipse.escet.cif.tests/tests/checks/ExprNoSpecificExprsCheckLevel5.cif b/cif/org.eclipse.escet.cif.tests/tests/checks/ExprNoSpecificExprsCheckLevel5.cif
index 0db6f80fa7f6d988e806a6372fd648c0416906aa..bb483d4e5c85bcf6f1945493902280d501c1ed90 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/checks/ExprNoSpecificExprsCheckLevel5.cif
+++ b/cif/org.eclipse.escet.cif.tests/tests/checks/ExprNoSpecificExprsCheckLevel5.cif
@@ -317,7 +317,7 @@ end
 
 // SWITCH_EXPRS.
 group SWITCH_EXPRS:
-  invariant switch 5: case 5: true else false end;
+  invariant switch 5: case 5: true end;
 end
 
 // TIME_VAR_REFS.
diff --git a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/elim_enums1.cif b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/elim_enums1.cif
index 49bfc1438030b1f5b9fc7c099a82d41f9f9d1e3d..6de224330f55706b50a1c71c60f753b3adc7b0d6 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/elim_enums1.cif
+++ b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/elim_enums1.cif
@@ -30,6 +30,11 @@ invariant RED = GREEN, RED = RED, p.v1 = p.UP;
 automaton a:
   disc t x = BLUE;
   invariant x = BLUE;
+  invariant switch x:
+              case RED:   true
+              case GREEN: false
+              case BLUE:  true or false
+            end;
   location:
     initial;
 end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/elim_enums1.out.cif b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/elim_enums1.out.cif
index aff883b07ae03082801220a86cf5b8578853e41b..746fd5a30a0c2e12c637f0c45ce3a4ebdbd35685 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/elim_enums1.out.cif
+++ b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/elim_enums1.out.cif
@@ -9,6 +9,7 @@ end
 automaton a:
   disc t x = 2;
   invariant x = 2;
+  invariant switch x: case 0: true case 1: false case 2: true or false end;
   location:
     initial;
 end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/elim_enums2.cif b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/elim_enums2.cif
index 80ae663f2bffdacc83cc84a418a67664e80ab1d4..7262ef358731480a646673376728d99e760a80af 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/elim_enums2.cif
+++ b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/elim_enums2.cif
@@ -26,6 +26,15 @@ automaton a:
   disc x2.E v2;
   invariant v1 = x1.A or v1 = x1.B;
   invariant v2 = x2.A or v2 = x2.B;
+  invariant switch v1:
+              case x1.A: 4
+              case x1.B: 5
+            end
+            =
+            switch v2:
+              case x2.A: 4
+              case x2.B: 5
+            end;
   location:
     initial;
 end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/elim_enums2.out.cif b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/elim_enums2.out.cif
index e8b581e41ab19b7d0113f5b0237872dbce855f31..e6330650ba8aa9060aaa20528aa9fb8e5f9ee95e 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/elim_enums2.out.cif
+++ b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/elim_enums2.out.cif
@@ -7,6 +7,7 @@ automaton a:
   disc int[0..1] v2;
   invariant v1 = 0 or v1 = 1;
   invariant v2 = 1 or v2 = 0;
+  invariant switch v1: case 0: 4 case 1: 5 end = switch v2: case 1: 4 case 0: 5 end;
   location:
     initial;
 end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/elim_locs_in_exprs.cif.cif2cif.err b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/elim_locs_in_exprs.cif.cif2cif.err
index 9ffbd0a5b71bd8530b7924bca51a6b9ef3138199..1327fddd92b476f1edac8602bbd253cc9257cace 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/elim_locs_in_exprs.cif.cif2cif.err
+++ b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/elim_locs_in_exprs.cif.cif2cif.err
@@ -1,5 +1,6 @@
 WARNING: File "cif2cif/elim_locs_in_exprs.cif": Semantic warning at line 103, column 19: Switch "else" is superfluous, as all locations already have a "case".
 WARNING: File "cif2cif/elim_locs_in_exprs.cif": Semantic warning at line 113, column 19: Switch "else" is superfluous, as all locations already have a "case".
+WARNING: File "cif2cif/elim_locs_in_exprs.cif": Semantic warning at line 130, column 19: Switch "else" is superfluous, as all values already have a "case".
 WARNING: Location pointer variable "LP" for automaton "p2" is renamed to "LP2".
 WARNING: Enumeration "LPE", introduced as the type of the location pointer variable for automaton "p2", is renamed to "LPE2".
 WARNING: Enumeration literal "LOC_l1", introduced as a value of the location pointer variable for automaton "p2", is renamed to "LOC_l13".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/enums_to_consts1.cif b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/enums_to_consts1.cif
index 49bfc1438030b1f5b9fc7c099a82d41f9f9d1e3d..6de224330f55706b50a1c71c60f753b3adc7b0d6 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/enums_to_consts1.cif
+++ b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/enums_to_consts1.cif
@@ -30,6 +30,11 @@ invariant RED = GREEN, RED = RED, p.v1 = p.UP;
 automaton a:
   disc t x = BLUE;
   invariant x = BLUE;
+  invariant switch x:
+              case RED:   true
+              case GREEN: false
+              case BLUE:  true or false
+            end;
   location:
     initial;
 end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/enums_to_consts1.out.cif b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/enums_to_consts1.out.cif
index 23c59bbd80986536b1499748d3b60d5100af3910..613a182820820087c733d1904dcd1edbbcc38eb2 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/enums_to_consts1.out.cif
+++ b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/enums_to_consts1.out.cif
@@ -14,6 +14,7 @@ end
 automaton a:
   disc t x = BLUE;
   invariant x = BLUE;
+  invariant switch x: case RED: true case GREEN: false case BLUE: true or false end;
   location:
     initial;
 end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/enums_to_consts2.cif b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/enums_to_consts2.cif
index 80ae663f2bffdacc83cc84a418a67664e80ab1d4..7262ef358731480a646673376728d99e760a80af 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/enums_to_consts2.cif
+++ b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/enums_to_consts2.cif
@@ -26,6 +26,15 @@ automaton a:
   disc x2.E v2;
   invariant v1 = x1.A or v1 = x1.B;
   invariant v2 = x2.A or v2 = x2.B;
+  invariant switch v1:
+              case x1.A: 4
+              case x1.B: 5
+            end
+            =
+            switch v2:
+              case x2.A: 4
+              case x2.B: 5
+            end;
   location:
     initial;
 end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/enums_to_consts2.out.cif b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/enums_to_consts2.out.cif
index 34db8f802fff24703b95d86eeeb36417b4ba3285..9048c625831a9b3ceb39e3574708508d361a5fa3 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/enums_to_consts2.out.cif
+++ b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/enums_to_consts2.out.cif
@@ -11,6 +11,7 @@ automaton a:
   disc int[0..1] v2;
   invariant v1 = x1.A or v1 = x1.B;
   invariant v2 = x2.A or v2 = x2.B;
+  invariant switch v1: case x1.A: 4 case x1.B: 5 end = switch v2: case x2.A: 4 case x2.B: 5 end;
   location:
     initial;
 end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/enums_to_ints1.cif b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/enums_to_ints1.cif
index 49bfc1438030b1f5b9fc7c099a82d41f9f9d1e3d..6de224330f55706b50a1c71c60f753b3adc7b0d6 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/enums_to_ints1.cif
+++ b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/enums_to_ints1.cif
@@ -30,6 +30,11 @@ invariant RED = GREEN, RED = RED, p.v1 = p.UP;
 automaton a:
   disc t x = BLUE;
   invariant x = BLUE;
+  invariant switch x:
+              case RED:   true
+              case GREEN: false
+              case BLUE:  true or false
+            end;
   location:
     initial;
 end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/enums_to_ints1.out.cif b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/enums_to_ints1.out.cif
index aff883b07ae03082801220a86cf5b8578853e41b..746fd5a30a0c2e12c637f0c45ce3a4ebdbd35685 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/enums_to_ints1.out.cif
+++ b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/enums_to_ints1.out.cif
@@ -9,6 +9,7 @@ end
 automaton a:
   disc t x = 2;
   invariant x = 2;
+  invariant switch x: case 0: true case 1: false case 2: true or false end;
   location:
     initial;
 end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/enums_to_ints2.cif b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/enums_to_ints2.cif
index 80ae663f2bffdacc83cc84a418a67664e80ab1d4..7262ef358731480a646673376728d99e760a80af 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/enums_to_ints2.cif
+++ b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/enums_to_ints2.cif
@@ -26,6 +26,15 @@ automaton a:
   disc x2.E v2;
   invariant v1 = x1.A or v1 = x1.B;
   invariant v2 = x2.A or v2 = x2.B;
+  invariant switch v1:
+              case x1.A: 4
+              case x1.B: 5
+            end
+            =
+            switch v2:
+              case x2.A: 4
+              case x2.B: 5
+            end;
   location:
     initial;
 end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/enums_to_ints2.out.cif b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/enums_to_ints2.out.cif
index e8b581e41ab19b7d0113f5b0237872dbce855f31..e6330650ba8aa9060aaa20528aa9fb8e5f9ee95e 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/enums_to_ints2.out.cif
+++ b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/enums_to_ints2.out.cif
@@ -7,6 +7,7 @@ automaton a:
   disc int[0..1] v2;
   invariant v1 = 0 or v1 = 1;
   invariant v2 = 1 or v2 = 0;
+  invariant switch v1: case 0: 4 case 1: 5 end = switch v2: case 1: 4 case 0: 5 end;
   location:
     initial;
 end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/merge_enums1.cif b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/merge_enums1.cif
index a568ddc74c086475e276ee4ebd077453e56dc4a3..e3e34ed1f6f6e01848e0d31582d3b37e4c5dd908 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/merge_enums1.cif
+++ b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/merge_enums1.cif
@@ -33,6 +33,11 @@ invariant RED = GREEN, RED = RED, p.v1 = p.UP;
 automaton a:
   disc t x = BLUE;
   invariant x = BLUE;
+  invariant switch x:
+              case RED:   true
+              case GREEN: false
+              case BLUE:  true or false
+            end;
   location:
     initial;
 end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/merge_enums1.out.cif b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/merge_enums1.out.cif
index 7aaa18a81809bfceba75bfd7832a1c8166ed9cd9..4959253a6f73ecb3b6b01c823b52b3ddf85dda66 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/merge_enums1.out.cif
+++ b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/merge_enums1.out.cif
@@ -13,6 +13,7 @@ end
 automaton a:
   disc t x = BLUE;
   invariant x = BLUE;
+  invariant switch x: case RED: true case GREEN: false else true or false end;
   location:
     initial;
 end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/merge_enums2.cif b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/merge_enums2.cif
index 7be5d027dcb0da3ffc06954da2b0d95cf74d6a2c..e64f751d428e6b29b5820e7ac0172757ac8f3cf4 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/merge_enums2.cif
+++ b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/merge_enums2.cif
@@ -21,6 +21,15 @@ plant p:
   disc g1.e1 v1;
   disc g2.e2 v2;
   initial v1 = g1.A or v2 = g2.A or v1 = g1.B or v2 = g2.B;
+  invariant switch v1:
+              case g1.A: 4
+              case g1.B: 5
+            end
+            =
+            switch v2:
+              case g2.A: 4
+              case g2.B: 5
+            end;
   location:
     initial;
 end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/merge_enums2.out.cif b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/merge_enums2.out.cif
index 4d1d83e9f030ffdbe6b77e8e7f520cfa4cd12ac1..b4cbdfbbe92d1772ee19103549b5f5b296667a18 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/merge_enums2.out.cif
+++ b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/merge_enums2.out.cif
@@ -7,6 +7,7 @@ plant automaton p:
   disc E v1 = A;
   disc E v2 = B;
   initial v1 = A or v2 = A or v1 = B or v2 = B;
+  invariant switch v1: case A: 4 else 5 end = switch v2: case A: 4 else 5 end;
   location:
     initial;
 end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/simplify_values.cif.cif2cif.err b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/simplify_values.cif.cif2cif.err
new file mode 100644
index 0000000000000000000000000000000000000000..53175570117180f51bd889a8093e139c06abbdc0
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/simplify_values.cif.cif2cif.err
@@ -0,0 +1,2 @@
+WARNING: File "cif2cif/simplify_values.cif": Semantic warning at line 251, column 20: Switch "else" is superfluous, as all values already have a "case".
+WARNING: File "cif2cif/simplify_values.cif": Semantic warning at line 256, column 20: Switch "else" is superfluous, as all values already have a "case".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/simplify_values_no_refs.cif.cif2cif.err b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/simplify_values_no_refs.cif.cif2cif.err
new file mode 100644
index 0000000000000000000000000000000000000000..8be9a16cc4f6d6c73a8576e233948f8d0f10d9de
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/simplify_values_no_refs.cif.cif2cif.err
@@ -0,0 +1,2 @@
+WARNING: File "cif2cif/simplify_values_no_refs.cif": Semantic warning at line 251, column 20: Switch "else" is superfluous, as all values already have a "case".
+WARNING: File "cif2cif/simplify_values_no_refs.cif": Semantic warning at line 256, column 20: Switch "else" is superfluous, as all values already have a "case".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/simplify_values_no_refs_optimized.cif.cif2cif.err b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/simplify_values_no_refs_optimized.cif.cif2cif.err
new file mode 100644
index 0000000000000000000000000000000000000000..11ab2b8d01e3221cc26d520e1943eb2e669a1cc2
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/simplify_values_no_refs_optimized.cif.cif2cif.err
@@ -0,0 +1,2 @@
+WARNING: File "cif2cif/simplify_values_no_refs_optimized.cif": Semantic warning at line 251, column 20: Switch "else" is superfluous, as all values already have a "case".
+WARNING: File "cif2cif/simplify_values_no_refs_optimized.cif": Semantic warning at line 256, column 20: Switch "else" is superfluous, as all values already have a "case".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/cif2cif/simplify_values_optimized.cif.cif2cif.err b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/simplify_values_optimized.cif.cif2cif.err
new file mode 100644
index 0000000000000000000000000000000000000000..7421720cf2e00bd8991dee78dd32b38f73b9da37
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/cif2cif/simplify_values_optimized.cif.cif2cif.err
@@ -0,0 +1,2 @@
+WARNING: File "cif2cif/simplify_values_optimized.cif": Semantic warning at line 251, column 20: Switch "else" is superfluous, as all values already have a "case".
+WARNING: File "cif2cif/simplify_values_optimized.cif": Semantic warning at line 256, column 20: Switch "else" is superfluous, as all values already have a "case".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/asgn_var_copy.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/asgn_var_copy.cif.out
index 8bd90ff3a2d20ada81ee292bed00afebdb628360..3fec9db07a8eede4dbf9a383412338382ac4463c 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/datasynth/asgn_var_copy.cif.out
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/asgn_var_copy.cif.out
@@ -22,7 +22,7 @@ Applying variable ordering:
       Metric: wes
       Relations: legacy
       Effect: var-order
-      Number of hyper-edges: 8
+      Number of hyper-edges: 7
 
       Applying Weighted Cuthill-McKee algorithm:
         Node finder: george-liu
@@ -30,8 +30,8 @@ Applying variable ordering:
         Effect: var-order
         Number of graph edges: 3
 
-        Total span:   8 (total)   1.00 (avg/edge) / WES:   0.420000 (total)   0.052500 (avg/edge) [before]
-        Total span:   6 (total)   0.75 (avg/edge) / WES:   0.360000 (total)   0.045000 (avg/edge) [after]
+        Total span:   8 (total)   1.14 (avg/edge) / WES:   0.468571 (total)   0.066939 (avg/edge) [before]
+        Total span:   6 (total)   0.86 (avg/edge) / WES:   0.365714 (total)   0.052245 (avg/edge) [after]
 
       Found new best variable order.
 
@@ -40,8 +40,8 @@ Applying variable ordering:
         Effect: var-order
         Number of graph edges: 3
 
-        Total span:   8 (total)   1.00 (avg/edge) / WES:   0.420000 (total)   0.052500 (avg/edge) [before]
-        Total span:   6 (total)   0.75 (avg/edge) / WES:   0.360000 (total)   0.045000 (avg/edge) [after]
+        Total span:   8 (total)   1.14 (avg/edge) / WES:   0.468571 (total)   0.066939 (avg/edge) [before]
+        Total span:   6 (total)   0.86 (avg/edge) / WES:   0.365714 (total)   0.052245 (avg/edge) [after]
 
       Applying 2 orderers, sequentially:
         Applying Weighted Cuthill-McKee algorithm:
@@ -50,18 +50,16 @@ Applying variable ordering:
           Effect: var-order
           Number of graph edges: 3
 
-          Total span:   8 (total)   1.00 (avg/edge) / WES:   0.420000 (total)   0.052500 (avg/edge) [before]
-          Total span:   6 (total)   0.75 (avg/edge) / WES:   0.360000 (total)   0.045000 (avg/edge) [after]
+          Total span:   8 (total)   1.14 (avg/edge) / WES:   0.468571 (total)   0.066939 (avg/edge) [before]
+          Total span:   6 (total)   0.86 (avg/edge) / WES:   0.365714 (total)   0.052245 (avg/edge) [after]
 
         Reversing the variable order:
           Relations: legacy
           Effect: var-order
-          Number of hyper-edges: 8
+          Number of hyper-edges: 7
 
-          Total span:   6 (total)   0.75 (avg/edge) / WES:   0.360000 (total)   0.045000 (avg/edge) [before]
-          Total span:   6 (total)   0.75 (avg/edge) / WES:   0.360000 (total)   0.045000 (avg/edge) [reversed]
-
-      Found new best variable order.
+          Total span:   6 (total)   0.86 (avg/edge) / WES:   0.365714 (total)   0.052245 (avg/edge) [before]
+          Total span:   6 (total)   0.86 (avg/edge) / WES:   0.365714 (total)   0.052245 (avg/edge) [reversed]
 
       Applying 2 orderers, sequentially:
         Applying Sloan algorithm:
@@ -69,16 +67,16 @@ Applying variable ordering:
           Effect: var-order
           Number of graph edges: 3
 
-          Total span:   8 (total)   1.00 (avg/edge) / WES:   0.420000 (total)   0.052500 (avg/edge) [before]
-          Total span:   6 (total)   0.75 (avg/edge) / WES:   0.360000 (total)   0.045000 (avg/edge) [after]
+          Total span:   8 (total)   1.14 (avg/edge) / WES:   0.468571 (total)   0.066939 (avg/edge) [before]
+          Total span:   6 (total)   0.86 (avg/edge) / WES:   0.365714 (total)   0.052245 (avg/edge) [after]
 
         Reversing the variable order:
           Relations: legacy
           Effect: var-order
-          Number of hyper-edges: 8
+          Number of hyper-edges: 7
 
-          Total span:   6 (total)   0.75 (avg/edge) / WES:   0.360000 (total)   0.045000 (avg/edge) [before]
-          Total span:   6 (total)   0.75 (avg/edge) / WES:   0.360000 (total)   0.045000 (avg/edge) [reversed]
+          Total span:   6 (total)   0.86 (avg/edge) / WES:   0.365714 (total)   0.052245 (avg/edge) [before]
+          Total span:   6 (total)   0.86 (avg/edge) / WES:   0.365714 (total)   0.052245 (avg/edge) [reversed]
 
     Applying FORCE algorithm:
       Metric: total-span
@@ -87,9 +85,9 @@ Applying variable ordering:
       Number of hyper-edges: 3
       Maximum number of iterations: 20
 
-      Total span:   3 (total)   1.00 (avg/edge) / WES:   0.426667 (total)   0.142222 (avg/edge) [before]
-      Total span:   3 (total)   1.00 (avg/edge) / WES:   0.426667 (total)   0.142222 (avg/edge) [iteration 1]
-      Total span:   3 (total)   1.00 (avg/edge) / WES:   0.426667 (total)   0.142222 (avg/edge) [after]
+      Total span:   3 (total)   1.00 (avg/edge) / WES:   0.373333 (total)   0.124444 (avg/edge) [before]
+      Total span:   3 (total)   1.00 (avg/edge) / WES:   0.373333 (total)   0.124444 (avg/edge) [iteration 1]
+      Total span:   3 (total)   1.00 (avg/edge) / WES:   0.373333 (total)   0.124444 (avg/edge) [after]
 
     Applying sliding window algorithm:
       Size: 4
@@ -99,19 +97,19 @@ Applying variable ordering:
       Number of hyper-edges: 3
       Window length: 4
 
-      Total span:   3 (total)   1.00 (avg/edge) / WES:   0.426667 (total)   0.142222 (avg/edge) [before]
-      Total span:   3 (total)   1.00 (avg/edge) / WES:   0.426667 (total)   0.142222 (avg/edge) [after]
+      Total span:   3 (total)   1.00 (avg/edge) / WES:   0.373333 (total)   0.124444 (avg/edge) [before]
+      Total span:   3 (total)   1.00 (avg/edge) / WES:   0.373333 (total)   0.124444 (avg/edge) [after]
 
 Variable order changed.
 
 CIF variables and location pointers:
   Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
   -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
-  1      discrete variable  int[0..4]  p.y   0      3 * 2     5 * 2       8 * 2       ~63%
-  2      discrete variable  int[0..4]  p.x   1      3 * 2     5 * 2       8 * 2       ~63%
+  1      discrete variable  int[1..7]  p.b   0      3 * 2     7 * 2       8 * 2       ~88%
+  2      discrete variable  int[0..3]  p.a   1      2 * 2     4 * 2       4 * 2       100%
   3      discrete variable  int[3..6]  p.c   2      3 * 2     4 * 2       8 * 2       50%
-  4      discrete variable  int[0..3]  p.a   3      2 * 2     4 * 2       4 * 2       100%
-  5      discrete variable  int[1..7]  p.b   4      3 * 2     7 * 2       8 * 2       ~88%
+  4      discrete variable  int[0..4]  p.x   3      3 * 2     5 * 2       8 * 2       ~63%
+  5      discrete variable  int[0..4]  p.y   4      3 * 2     5 * 2       8 * 2       ~63%
   -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
   Total                                      5      28        50          72          ~69%
 
@@ -168,10 +166,10 @@ Controlled behavior: true -> p.y != 2 [state requirements: p.y != 2].
 
 Extending controlled-behavior predicate using variable ranges.
 
-Controlled behavior: p.y != 2 -> p.y != 2 [range: true, variable: discrete variable "p.y" of type "int[0..4]" (group: 0, domain: 0+1, BDD variables: 3, CIF/BDD values: 5/8)].
-Controlled behavior: p.y != 2 -> p.y != 2 [range: true, variable: discrete variable "p.x" of type "int[0..4]" (group: 1, domain: 2+3, BDD variables: 3, CIF/BDD values: 5/8)].
-Controlled behavior: p.y != 2 -> p.y != 2 [range: true, variable: discrete variable "p.c" of type "int[3..6]" (group: 2, domain: 4+5, BDD variables: 3, CIF/BDD values: 4/8)].
-Controlled behavior: p.y != 2 -> <bdd 13n 54p> [range: true, variable: discrete variable "p.b" of type "int[1..7]" (group: 4, domain: 8+9, BDD variables: 3, CIF/BDD values: 7/8)].
+Controlled behavior: p.y != 2 -> (p.b != 4 or p.y != 2) and ((not(p.b = 2 or p.b = 6) or p.y != 2) and (p.b = 2 or p.b = 4 or (p.b = 6 or p.y != 2))) [range: true, variable: discrete variable "p.b" of type "int[1..7]" (group: 0, domain: 0+1, BDD variables: 3, CIF/BDD values: 7/8)].
+Controlled behavior: (p.b != 4 or p.y != 2) and ((not(p.b = 2 or p.b = 6) or p.y != 2) and (p.b = 2 or p.b = 4 or (p.b = 6 or p.y != 2))) -> <bdd 10n 27p> [range: true, variable: discrete variable "p.c" of type "int[3..6]" (group: 2, domain: 4+5, BDD variables: 3, CIF/BDD values: 4/8)].
+Controlled behavior: <bdd 10n 27p> -> <bdd 13n 81p> [range: true, variable: discrete variable "p.x" of type "int[0..4]" (group: 3, domain: 6+7, BDD variables: 3, CIF/BDD values: 5/8)].
+Controlled behavior: <bdd 13n 81p> -> <bdd 13n 54p> [range: true, variable: discrete variable "p.y" of type "int[0..4]" (group: 4, domain: 8+9, BDD variables: 3, CIF/BDD values: 5/8)].
 
 Extended controlled-behavior predicate using variable ranges: <bdd 13n 54p>.
 
@@ -187,7 +185,7 @@ Backward controlled-behavior: <bdd 14n 54p> [fixed point].
 Controlled behavior: <bdd 13n 54p> -> <bdd 14n 54p>.
 
 Round 1: computing backward uncontrolled bad-state predicate.
-Backward uncontrolled bad-state: <bdd 14n 43p> [current/previous controlled behavior predicate]
+Backward uncontrolled bad-state: <bdd 14n 109p> [current/previous controlled behavior predicate]
 Backward reachability: iteration 1.
 
 Round 1: computing forward controlled-behavior predicate.
@@ -208,22 +206,22 @@ Backward reachability: iteration 1.
 Backward controlled-behavior: <bdd 12n 27p> [fixed point].
 
 Round 2: computing backward uncontrolled bad-state predicate.
-Backward uncontrolled bad-state: <bdd 12n 22p> [current/previous controlled behavior predicate]
+Backward uncontrolled bad-state: <bdd 12n 82p> [current/previous controlled behavior predicate]
 Backward reachability: iteration 1.
 
 Round 2: finished, controlled behavior is stable.
 
 Computing controlled system guards.
 
-Edge (event: p.c1) (guard: true) (assignments: p.x := p.y): guard: true -> p.y != 2 and (p.y = 0 or (p.y = 2 or p.y = 4)).
-Edge (event: p.c2) (guard: true) (assignments: p.a := p.b): guard: true -> (p.y = 0 or p.y = 4) and (p.x = 0 or p.x = 4) and ((p.c = 4 or p.c = 6) and p.b = 2) or (p.y = 0 or p.y = 4) and (p.x = 0 or p.x = 4) and ((p.c = 4 or p.c = 6) and (p.b = 1 or p.b = 3)) or ((p.y = 0 or p.y = 4) and (p.x = 0 or p.x = 4) and (p.c = 5 and p.b = 2) or (p.y = 0 or p.y = 4) and (p.x = 0 or p.x = 4) and (p.c = 5 and (p.b = 1 or p.b = 3))) or ((p.y = 0 or p.y = 4) and (p.x = 0 or p.x = 4) and (p.c = 3 and p.b = 2) or (p.y = 0 or p.y = 4) and (p.x = 0 or p.x = 4) and (p.c = 3 and (p.b = 1 or p.b = 3)) or ((p.y = 0 or p.y = 4) and p.x = 2 and ((p.c = 4 or p.c = 6) and p.b = 2) or ((p.y = 0 or p.y = 4) and p.x = 2 and ((p.c = 4 or p.c = 6) and (p.b = 1 or p.b = 3)) or (p.y = 0 or p.y = 4) and p.x = 2 and (p.c = 5 and p.b = 2)))) or ((p.y = 0 or p.y = 4) and p.x = 2 and (p.c = 5 and (p.b = 1 or p.b = 3)) or (p.y = 0 or p.y = 4) and p.x = 2 and (p.c = 3 and p.b = 2) or ((p.y = 0 or p.y = 4) and p.x = 2 and (p.c = 3 and (p.b = 1 or p.b = 3)) or (p.y = 0 or p.y = 4) and (p.x = 1 or p.x = 3) and ((p.c = 4 or p.c = 6) and p.b = 2)) or ((p.y = 0 or p.y = 4) and (p.x = 1 or p.x = 3) and ((p.c = 4 or p.c = 6) and (p.b = 1 or p.b = 3)) or (p.y = 0 or p.y = 4) and (p.x = 1 or p.x = 3) and (p.c = 5 and p.b = 2) or ((p.y = 0 or p.y = 4) and (p.x = 1 or p.x = 3) and (p.c = 5 and (p.b = 1 or p.b = 3)) or ((p.y = 0 or p.y = 4) and (p.x = 1 or p.x = 3) and (p.c = 3 and p.b = 2) or (p.y = 0 or p.y = 4) and (p.x = 1 or p.x = 3) and (p.c = 3 and (p.b = 1 or p.b = 3)))))).
-Edge (event: p.c3) (guard: true) (assignments: p.a := p.c): guard: true -> (1 <= p.y and p.y <= 3 or 1 <= p.x and p.x <= 3 or (p.c = 3 or p.c = 5)) and (1 <= p.y and p.y <= 3 or (1 <= p.x and p.x <= 3 or p.c != 5)) and ((1 <= p.y and p.y <= 3 or p.x != 2 or (p.c = 3 or p.c = 5)) and (1 <= p.y and p.y <= 3 or (p.x != 2 or p.c != 5))) and ((1 <= p.y and p.y <= 3 or (p.x = 0 or p.x = 2) or (p.x = 4 or (p.c = 3 or p.c = 5))) and (1 <= p.y and p.y <= 3 or p.x = 0 or (p.x = 2 or (p.x = 4 or p.c != 5))) and (p.y != 2 and (p.y = 0 or (p.y = 2 or p.y = 4)))).
+Edge (event: p.c1) (guard: true) (assignments: p.x := p.y): guard: true -> p.b = 4 and ((p.c = 4 or p.c = 6) and (p.y = 0 or p.y = 4)) or p.b = 4 and (p.c = 5 and (p.y = 0 or p.y = 4)) or (p.b = 4 and (p.c = 3 and (p.y = 0 or p.y = 4)) or (p.b = 2 or p.b = 6) and ((p.c = 4 or p.c = 6) and (p.y = 0 or p.y = 4))) or ((p.b = 2 or p.b = 6) and (p.c = 5 and (p.y = 0 or p.y = 4)) or (p.b = 2 or p.b = 6) and (p.c = 3 and (p.y = 0 or p.y = 4)) or ((p.b = 1 or p.b = 3 or (p.b = 5 or p.b = 7)) and ((p.c = 4 or p.c = 6) and (p.y = 0 or p.y = 4)) or ((p.b = 1 or p.b = 3 or (p.b = 5 or p.b = 7)) and (p.c = 5 and (p.y = 0 or p.y = 4)) or (p.b = 1 or p.b = 3 or (p.b = 5 or p.b = 7)) and (p.c = 3 and (p.y = 0 or p.y = 4))))).
+Edge (event: p.c2) (guard: true) (assignments: p.a := p.b): guard: true -> p.b = 2 and (p.c = 4 or p.c = 6) and ((p.x = 0 or p.x = 4) and (p.y = 0 or p.y = 4)) or p.b = 2 and (p.c = 4 or p.c = 6) and (p.x = 2 and (p.y = 0 or p.y = 4)) or (p.b = 2 and (p.c = 4 or p.c = 6) and ((p.x = 1 or p.x = 3) and (p.y = 0 or p.y = 4)) or p.b = 2 and p.c = 5 and ((p.x = 0 or p.x = 4) and (p.y = 0 or p.y = 4))) or (p.b = 2 and p.c = 5 and (p.x = 2 and (p.y = 0 or p.y = 4)) or p.b = 2 and p.c = 5 and ((p.x = 1 or p.x = 3) and (p.y = 0 or p.y = 4)) or (p.b = 2 and p.c = 3 and ((p.x = 0 or p.x = 4) and (p.y = 0 or p.y = 4)) or (p.b = 2 and p.c = 3 and (p.x = 2 and (p.y = 0 or p.y = 4)) or p.b = 2 and p.c = 3 and ((p.x = 1 or p.x = 3) and (p.y = 0 or p.y = 4))))) or ((p.b = 1 or p.b = 3) and (p.c = 4 or p.c = 6) and ((p.x = 0 or p.x = 4) and (p.y = 0 or p.y = 4)) or (p.b = 1 or p.b = 3) and (p.c = 4 or p.c = 6) and (p.x = 2 and (p.y = 0 or p.y = 4)) or ((p.b = 1 or p.b = 3) and (p.c = 4 or p.c = 6) and ((p.x = 1 or p.x = 3) and (p.y = 0 or p.y = 4)) or (p.b = 1 or p.b = 3) and p.c = 5 and ((p.x = 0 or p.x = 4) and (p.y = 0 or p.y = 4))) or ((p.b = 1 or p.b = 3) and p.c = 5 and (p.x = 2 and (p.y = 0 or p.y = 4)) or (p.b = 1 or p.b = 3) and p.c = 5 and ((p.x = 1 or p.x = 3) and (p.y = 0 or p.y = 4)) or ((p.b = 1 or p.b = 3) and p.c = 3 and ((p.x = 0 or p.x = 4) and (p.y = 0 or p.y = 4)) or ((p.b = 1 or p.b = 3) and p.c = 3 and (p.x = 2 and (p.y = 0 or p.y = 4)) or (p.b = 1 or p.b = 3) and p.c = 3 and ((p.x = 1 or p.x = 3) and (p.y = 0 or p.y = 4)))))).
+Edge (event: p.c3) (guard: true) (assignments: p.a := p.c): guard: true -> p.b = 4 and p.c = 3 and ((p.x = 0 or p.x = 4) and (p.y = 0 or p.y = 4)) or p.b = 4 and p.c = 3 and (p.x = 2 and (p.y = 0 or p.y = 4)) or (p.b = 4 and p.c = 3 and ((p.x = 1 or p.x = 3) and (p.y = 0 or p.y = 4)) or (p.b = 2 or p.b = 6) and p.c = 3 and ((p.x = 0 or p.x = 4) and (p.y = 0 or p.y = 4))) or ((p.b = 2 or p.b = 6) and p.c = 3 and (p.x = 2 and (p.y = 0 or p.y = 4)) or (p.b = 2 or p.b = 6) and p.c = 3 and ((p.x = 1 or p.x = 3) and (p.y = 0 or p.y = 4)) or ((p.b = 1 or p.b = 3 or (p.b = 5 or p.b = 7)) and p.c = 3 and ((p.x = 0 or p.x = 4) and (p.y = 0 or p.y = 4)) or ((p.b = 1 or p.b = 3 or (p.b = 5 or p.b = 7)) and p.c = 3 and (p.x = 2 and (p.y = 0 or p.y = 4)) or (p.b = 1 or p.b = 3 or (p.b = 5 or p.b = 7)) and p.c = 3 and ((p.x = 1 or p.x = 3) and (p.y = 0 or p.y = 4))))).
 
 Final synthesis result:
   State: (controlled-behavior: <bdd 12n 27p>)
-    Edge: (event: p.c1) (guard: true -> p.y != 2 and (p.y = 0 or (p.y = 2 or p.y = 4))) (assignments: p.x := p.y)
-    Edge: (event: p.c2) (guard: true -> (p.y = 0 or p.y = 4) and (p.x = 0 or p.x = 4) and ((p.c = 4 or p.c = 6) and p.b = 2) or (p.y = 0 or p.y = 4) and (p.x = 0 or p.x = 4) and ((p.c = 4 or p.c = 6) and (p.b = 1 or p.b = 3)) or ((p.y = 0 or p.y = 4) and (p.x = 0 or p.x = 4) and (p.c = 5 and p.b = 2) or (p.y = 0 or p.y = 4) and (p.x = 0 or p.x = 4) and (p.c = 5 and (p.b = 1 or p.b = 3))) or ((p.y = 0 or p.y = 4) and (p.x = 0 or p.x = 4) and (p.c = 3 and p.b = 2) or (p.y = 0 or p.y = 4) and (p.x = 0 or p.x = 4) and (p.c = 3 and (p.b = 1 or p.b = 3)) or ((p.y = 0 or p.y = 4) and p.x = 2 and ((p.c = 4 or p.c = 6) and p.b = 2) or ((p.y = 0 or p.y = 4) and p.x = 2 and ((p.c = 4 or p.c = 6) and (p.b = 1 or p.b = 3)) or (p.y = 0 or p.y = 4) and p.x = 2 and (p.c = 5 and p.b = 2)))) or ((p.y = 0 or p.y = 4) and p.x = 2 and (p.c = 5 and (p.b = 1 or p.b = 3)) or (p.y = 0 or p.y = 4) and p.x = 2 and (p.c = 3 and p.b = 2) or ((p.y = 0 or p.y = 4) and p.x = 2 and (p.c = 3 and (p.b = 1 or p.b = 3)) or (p.y = 0 or p.y = 4) and (p.x = 1 or p.x = 3) and ((p.c = 4 or p.c = 6) and p.b = 2)) or ((p.y = 0 or p.y = 4) and (p.x = 1 or p.x = 3) and ((p.c = 4 or p.c = 6) and (p.b = 1 or p.b = 3)) or (p.y = 0 or p.y = 4) and (p.x = 1 or p.x = 3) and (p.c = 5 and p.b = 2) or ((p.y = 0 or p.y = 4) and (p.x = 1 or p.x = 3) and (p.c = 5 and (p.b = 1 or p.b = 3)) or ((p.y = 0 or p.y = 4) and (p.x = 1 or p.x = 3) and (p.c = 3 and p.b = 2) or (p.y = 0 or p.y = 4) and (p.x = 1 or p.x = 3) and (p.c = 3 and (p.b = 1 or p.b = 3))))))) (assignments: p.a := p.b)
-    Edge: (event: p.c3) (guard: true -> (1 <= p.y and p.y <= 3 or 1 <= p.x and p.x <= 3 or (p.c = 3 or p.c = 5)) and (1 <= p.y and p.y <= 3 or (1 <= p.x and p.x <= 3 or p.c != 5)) and ((1 <= p.y and p.y <= 3 or p.x != 2 or (p.c = 3 or p.c = 5)) and (1 <= p.y and p.y <= 3 or (p.x != 2 or p.c != 5))) and ((1 <= p.y and p.y <= 3 or (p.x = 0 or p.x = 2) or (p.x = 4 or (p.c = 3 or p.c = 5))) and (1 <= p.y and p.y <= 3 or p.x = 0 or (p.x = 2 or (p.x = 4 or p.c != 5))) and (p.y != 2 and (p.y = 0 or (p.y = 2 or p.y = 4))))) (assignments: p.a := p.c)
+    Edge: (event: p.c1) (guard: true -> p.b = 4 and ((p.c = 4 or p.c = 6) and (p.y = 0 or p.y = 4)) or p.b = 4 and (p.c = 5 and (p.y = 0 or p.y = 4)) or (p.b = 4 and (p.c = 3 and (p.y = 0 or p.y = 4)) or (p.b = 2 or p.b = 6) and ((p.c = 4 or p.c = 6) and (p.y = 0 or p.y = 4))) or ((p.b = 2 or p.b = 6) and (p.c = 5 and (p.y = 0 or p.y = 4)) or (p.b = 2 or p.b = 6) and (p.c = 3 and (p.y = 0 or p.y = 4)) or ((p.b = 1 or p.b = 3 or (p.b = 5 or p.b = 7)) and ((p.c = 4 or p.c = 6) and (p.y = 0 or p.y = 4)) or ((p.b = 1 or p.b = 3 or (p.b = 5 or p.b = 7)) and (p.c = 5 and (p.y = 0 or p.y = 4)) or (p.b = 1 or p.b = 3 or (p.b = 5 or p.b = 7)) and (p.c = 3 and (p.y = 0 or p.y = 4)))))) (assignments: p.x := p.y)
+    Edge: (event: p.c2) (guard: true -> p.b = 2 and (p.c = 4 or p.c = 6) and ((p.x = 0 or p.x = 4) and (p.y = 0 or p.y = 4)) or p.b = 2 and (p.c = 4 or p.c = 6) and (p.x = 2 and (p.y = 0 or p.y = 4)) or (p.b = 2 and (p.c = 4 or p.c = 6) and ((p.x = 1 or p.x = 3) and (p.y = 0 or p.y = 4)) or p.b = 2 and p.c = 5 and ((p.x = 0 or p.x = 4) and (p.y = 0 or p.y = 4))) or (p.b = 2 and p.c = 5 and (p.x = 2 and (p.y = 0 or p.y = 4)) or p.b = 2 and p.c = 5 and ((p.x = 1 or p.x = 3) and (p.y = 0 or p.y = 4)) or (p.b = 2 and p.c = 3 and ((p.x = 0 or p.x = 4) and (p.y = 0 or p.y = 4)) or (p.b = 2 and p.c = 3 and (p.x = 2 and (p.y = 0 or p.y = 4)) or p.b = 2 and p.c = 3 and ((p.x = 1 or p.x = 3) and (p.y = 0 or p.y = 4))))) or ((p.b = 1 or p.b = 3) and (p.c = 4 or p.c = 6) and ((p.x = 0 or p.x = 4) and (p.y = 0 or p.y = 4)) or (p.b = 1 or p.b = 3) and (p.c = 4 or p.c = 6) and (p.x = 2 and (p.y = 0 or p.y = 4)) or ((p.b = 1 or p.b = 3) and (p.c = 4 or p.c = 6) and ((p.x = 1 or p.x = 3) and (p.y = 0 or p.y = 4)) or (p.b = 1 or p.b = 3) and p.c = 5 and ((p.x = 0 or p.x = 4) and (p.y = 0 or p.y = 4))) or ((p.b = 1 or p.b = 3) and p.c = 5 and (p.x = 2 and (p.y = 0 or p.y = 4)) or (p.b = 1 or p.b = 3) and p.c = 5 and ((p.x = 1 or p.x = 3) and (p.y = 0 or p.y = 4)) or ((p.b = 1 or p.b = 3) and p.c = 3 and ((p.x = 0 or p.x = 4) and (p.y = 0 or p.y = 4)) or ((p.b = 1 or p.b = 3) and p.c = 3 and (p.x = 2 and (p.y = 0 or p.y = 4)) or (p.b = 1 or p.b = 3) and p.c = 3 and ((p.x = 1 or p.x = 3) and (p.y = 0 or p.y = 4))))))) (assignments: p.a := p.b)
+    Edge: (event: p.c3) (guard: true -> p.b = 4 and p.c = 3 and ((p.x = 0 or p.x = 4) and (p.y = 0 or p.y = 4)) or p.b = 4 and p.c = 3 and (p.x = 2 and (p.y = 0 or p.y = 4)) or (p.b = 4 and p.c = 3 and ((p.x = 1 or p.x = 3) and (p.y = 0 or p.y = 4)) or (p.b = 2 or p.b = 6) and p.c = 3 and ((p.x = 0 or p.x = 4) and (p.y = 0 or p.y = 4))) or ((p.b = 2 or p.b = 6) and p.c = 3 and (p.x = 2 and (p.y = 0 or p.y = 4)) or (p.b = 2 or p.b = 6) and p.c = 3 and ((p.x = 1 or p.x = 3) and (p.y = 0 or p.y = 4)) or ((p.b = 1 or p.b = 3 or (p.b = 5 or p.b = 7)) and p.c = 3 and ((p.x = 0 or p.x = 4) and (p.y = 0 or p.y = 4)) or ((p.b = 1 or p.b = 3 or (p.b = 5 or p.b = 7)) and p.c = 3 and (p.x = 2 and (p.y = 0 or p.y = 4)) or (p.b = 1 or p.b = 3 or (p.b = 5 or p.b = 7)) and p.c = 3 and ((p.x = 1 or p.x = 3) and (p.y = 0 or p.y = 4)))))) (assignments: p.a := p.c)
 
 Controlled system:                     exactly 1,120 states.
 
@@ -231,7 +229,7 @@ Initial (synthesis result):            <bdd 12n 27p>
 Initial (uncontrolled system):         <bdd 14n 81p>
 Initial (controlled system):           <bdd 12n 27p>
 Initial (removed by supervisor):       <bdd 12n 27p>
-Initial (added by supervisor):         <bdd 12n 22p>
+Initial (added by supervisor):         <bdd 12n 82p>
 
 Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
   Initial: <bdd 12n 27p> -> p.y = 0 or p.y = 4 [assume <bdd 14n 81p>].
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/asgn_var_copy.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/asgn_var_copy.ctrlsys.cif
index cd0c1d2adfc5a9b80df79954a3230525ea0d933d..f47d5d226a61441de78d8ed31047a1d49932a97c 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/datasynth/asgn_var_copy.ctrlsys.cif
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/asgn_var_copy.ctrlsys.cif
@@ -20,7 +20,7 @@ supervisor automaton sup:
   location:
     initial;
     marked;
-    edge p.c1 when p.y != 2 and (p.y = 0 or (p.y = 2 or p.y = 4));
-    edge p.c2 when (p.y = 0 or p.y = 4) and (p.x = 0 or p.x = 4) and ((p.c = 4 or p.c = 6) and p.b = 2) or (p.y = 0 or p.y = 4) and (p.x = 0 or p.x = 4) and ((p.c = 4 or p.c = 6) and (p.b = 1 or p.b = 3)) or ((p.y = 0 or p.y = 4) and (p.x = 0 or p.x = 4) and (p.c = 5 and p.b = 2) or (p.y = 0 or p.y = 4) and (p.x = 0 or p.x = 4) and (p.c = 5 and (p.b = 1 or p.b = 3))) or ((p.y = 0 or p.y = 4) and (p.x = 0 or p.x = 4) and (p.c = 3 and p.b = 2) or (p.y = 0 or p.y = 4) and (p.x = 0 or p.x = 4) and (p.c = 3 and (p.b = 1 or p.b = 3)) or ((p.y = 0 or p.y = 4) and p.x = 2 and ((p.c = 4 or p.c = 6) and p.b = 2) or ((p.y = 0 or p.y = 4) and p.x = 2 and ((p.c = 4 or p.c = 6) and (p.b = 1 or p.b = 3)) or (p.y = 0 or p.y = 4) and p.x = 2 and (p.c = 5 and p.b = 2)))) or ((p.y = 0 or p.y = 4) and p.x = 2 and (p.c = 5 and (p.b = 1 or p.b = 3)) or (p.y = 0 or p.y = 4) and p.x = 2 and (p.c = 3 and p.b = 2) or ((p.y = 0 or p.y = 4) and p.x = 2 and (p.c = 3 and (p.b = 1 or p.b = 3)) or (p.y = 0 or p.y = 4) and (p.x = 1 or p.x = 3) and ((p.c = 4 or p.c = 6) and p.b = 2)) or ((p.y = 0 or p.y = 4) and (p.x = 1 or p.x = 3) and ((p.c = 4 or p.c = 6) and (p.b = 1 or p.b = 3)) or (p.y = 0 or p.y = 4) and (p.x = 1 or p.x = 3) and (p.c = 5 and p.b = 2) or ((p.y = 0 or p.y = 4) and (p.x = 1 or p.x = 3) and (p.c = 5 and (p.b = 1 or p.b = 3)) or ((p.y = 0 or p.y = 4) and (p.x = 1 or p.x = 3) and (p.c = 3 and p.b = 2) or (p.y = 0 or p.y = 4) and (p.x = 1 or p.x = 3) and (p.c = 3 and (p.b = 1 or p.b = 3))))));
-    edge p.c3 when (1 <= p.y and p.y <= 3 or 1 <= p.x and p.x <= 3 or (p.c = 3 or p.c = 5)) and (1 <= p.y and p.y <= 3 or (1 <= p.x and p.x <= 3 or p.c != 5)) and ((1 <= p.y and p.y <= 3 or p.x != 2 or (p.c = 3 or p.c = 5)) and (1 <= p.y and p.y <= 3 or (p.x != 2 or p.c != 5))) and ((1 <= p.y and p.y <= 3 or (p.x = 0 or p.x = 2) or (p.x = 4 or (p.c = 3 or p.c = 5))) and (1 <= p.y and p.y <= 3 or p.x = 0 or (p.x = 2 or (p.x = 4 or p.c != 5))) and (p.y != 2 and (p.y = 0 or (p.y = 2 or p.y = 4))));
+    edge p.c1 when p.b = 4 and ((p.c = 4 or p.c = 6) and (p.y = 0 or p.y = 4)) or p.b = 4 and (p.c = 5 and (p.y = 0 or p.y = 4)) or (p.b = 4 and (p.c = 3 and (p.y = 0 or p.y = 4)) or (p.b = 2 or p.b = 6) and ((p.c = 4 or p.c = 6) and (p.y = 0 or p.y = 4))) or ((p.b = 2 or p.b = 6) and (p.c = 5 and (p.y = 0 or p.y = 4)) or (p.b = 2 or p.b = 6) and (p.c = 3 and (p.y = 0 or p.y = 4)) or ((p.b = 1 or p.b = 3 or (p.b = 5 or p.b = 7)) and ((p.c = 4 or p.c = 6) and (p.y = 0 or p.y = 4)) or ((p.b = 1 or p.b = 3 or (p.b = 5 or p.b = 7)) and (p.c = 5 and (p.y = 0 or p.y = 4)) or (p.b = 1 or p.b = 3 or (p.b = 5 or p.b = 7)) and (p.c = 3 and (p.y = 0 or p.y = 4)))));
+    edge p.c2 when p.b = 2 and (p.c = 4 or p.c = 6) and ((p.x = 0 or p.x = 4) and (p.y = 0 or p.y = 4)) or p.b = 2 and (p.c = 4 or p.c = 6) and (p.x = 2 and (p.y = 0 or p.y = 4)) or (p.b = 2 and (p.c = 4 or p.c = 6) and ((p.x = 1 or p.x = 3) and (p.y = 0 or p.y = 4)) or p.b = 2 and p.c = 5 and ((p.x = 0 or p.x = 4) and (p.y = 0 or p.y = 4))) or (p.b = 2 and p.c = 5 and (p.x = 2 and (p.y = 0 or p.y = 4)) or p.b = 2 and p.c = 5 and ((p.x = 1 or p.x = 3) and (p.y = 0 or p.y = 4)) or (p.b = 2 and p.c = 3 and ((p.x = 0 or p.x = 4) and (p.y = 0 or p.y = 4)) or (p.b = 2 and p.c = 3 and (p.x = 2 and (p.y = 0 or p.y = 4)) or p.b = 2 and p.c = 3 and ((p.x = 1 or p.x = 3) and (p.y = 0 or p.y = 4))))) or ((p.b = 1 or p.b = 3) and (p.c = 4 or p.c = 6) and ((p.x = 0 or p.x = 4) and (p.y = 0 or p.y = 4)) or (p.b = 1 or p.b = 3) and (p.c = 4 or p.c = 6) and (p.x = 2 and (p.y = 0 or p.y = 4)) or ((p.b = 1 or p.b = 3) and (p.c = 4 or p.c = 6) and ((p.x = 1 or p.x = 3) and (p.y = 0 or p.y = 4)) or (p.b = 1 or p.b = 3) and p.c = 5 and ((p.x = 0 or p.x = 4) and (p.y = 0 or p.y = 4))) or ((p.b = 1 or p.b = 3) and p.c = 5 and (p.x = 2 and (p.y = 0 or p.y = 4)) or (p.b = 1 or p.b = 3) and p.c = 5 and ((p.x = 1 or p.x = 3) and (p.y = 0 or p.y = 4)) or ((p.b = 1 or p.b = 3) and p.c = 3 and ((p.x = 0 or p.x = 4) and (p.y = 0 or p.y = 4)) or ((p.b = 1 or p.b = 3) and p.c = 3 and (p.x = 2 and (p.y = 0 or p.y = 4)) or (p.b = 1 or p.b = 3) and p.c = 3 and ((p.x = 1 or p.x = 3) and (p.y = 0 or p.y = 4))))));
+    edge p.c3 when p.b = 4 and p.c = 3 and ((p.x = 0 or p.x = 4) and (p.y = 0 or p.y = 4)) or p.b = 4 and p.c = 3 and (p.x = 2 and (p.y = 0 or p.y = 4)) or (p.b = 4 and p.c = 3 and ((p.x = 1 or p.x = 3) and (p.y = 0 or p.y = 4)) or (p.b = 2 or p.b = 6) and p.c = 3 and ((p.x = 0 or p.x = 4) and (p.y = 0 or p.y = 4))) or ((p.b = 2 or p.b = 6) and p.c = 3 and (p.x = 2 and (p.y = 0 or p.y = 4)) or (p.b = 2 or p.b = 6) and p.c = 3 and ((p.x = 1 or p.x = 3) and (p.y = 0 or p.y = 4)) or ((p.b = 1 or p.b = 3 or (p.b = 5 or p.b = 7)) and p.c = 3 and ((p.x = 0 or p.x = 4) and (p.y = 0 or p.y = 4)) or ((p.b = 1 or p.b = 3 or (p.b = 5 or p.b = 7)) and p.c = 3 and (p.x = 2 and (p.y = 0 or p.y = 4)) or (p.b = 1 or p.b = 3 or (p.b = 5 or p.b = 7)) and p.c = 3 and ((p.x = 1 or p.x = 3) and (p.y = 0 or p.y = 4)))));
 end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/bdd_out_nodes.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/bdd_out_nodes.cif.out
index ccbe312a558d58c83d156312586f4fe6c160a52e..ae270687704bd6091371860ea018507f9d861e91 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/datasynth/bdd_out_nodes.cif.out
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/bdd_out_nodes.cif.out
@@ -23,7 +23,7 @@ Applying variable ordering:
       Metric: wes
       Relations: legacy
       Effect: var-order
-      Number of hyper-edges: 8
+      Number of hyper-edges: 7
 
       Applying Weighted Cuthill-McKee algorithm:
         Node finder: george-liu
@@ -31,8 +31,8 @@ Applying variable ordering:
         Effect: var-order
         Number of graph edges: 4
 
-        Total span:   6 (total)   0.75 (avg/edge) / WES:   0.291667 (total)   0.036458 (avg/edge) [before]
-        Total span:   3 (total)   0.38 (avg/edge) / WES:   0.194444 (total)   0.024306 (avg/edge) [after]
+        Total span:   6 (total)   0.86 (avg/edge) / WES:   0.341270 (total)   0.048753 (avg/edge) [before]
+        Total span:   3 (total)   0.43 (avg/edge) / WES:   0.198413 (total)   0.028345 (avg/edge) [after]
 
       Found new best variable order.
 
@@ -41,8 +41,8 @@ Applying variable ordering:
         Effect: var-order
         Number of graph edges: 4
 
-        Total span:   6 (total)   0.75 (avg/edge) / WES:   0.291667 (total)   0.036458 (avg/edge) [before]
-        Total span:   3 (total)   0.38 (avg/edge) / WES:   0.194444 (total)   0.024306 (avg/edge) [after]
+        Total span:   6 (total)   0.86 (avg/edge) / WES:   0.341270 (total)   0.048753 (avg/edge) [before]
+        Total span:   3 (total)   0.43 (avg/edge) / WES:   0.198413 (total)   0.028345 (avg/edge) [after]
 
       Applying 2 orderers, sequentially:
         Applying Weighted Cuthill-McKee algorithm:
@@ -51,16 +51,16 @@ Applying variable ordering:
           Effect: var-order
           Number of graph edges: 4
 
-          Total span:   6 (total)   0.75 (avg/edge) / WES:   0.291667 (total)   0.036458 (avg/edge) [before]
-          Total span:   3 (total)   0.38 (avg/edge) / WES:   0.194444 (total)   0.024306 (avg/edge) [after]
+          Total span:   6 (total)   0.86 (avg/edge) / WES:   0.341270 (total)   0.048753 (avg/edge) [before]
+          Total span:   3 (total)   0.43 (avg/edge) / WES:   0.198413 (total)   0.028345 (avg/edge) [after]
 
         Reversing the variable order:
           Relations: legacy
           Effect: var-order
-          Number of hyper-edges: 8
+          Number of hyper-edges: 7
 
-          Total span:   3 (total)   0.38 (avg/edge) / WES:   0.194444 (total)   0.024306 (avg/edge) [before]
-          Total span:   3 (total)   0.38 (avg/edge) / WES:   0.194444 (total)   0.024306 (avg/edge) [reversed]
+          Total span:   3 (total)   0.43 (avg/edge) / WES:   0.198413 (total)   0.028345 (avg/edge) [before]
+          Total span:   3 (total)   0.43 (avg/edge) / WES:   0.198413 (total)   0.028345 (avg/edge) [reversed]
 
       Applying 2 orderers, sequentially:
         Applying Sloan algorithm:
@@ -68,16 +68,16 @@ Applying variable ordering:
           Effect: var-order
           Number of graph edges: 4
 
-          Total span:   6 (total)   0.75 (avg/edge) / WES:   0.291667 (total)   0.036458 (avg/edge) [before]
-          Total span:   3 (total)   0.38 (avg/edge) / WES:   0.194444 (total)   0.024306 (avg/edge) [after]
+          Total span:   6 (total)   0.86 (avg/edge) / WES:   0.341270 (total)   0.048753 (avg/edge) [before]
+          Total span:   3 (total)   0.43 (avg/edge) / WES:   0.198413 (total)   0.028345 (avg/edge) [after]
 
         Reversing the variable order:
           Relations: legacy
           Effect: var-order
-          Number of hyper-edges: 8
+          Number of hyper-edges: 7
 
-          Total span:   3 (total)   0.38 (avg/edge) / WES:   0.194444 (total)   0.024306 (avg/edge) [before]
-          Total span:   3 (total)   0.38 (avg/edge) / WES:   0.194444 (total)   0.024306 (avg/edge) [reversed]
+          Total span:   3 (total)   0.43 (avg/edge) / WES:   0.198413 (total)   0.028345 (avg/edge) [before]
+          Total span:   3 (total)   0.43 (avg/edge) / WES:   0.198413 (total)   0.028345 (avg/edge) [reversed]
 
     Applying FORCE algorithm:
       Metric: total-span
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors01_per_edge.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors01_per_edge.cif
new file mode 100644
index 0000000000000000000000000000000000000000..e31059c1c107fa4a39964527e1fb1ecc5f4396ec
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors01_per_edge.cif
@@ -0,0 +1,28 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..7] x in any;
+
+  location l1:
+    initial;
+
+    // Overflow, two directions.
+    edge e do x := x + 1 goto l2;
+    edge e do x := x - 1 goto l2;
+
+  location l2:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors01_per_edge.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors01_per_edge.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..863e8e6dfeed9e34eeac291c41e51c027c3fa292
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors01_per_edge.cif.out
@@ -0,0 +1,220 @@
+Reading CIF file "datasynth/edge_granularity_errors01_per_edge.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      1 * 2     2 * 2       2 * 2       100%
+  2      discrete variable  int[0..7]  p.x   1      3 * 2     8 * 2       8 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 3
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 3
+
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 3
+
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 10
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [iteration 1]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 2
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..7]  p.x   0      3 * 2     8 * 2       8 * 2       100%
+  2      location pointer   n/a        p     1      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.l2
+Marked    (auts/locs marker predicate):      p.l2
+Marked    (uncontrolled system):             p.l2
+Marked    (system, combined mark/plant inv): p.l2
+Marked    (system, combined mark/state inv): p.l2
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 1, p := p.l2)
+    Edge: (event: e) (guard: p.l1) (assignments: p.x := p.x - 1, p := p.l2)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.l2 -> p.x != 7 or p.l2 [backward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 1, p := p.l2), restricted to current/previous controlled-behavior predicate: true]
+Backward controlled-behavior: p.x != 7 or p.l2 -> true [backward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x - 1, p := p.l2), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 2.
+Backward controlled-behavior: true [fixed point].
+
+Round 1: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: false [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+Backward uncontrolled bad-state: false -> p.x = 7 and p.l1 [backward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 1, p := p.l2)]
+Backward uncontrolled bad-state: p.x = 7 and p.l1 -> p.x = 0 and p.l1 or p.x = 7 and p.l1 [backward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x - 1, p := p.l2)]
+Backward reachability: iteration 2.
+Backward uncontrolled bad-state: p.x = 0 and p.l1 or p.x = 7 and p.l1 [fixed point].
+Controlled behavior: true -> (p.x != 0 or p.l2) and (p.x != 7 or p.l2).
+
+Round 1: computing forward controlled-behavior predicate.
+Forward controlled-behavior: p.l1 [initialization predicate]
+Forward controlled-behavior: p.l1 -> p.x = 4 and p.l1 or (p.x = 2 or p.x = 6) and p.l1 or ((p.x = 1 or p.x = 5) and p.l1 or p.x = 3 and p.l1) [restricted to current/previous controlled-behavior predicate: (p.x != 0 or p.l2) and (p.x != 7 or p.l2)]
+Forward reachability: iteration 1.
+Forward controlled-behavior: p.x = 4 and p.l1 or (p.x = 2 or p.x = 6) and p.l1 or ((p.x = 1 or p.x = 5) and p.l1 or p.x = 3 and p.l1) -> p.x != 0 and ((p.x != 1 or p.l1) and (p.x != 7 or p.l2)) [forward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 1, p := p.l2), restricted to current/previous controlled-behavior predicate: (p.x != 0 or p.l2) and (p.x != 7 or p.l2)]
+Forward controlled-behavior: p.x != 0 and ((p.x != 1 or p.l1) and (p.x != 7 or p.l2)) -> (p.x != 0 or p.l2) and (p.x != 7 or p.l2) [forward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x - 1, p := p.l2), restricted to current/previous controlled-behavior predicate: (p.x != 0 or p.l2) and (p.x != 7 or p.l2)]
+Forward reachability: iteration 2.
+Forward controlled-behavior: (p.x != 0 or p.l2) and (p.x != 7 or p.l2) [fixed point].
+
+Round 1: finished, need another round.
+
+Round 2: started.
+
+Round 2: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.l2 -> (p.x != 0 or p.l2) and (p.x != 7 or p.l2) [backward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 1, p := p.l2), restricted to current/previous controlled-behavior predicate: (p.x != 0 or p.l2) and (p.x != 7 or p.l2)]
+Backward reachability: iteration 2.
+Backward controlled-behavior: (p.x != 0 or p.l2) and (p.x != 7 or p.l2) [fixed point].
+
+Round 2: finished, controlled behavior is stable.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: (p.x != 0 or p.l2) and (p.x != 7 or p.l2))
+    Edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 1, p := p.l2)
+    Edge: (event: e) (guard: p.l1) (assignments: p.x := p.x - 1, p := p.l2)
+
+Controlled system:                     exactly 14 states.
+
+Initial (synthesis result):            (p.x != 0 or p.l2) and (p.x != 7 or p.l2)
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           p.x = 4 and p.l1 or (p.x = 2 or p.x = 6) and p.l1 or ((p.x = 1 or p.x = 5) and p.l1 or p.x = 3 and p.l1)
+Initial (removed by supervisor):       p.x = 0 and p.l1 or p.x = 7 and p.l1
+Initial (added by supervisor):         (p.x != 0 or p.l2) and (p.x != 7 or p.l2)
+
+Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
+  Initial: p.x = 4 and p.l1 or (p.x = 2 or p.x = 6) and p.l1 or ((p.x = 1 or p.x = 5) and p.l1 or p.x = 3 and p.l1) -> p.x != 0 and p.x != 7 [assume p.l1].
+
+Constructing output CIF specification.
+Writing output CIF file "datasynth/edge_granularity_errors01_per_edge.ctrlsys.real.cif".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors01_per_edge.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors01_per_edge.ctrlsys.cif
new file mode 100644
index 0000000000000000000000000000000000000000..bd16558b2fd2c6788e3c6567289ba65d9e4e514d
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors01_per_edge.ctrlsys.cif
@@ -0,0 +1,17 @@
+uncontrollable e;
+plant automaton p:
+  disc int[0..7] x in any;
+  location l1:
+    initial;
+    edge e do x := x + 1 goto l2;
+    edge e do x := x - 1 goto l2;
+  location l2:
+    marked;
+end
+supervisor automaton sup:
+  alphabet;
+  initial p.x != 0 and p.x != 7;
+  location:
+    initial;
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors01_per_edge.statespace.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors01_per_edge.statespace.cif
new file mode 100644
index 0000000000000000000000000000000000000000..eaa417d7e6d55e3439cf0a38280f3b60bbd31966
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors01_per_edge.statespace.cif
@@ -0,0 +1,44 @@
+uncontrollable e;
+automaton statespace:
+  alphabet e;
+  location loc1:
+    initial;
+    edge e goto loc7;
+    edge e goto loc8;
+  location loc2:
+    initial;
+    edge e goto loc9;
+    edge e goto loc10;
+  location loc3:
+    initial;
+    edge e goto loc11;
+    edge e goto loc7;
+  location loc4:
+    initial;
+    edge e goto loc12;
+    edge e goto loc9;
+  location loc5:
+    initial;
+    edge e goto loc13;
+    edge e goto loc11;
+  location loc6:
+    initial;
+    edge e goto loc14;
+    edge e goto loc12;
+  location loc7:
+    marked;
+  location loc8:
+    marked;
+  location loc9:
+    marked;
+  location loc10:
+    marked;
+  location loc11:
+    marked;
+  location loc12:
+    marked;
+  location loc13:
+    marked;
+  location loc14:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors01_per_event.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors01_per_event.cif
new file mode 100644
index 0000000000000000000000000000000000000000..e31059c1c107fa4a39964527e1fb1ecc5f4396ec
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors01_per_event.cif
@@ -0,0 +1,28 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..7] x in any;
+
+  location l1:
+    initial;
+
+    // Overflow, two directions.
+    edge e do x := x + 1 goto l2;
+    edge e do x := x - 1 goto l2;
+
+  location l2:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors01_per_event.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors01_per_event.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..409336aa4e51cce7eacf4fd0093192a9884046f6
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors01_per_event.cif.out
@@ -0,0 +1,201 @@
+Reading CIF file "datasynth/edge_granularity_errors01_per_event.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      1 * 2     2 * 2       2 * 2       100%
+  2      discrete variable  int[0..7]  p.x   1      3 * 2     8 * 2       8 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 3
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 3
+
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 3
+
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 10
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [iteration 1]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 2
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..7]  p.x   0      3 * 2     8 * 2       8 * 2       100%
+  2      location pointer   n/a        p     1      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.l2
+Marked    (auts/locs marker predicate):      p.l2
+Marked    (uncontrolled system):             p.l2
+Marked    (system, combined mark/plant inv): p.l2
+Marked    (system, combined mark/state inv): p.l2
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 1, p := p.l2 / p.x := p.x - 1, p := p.l2)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.l2 -> (p.x != 0 or p.l2) and (p.x != 7 or p.l2) [backward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 1, p := p.l2 / p.x := p.x - 1, p := p.l2), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 2.
+Backward controlled-behavior: (p.x != 0 or p.l2) and (p.x != 7 or p.l2) [fixed point].
+Controlled behavior: true -> (p.x != 0 or p.l2) and (p.x != 7 or p.l2).
+
+Round 1: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: p.x = 0 and p.l1 or p.x = 7 and p.l1 [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 1: computing forward controlled-behavior predicate.
+Forward controlled-behavior: p.l1 [initialization predicate]
+Forward controlled-behavior: p.l1 -> p.x = 4 and p.l1 or (p.x = 2 or p.x = 6) and p.l1 or ((p.x = 1 or p.x = 5) and p.l1 or p.x = 3 and p.l1) [restricted to current/previous controlled-behavior predicate: (p.x != 0 or p.l2) and (p.x != 7 or p.l2)]
+Forward reachability: iteration 1.
+Forward controlled-behavior: p.x = 4 and p.l1 or (p.x = 2 or p.x = 6) and p.l1 or ((p.x = 1 or p.x = 5) and p.l1 or p.x = 3 and p.l1) -> (p.x != 0 or p.l2) and (p.x != 7 or p.l2) [forward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 1, p := p.l2 / p.x := p.x - 1, p := p.l2), restricted to current/previous controlled-behavior predicate: (p.x != 0 or p.l2) and (p.x != 7 or p.l2)]
+Forward reachability: iteration 2.
+Forward controlled-behavior: (p.x != 0 or p.l2) and (p.x != 7 or p.l2) [fixed point].
+
+Round 1: finished, controlled behavior is stable.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: (p.x != 0 or p.l2) and (p.x != 7 or p.l2))
+    Edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 1, p := p.l2 / p.x := p.x - 1, p := p.l2)
+
+Controlled system:                     exactly 14 states.
+
+Initial (synthesis result):            (p.x != 0 or p.l2) and (p.x != 7 or p.l2)
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           p.x = 4 and p.l1 or (p.x = 2 or p.x = 6) and p.l1 or ((p.x = 1 or p.x = 5) and p.l1 or p.x = 3 and p.l1)
+Initial (removed by supervisor):       p.x = 0 and p.l1 or p.x = 7 and p.l1
+Initial (added by supervisor):         (p.x != 0 or p.l2) and (p.x != 7 or p.l2)
+
+Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
+  Initial: p.x = 4 and p.l1 or (p.x = 2 or p.x = 6) and p.l1 or ((p.x = 1 or p.x = 5) and p.l1 or p.x = 3 and p.l1) -> p.x != 0 and p.x != 7 [assume p.l1].
+
+Constructing output CIF specification.
+Writing output CIF file "datasynth/edge_granularity_errors01_per_event.ctrlsys.real.cif".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors01_per_event.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors01_per_event.ctrlsys.cif
new file mode 100644
index 0000000000000000000000000000000000000000..bd16558b2fd2c6788e3c6567289ba65d9e4e514d
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors01_per_event.ctrlsys.cif
@@ -0,0 +1,17 @@
+uncontrollable e;
+plant automaton p:
+  disc int[0..7] x in any;
+  location l1:
+    initial;
+    edge e do x := x + 1 goto l2;
+    edge e do x := x - 1 goto l2;
+  location l2:
+    marked;
+end
+supervisor automaton sup:
+  alphabet;
+  initial p.x != 0 and p.x != 7;
+  location:
+    initial;
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors01_per_event.statespace.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors01_per_event.statespace.cif
new file mode 100644
index 0000000000000000000000000000000000000000..eaa417d7e6d55e3439cf0a38280f3b60bbd31966
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors01_per_event.statespace.cif
@@ -0,0 +1,44 @@
+uncontrollable e;
+automaton statespace:
+  alphabet e;
+  location loc1:
+    initial;
+    edge e goto loc7;
+    edge e goto loc8;
+  location loc2:
+    initial;
+    edge e goto loc9;
+    edge e goto loc10;
+  location loc3:
+    initial;
+    edge e goto loc11;
+    edge e goto loc7;
+  location loc4:
+    initial;
+    edge e goto loc12;
+    edge e goto loc9;
+  location loc5:
+    initial;
+    edge e goto loc13;
+    edge e goto loc11;
+  location loc6:
+    initial;
+    edge e goto loc14;
+    edge e goto loc12;
+  location loc7:
+    marked;
+  location loc8:
+    marked;
+  location loc9:
+    marked;
+  location loc10:
+    marked;
+  location loc11:
+    marked;
+  location loc12:
+    marked;
+  location loc13:
+    marked;
+  location loc14:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors02_per_edge.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors02_per_edge.cif
new file mode 100644
index 0000000000000000000000000000000000000000..c9c5da4514dbd8174751184798887b1d4e4f96f3
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors02_per_edge.cif
@@ -0,0 +1,28 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..7] x in any;
+
+  location l1:
+    initial;
+
+    // Overflow, different steps.
+    edge e do x := x + 1 goto l2;
+    edge e do x := x + 2 goto l2;
+
+  location l2:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors02_per_edge.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors02_per_edge.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..704547029af0a1f3c503c9ba3c747eaa57f19e7b
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors02_per_edge.cif.out
@@ -0,0 +1,225 @@
+Reading CIF file "datasynth/edge_granularity_errors02_per_edge.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      1 * 2     2 * 2       2 * 2       100%
+  2      discrete variable  int[0..7]  p.x   1      3 * 2     8 * 2       8 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 3
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 3
+
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 3
+
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 10
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [iteration 1]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 2
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..7]  p.x   0      3 * 2     8 * 2       8 * 2       100%
+  2      location pointer   n/a        p     1      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.l2
+Marked    (auts/locs marker predicate):      p.l2
+Marked    (uncontrolled system):             p.l2
+Marked    (system, combined mark/plant inv): p.l2
+Marked    (system, combined mark/state inv): p.l2
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 1, p := p.l2)
+    Edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 2, p := p.l2)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.l2 -> p.x != 7 or p.l2 [backward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 1, p := p.l2), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 2.
+Backward controlled-behavior: p.x != 7 or p.l2 [fixed point].
+Controlled behavior: true -> p.x != 7 or p.l2.
+
+Round 1: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: p.x = 7 and p.l1 [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+Backward uncontrolled bad-state: p.x = 7 and p.l1 -> (p.x = 6 or p.x = 7) and p.l1 [backward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 2, p := p.l2)]
+Backward reachability: iteration 2.
+Backward uncontrolled bad-state: (p.x = 6 or p.x = 7) and p.l1 [fixed point].
+Controlled behavior: p.x != 7 or p.l2 -> 0 <= p.x and p.x <= 5 or p.l2.
+
+Round 1: computing forward controlled-behavior predicate.
+Forward controlled-behavior: p.l1 [initialization predicate]
+Forward controlled-behavior: p.l1 -> (p.x = 0 or p.x = 1 or (p.x = 4 or p.x = 5)) and p.l1 or (p.x = 2 or p.x = 3) and p.l1 [restricted to current/previous controlled-behavior predicate: 0 <= p.x and p.x <= 5 or p.l2]
+Forward reachability: iteration 1.
+Forward controlled-behavior: (p.x = 0 or p.x = 1 or (p.x = 4 or p.x = 5)) and p.l1 or (p.x = 2 or p.x = 3) and p.l1 -> (p.x != 0 or p.l1) and ((p.x != 6 or p.l2) and p.x != 7) [forward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 1, p := p.l2), restricted to current/previous controlled-behavior predicate: 0 <= p.x and p.x <= 5 or p.l2]
+Forward controlled-behavior: (p.x != 0 or p.l1) and ((p.x != 6 or p.l2) and p.x != 7) -> (p.x != 0 or p.l1) and ((p.x != 6 or p.l2) and (p.x != 7 or p.l2)) [forward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 2, p := p.l2), restricted to current/previous controlled-behavior predicate: 0 <= p.x and p.x <= 5 or p.l2]
+Forward reachability: iteration 2.
+Forward controlled-behavior: (p.x != 0 or p.l1) and ((p.x != 6 or p.l2) and (p.x != 7 or p.l2)) [fixed point].
+Controlled behavior: 0 <= p.x and p.x <= 5 or p.l2 -> (p.x != 0 or p.l1) and ((p.x != 6 or p.l2) and (p.x != 7 or p.l2)).
+
+Round 1: finished, need another round.
+
+Round 2: started.
+
+Round 2: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward controlled-behavior: p.l2 -> p.x = 4 and p.l2 or ((p.x = 2 or p.x = 6) and p.l2 or (p.x = 1 or p.x = 3 or (p.x = 5 or p.x = 7)) and p.l2) [restricted to current/previous controlled-behavior predicate: (p.x != 0 or p.l1) and ((p.x != 6 or p.l2) and (p.x != 7 or p.l2))]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.x = 4 and p.l2 or ((p.x = 2 or p.x = 6) and p.l2 or (p.x = 1 or p.x = 3 or (p.x = 5 or p.x = 7)) and p.l2) -> (p.x != 0 or p.l1) and ((p.x != 6 or p.l2) and (p.x != 7 or p.l2)) [backward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 1, p := p.l2), restricted to current/previous controlled-behavior predicate: (p.x != 0 or p.l1) and ((p.x != 6 or p.l2) and (p.x != 7 or p.l2))]
+Backward reachability: iteration 2.
+Backward controlled-behavior: (p.x != 0 or p.l1) and ((p.x != 6 or p.l2) and (p.x != 7 or p.l2)) [fixed point].
+
+Round 2: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: p.x = 0 and p.l2 or (p.x = 6 and p.l1 or p.x = 7 and p.l1) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 2: finished, controlled behavior is stable.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: (p.x != 0 or p.l1) and ((p.x != 6 or p.l2) and (p.x != 7 or p.l2)))
+    Edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 1, p := p.l2)
+    Edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 2, p := p.l2)
+
+Controlled system:                     exactly 13 states.
+
+Initial (synthesis result):            (p.x != 0 or p.l1) and ((p.x != 6 or p.l2) and (p.x != 7 or p.l2))
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           (p.x = 0 or p.x = 1 or (p.x = 4 or p.x = 5)) and p.l1 or (p.x = 2 or p.x = 3) and p.l1
+Initial (removed by supervisor):       (p.x = 6 or p.x = 7) and p.l1
+Initial (added by supervisor):         0 <= p.x and p.x <= 5 or p.l2
+
+Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
+  Initial: (p.x = 0 or p.x = 1 or (p.x = 4 or p.x = 5)) and p.l1 or (p.x = 2 or p.x = 3) and p.l1 -> 0 <= p.x and p.x <= 5 [assume p.l1].
+
+Constructing output CIF specification.
+Writing output CIF file "datasynth/edge_granularity_errors02_per_edge.ctrlsys.real.cif".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors02_per_edge.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors02_per_edge.ctrlsys.cif
new file mode 100644
index 0000000000000000000000000000000000000000..35ac2041c3a06bc0af7241988bc021de58683b30
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors02_per_edge.ctrlsys.cif
@@ -0,0 +1,17 @@
+uncontrollable e;
+plant automaton p:
+  disc int[0..7] x in any;
+  location l1:
+    initial;
+    edge e do x := x + 1 goto l2;
+    edge e do x := x + 2 goto l2;
+  location l2:
+    marked;
+end
+supervisor automaton sup:
+  alphabet;
+  initial 0 <= p.x and p.x <= 5;
+  location:
+    initial;
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors02_per_edge.statespace.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors02_per_edge.statespace.cif
new file mode 100644
index 0000000000000000000000000000000000000000..2dbdb522cfef1e62b21b1d198ed79553e8abc949
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors02_per_edge.statespace.cif
@@ -0,0 +1,42 @@
+uncontrollable e;
+automaton statespace:
+  alphabet e;
+  location loc1:
+    initial;
+    edge e goto loc7;
+    edge e goto loc8;
+  location loc2:
+    initial;
+    edge e goto loc8;
+    edge e goto loc9;
+  location loc3:
+    initial;
+    edge e goto loc9;
+    edge e goto loc10;
+  location loc4:
+    initial;
+    edge e goto loc10;
+    edge e goto loc11;
+  location loc5:
+    initial;
+    edge e goto loc11;
+    edge e goto loc12;
+  location loc6:
+    initial;
+    edge e goto loc12;
+    edge e goto loc13;
+  location loc7:
+    marked;
+  location loc8:
+    marked;
+  location loc9:
+    marked;
+  location loc10:
+    marked;
+  location loc11:
+    marked;
+  location loc12:
+    marked;
+  location loc13:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors02_per_event.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors02_per_event.cif
new file mode 100644
index 0000000000000000000000000000000000000000..c9c5da4514dbd8174751184798887b1d4e4f96f3
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors02_per_event.cif
@@ -0,0 +1,28 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..7] x in any;
+
+  location l1:
+    initial;
+
+    // Overflow, different steps.
+    edge e do x := x + 1 goto l2;
+    edge e do x := x + 2 goto l2;
+
+  location l2:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors02_per_event.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors02_per_event.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..804ac657b75c44313efe837f1ad49fb54b206929
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors02_per_event.cif.out
@@ -0,0 +1,218 @@
+Reading CIF file "datasynth/edge_granularity_errors02_per_event.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      1 * 2     2 * 2       2 * 2       100%
+  2      discrete variable  int[0..7]  p.x   1      3 * 2     8 * 2       8 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 3
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 3
+
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 3
+
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 10
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [iteration 1]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 2
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..7]  p.x   0      3 * 2     8 * 2       8 * 2       100%
+  2      location pointer   n/a        p     1      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.l2
+Marked    (auts/locs marker predicate):      p.l2
+Marked    (uncontrolled system):             p.l2
+Marked    (system, combined mark/plant inv): p.l2
+Marked    (system, combined mark/state inv): p.l2
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 1, p := p.l2 / p.x := p.x + 2, p := p.l2)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.l2 -> 0 <= p.x and p.x <= 5 or p.l2 [backward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 1, p := p.l2 / p.x := p.x + 2, p := p.l2), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 2.
+Backward controlled-behavior: 0 <= p.x and p.x <= 5 or p.l2 [fixed point].
+Controlled behavior: true -> 0 <= p.x and p.x <= 5 or p.l2.
+
+Round 1: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.x = 6 or p.x = 7) and p.l1 [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 1: computing forward controlled-behavior predicate.
+Forward controlled-behavior: p.l1 [initialization predicate]
+Forward controlled-behavior: p.l1 -> (p.x = 0 or p.x = 1 or (p.x = 4 or p.x = 5)) and p.l1 or (p.x = 2 or p.x = 3) and p.l1 [restricted to current/previous controlled-behavior predicate: 0 <= p.x and p.x <= 5 or p.l2]
+Forward reachability: iteration 1.
+Forward controlled-behavior: (p.x = 0 or p.x = 1 or (p.x = 4 or p.x = 5)) and p.l1 or (p.x = 2 or p.x = 3) and p.l1 -> (p.x != 0 or p.l1) and ((p.x != 6 or p.l2) and (p.x != 7 or p.l2)) [forward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 1, p := p.l2 / p.x := p.x + 2, p := p.l2), restricted to current/previous controlled-behavior predicate: 0 <= p.x and p.x <= 5 or p.l2]
+Forward reachability: iteration 2.
+Forward controlled-behavior: (p.x != 0 or p.l1) and ((p.x != 6 or p.l2) and (p.x != 7 or p.l2)) [fixed point].
+Controlled behavior: 0 <= p.x and p.x <= 5 or p.l2 -> (p.x != 0 or p.l1) and ((p.x != 6 or p.l2) and (p.x != 7 or p.l2)).
+
+Round 1: finished, need another round.
+
+Round 2: started.
+
+Round 2: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward controlled-behavior: p.l2 -> p.x = 4 and p.l2 or ((p.x = 2 or p.x = 6) and p.l2 or (p.x = 1 or p.x = 3 or (p.x = 5 or p.x = 7)) and p.l2) [restricted to current/previous controlled-behavior predicate: (p.x != 0 or p.l1) and ((p.x != 6 or p.l2) and (p.x != 7 or p.l2))]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.x = 4 and p.l2 or ((p.x = 2 or p.x = 6) and p.l2 or (p.x = 1 or p.x = 3 or (p.x = 5 or p.x = 7)) and p.l2) -> (p.x != 0 or p.l1) and ((p.x != 6 or p.l2) and (p.x != 7 or p.l2)) [backward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 1, p := p.l2 / p.x := p.x + 2, p := p.l2), restricted to current/previous controlled-behavior predicate: (p.x != 0 or p.l1) and ((p.x != 6 or p.l2) and (p.x != 7 or p.l2))]
+Backward reachability: iteration 2.
+Backward controlled-behavior: (p.x != 0 or p.l1) and ((p.x != 6 or p.l2) and (p.x != 7 or p.l2)) [fixed point].
+
+Round 2: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: p.x = 0 and p.l2 or (p.x = 6 and p.l1 or p.x = 7 and p.l1) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 2: finished, controlled behavior is stable.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: (p.x != 0 or p.l1) and ((p.x != 6 or p.l2) and (p.x != 7 or p.l2)))
+    Edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 1, p := p.l2 / p.x := p.x + 2, p := p.l2)
+
+Controlled system:                     exactly 13 states.
+
+Initial (synthesis result):            (p.x != 0 or p.l1) and ((p.x != 6 or p.l2) and (p.x != 7 or p.l2))
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           (p.x = 0 or p.x = 1 or (p.x = 4 or p.x = 5)) and p.l1 or (p.x = 2 or p.x = 3) and p.l1
+Initial (removed by supervisor):       (p.x = 6 or p.x = 7) and p.l1
+Initial (added by supervisor):         0 <= p.x and p.x <= 5 or p.l2
+
+Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
+  Initial: (p.x = 0 or p.x = 1 or (p.x = 4 or p.x = 5)) and p.l1 or (p.x = 2 or p.x = 3) and p.l1 -> 0 <= p.x and p.x <= 5 [assume p.l1].
+
+Constructing output CIF specification.
+Writing output CIF file "datasynth/edge_granularity_errors02_per_event.ctrlsys.real.cif".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors02_per_event.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors02_per_event.ctrlsys.cif
new file mode 100644
index 0000000000000000000000000000000000000000..35ac2041c3a06bc0af7241988bc021de58683b30
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors02_per_event.ctrlsys.cif
@@ -0,0 +1,17 @@
+uncontrollable e;
+plant automaton p:
+  disc int[0..7] x in any;
+  location l1:
+    initial;
+    edge e do x := x + 1 goto l2;
+    edge e do x := x + 2 goto l2;
+  location l2:
+    marked;
+end
+supervisor automaton sup:
+  alphabet;
+  initial 0 <= p.x and p.x <= 5;
+  location:
+    initial;
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors02_per_event.statespace.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors02_per_event.statespace.cif
new file mode 100644
index 0000000000000000000000000000000000000000..2dbdb522cfef1e62b21b1d198ed79553e8abc949
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors02_per_event.statespace.cif
@@ -0,0 +1,42 @@
+uncontrollable e;
+automaton statespace:
+  alphabet e;
+  location loc1:
+    initial;
+    edge e goto loc7;
+    edge e goto loc8;
+  location loc2:
+    initial;
+    edge e goto loc8;
+    edge e goto loc9;
+  location loc3:
+    initial;
+    edge e goto loc9;
+    edge e goto loc10;
+  location loc4:
+    initial;
+    edge e goto loc10;
+    edge e goto loc11;
+  location loc5:
+    initial;
+    edge e goto loc11;
+    edge e goto loc12;
+  location loc6:
+    initial;
+    edge e goto loc12;
+    edge e goto loc13;
+  location loc7:
+    marked;
+  location loc8:
+    marked;
+  location loc9:
+    marked;
+  location loc10:
+    marked;
+  location loc11:
+    marked;
+  location loc12:
+    marked;
+  location loc13:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors03_per_edge.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors03_per_edge.cif
new file mode 100644
index 0000000000000000000000000000000000000000..b22b696d939dcd9be9e0bb46cfdd1f8e0b856ec9
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors03_per_edge.cif
@@ -0,0 +1,28 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..7] x in any;
+
+  location l1:
+    initial;
+
+    // One overflow, other not.
+    edge e do x := x + 1 goto l2;
+    edge e do x := 5     goto l2;
+
+  location l2:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors03_per_edge.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors03_per_edge.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..429a3f3a93b6609384e8c68006698a8b9c431967
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors03_per_edge.cif.out
@@ -0,0 +1,224 @@
+Reading CIF file "datasynth/edge_granularity_errors03_per_edge.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      1 * 2     2 * 2       2 * 2       100%
+  2      discrete variable  int[0..7]  p.x   1      3 * 2     8 * 2       8 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 3
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 3
+
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 3
+
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 10
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [iteration 1]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 2
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..7]  p.x   0      3 * 2     8 * 2       8 * 2       100%
+  2      location pointer   n/a        p     1      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.l2
+Marked    (auts/locs marker predicate):      p.l2
+Marked    (uncontrolled system):             p.l2
+Marked    (system, combined mark/plant inv): p.l2
+Marked    (system, combined mark/state inv): p.l2
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 1, p := p.l2)
+    Edge: (event: e) (guard: p.l1) (assignments: p.x := 5, p := p.l2)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.l2 -> p.x != 7 or p.l2 [backward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 1, p := p.l2), restricted to current/previous controlled-behavior predicate: true]
+Backward controlled-behavior: p.x != 7 or p.l2 -> true [backward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := 5, p := p.l2), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 2.
+Backward controlled-behavior: true [fixed point].
+
+Round 1: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: false [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+Backward uncontrolled bad-state: false -> p.x = 7 and p.l1 [backward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 1, p := p.l2)]
+Backward reachability: iteration 2.
+Backward uncontrolled bad-state: p.x = 7 and p.l1 [fixed point].
+Controlled behavior: true -> p.x != 7 or p.l2.
+
+Round 1: computing forward controlled-behavior predicate.
+Forward controlled-behavior: p.l1 [initialization predicate]
+Forward controlled-behavior: p.l1 -> (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) and p.l1 or ((p.x = 1 or p.x = 5) and p.l1 or p.x = 3 and p.l1) [restricted to current/previous controlled-behavior predicate: p.x != 7 or p.l2]
+Forward reachability: iteration 1.
+Forward controlled-behavior: (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) and p.l1 or ((p.x = 1 or p.x = 5) and p.l1 or p.x = 3 and p.l1) -> (p.x != 0 or p.l1) and (p.x != 7 or p.l2) [forward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 1, p := p.l2), restricted to current/previous controlled-behavior predicate: p.x != 7 or p.l2]
+Forward reachability: iteration 2.
+Forward controlled-behavior: (p.x != 0 or p.l1) and (p.x != 7 or p.l2) [fixed point].
+Controlled behavior: p.x != 7 or p.l2 -> (p.x != 0 or p.l1) and (p.x != 7 or p.l2).
+
+Round 1: finished, need another round.
+
+Round 2: started.
+
+Round 2: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward controlled-behavior: p.l2 -> p.x = 4 and p.l2 or ((p.x = 2 or p.x = 6) and p.l2 or (p.x = 1 or p.x = 3 or (p.x = 5 or p.x = 7)) and p.l2) [restricted to current/previous controlled-behavior predicate: (p.x != 0 or p.l1) and (p.x != 7 or p.l2)]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.x = 4 and p.l2 or ((p.x = 2 or p.x = 6) and p.l2 or (p.x = 1 or p.x = 3 or (p.x = 5 or p.x = 7)) and p.l2) -> (p.x != 0 or p.l1) and (p.x != 7 or p.l2) [backward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 1, p := p.l2), restricted to current/previous controlled-behavior predicate: (p.x != 0 or p.l1) and (p.x != 7 or p.l2)]
+Backward reachability: iteration 2.
+Backward controlled-behavior: (p.x != 0 or p.l1) and (p.x != 7 or p.l2) [fixed point].
+
+Round 2: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: p.x = 0 and p.l2 or p.x = 7 and p.l1 [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 2: finished, controlled behavior is stable.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: (p.x != 0 or p.l1) and (p.x != 7 or p.l2))
+    Edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 1, p := p.l2)
+    Edge: (event: e) (guard: p.l1) (assignments: p.x := 5, p := p.l2)
+
+Controlled system:                     exactly 14 states.
+
+Initial (synthesis result):            (p.x != 0 or p.l1) and (p.x != 7 or p.l2)
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) and p.l1 or ((p.x = 1 or p.x = 5) and p.l1 or p.x = 3 and p.l1)
+Initial (removed by supervisor):       p.x = 7 and p.l1
+Initial (added by supervisor):         p.x != 7 or p.l2
+
+Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
+  Initial: (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) and p.l1 or ((p.x = 1 or p.x = 5) and p.l1 or p.x = 3 and p.l1) -> p.x != 7 [assume p.l1].
+
+Constructing output CIF specification.
+Writing output CIF file "datasynth/edge_granularity_errors03_per_edge.ctrlsys.real.cif".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors03_per_edge.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors03_per_edge.ctrlsys.cif
new file mode 100644
index 0000000000000000000000000000000000000000..079631ca7d6588bf7c1d18f59ecc688b1fe2b998
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors03_per_edge.ctrlsys.cif
@@ -0,0 +1,17 @@
+uncontrollable e;
+plant automaton p:
+  disc int[0..7] x in any;
+  location l1:
+    initial;
+    edge e do x := x + 1 goto l2;
+    edge e do x := 5 goto l2;
+  location l2:
+    marked;
+end
+supervisor automaton sup:
+  alphabet;
+  initial p.x != 7;
+  location:
+    initial;
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors03_per_edge.statespace.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors03_per_edge.statespace.cif
new file mode 100644
index 0000000000000000000000000000000000000000..94de2bedc4b5f428a9013287e48f30168ffcb335
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors03_per_edge.statespace.cif
@@ -0,0 +1,45 @@
+uncontrollable e;
+automaton statespace:
+  alphabet e;
+  location loc1:
+    initial;
+    edge e goto loc8;
+    edge e goto loc9;
+  location loc2:
+    initial;
+    edge e goto loc10;
+    edge e goto loc9;
+  location loc3:
+    initial;
+    edge e goto loc11;
+    edge e goto loc9;
+  location loc4:
+    initial;
+    edge e goto loc12;
+    edge e goto loc9;
+  location loc5:
+    initial;
+    edge e goto loc9;
+  location loc6:
+    initial;
+    edge e goto loc13;
+    edge e goto loc9;
+  location loc7:
+    initial;
+    edge e goto loc14;
+    edge e goto loc9;
+  location loc8:
+    marked;
+  location loc9:
+    marked;
+  location loc10:
+    marked;
+  location loc11:
+    marked;
+  location loc12:
+    marked;
+  location loc13:
+    marked;
+  location loc14:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors03_per_event.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors03_per_event.cif
new file mode 100644
index 0000000000000000000000000000000000000000..b22b696d939dcd9be9e0bb46cfdd1f8e0b856ec9
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors03_per_event.cif
@@ -0,0 +1,28 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..7] x in any;
+
+  location l1:
+    initial;
+
+    // One overflow, other not.
+    edge e do x := x + 1 goto l2;
+    edge e do x := 5     goto l2;
+
+  location l2:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors03_per_event.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors03_per_event.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..12130308733e276baa33375b24969e5982917fc9
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors03_per_event.cif.out
@@ -0,0 +1,218 @@
+Reading CIF file "datasynth/edge_granularity_errors03_per_event.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      1 * 2     2 * 2       2 * 2       100%
+  2      discrete variable  int[0..7]  p.x   1      3 * 2     8 * 2       8 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 3
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 3
+
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 3
+
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.222222 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 10
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [iteration 1]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 2
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..7]  p.x   0      3 * 2     8 * 2       8 * 2       100%
+  2      location pointer   n/a        p     1      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.l2
+Marked    (auts/locs marker predicate):      p.l2
+Marked    (uncontrolled system):             p.l2
+Marked    (system, combined mark/plant inv): p.l2
+Marked    (system, combined mark/state inv): p.l2
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 1, p := p.l2 / p.x := 5, p := p.l2)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.l2 -> p.x != 7 or p.l2 [backward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 1, p := p.l2 / p.x := 5, p := p.l2), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 2.
+Backward controlled-behavior: p.x != 7 or p.l2 [fixed point].
+Controlled behavior: true -> p.x != 7 or p.l2.
+
+Round 1: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: p.x = 7 and p.l1 [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 1: computing forward controlled-behavior predicate.
+Forward controlled-behavior: p.l1 [initialization predicate]
+Forward controlled-behavior: p.l1 -> (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) and p.l1 or ((p.x = 1 or p.x = 5) and p.l1 or p.x = 3 and p.l1) [restricted to current/previous controlled-behavior predicate: p.x != 7 or p.l2]
+Forward reachability: iteration 1.
+Forward controlled-behavior: (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) and p.l1 or ((p.x = 1 or p.x = 5) and p.l1 or p.x = 3 and p.l1) -> (p.x != 0 or p.l1) and (p.x != 7 or p.l2) [forward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 1, p := p.l2 / p.x := 5, p := p.l2), restricted to current/previous controlled-behavior predicate: p.x != 7 or p.l2]
+Forward reachability: iteration 2.
+Forward controlled-behavior: (p.x != 0 or p.l1) and (p.x != 7 or p.l2) [fixed point].
+Controlled behavior: p.x != 7 or p.l2 -> (p.x != 0 or p.l1) and (p.x != 7 or p.l2).
+
+Round 1: finished, need another round.
+
+Round 2: started.
+
+Round 2: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward controlled-behavior: p.l2 -> p.x = 4 and p.l2 or ((p.x = 2 or p.x = 6) and p.l2 or (p.x = 1 or p.x = 3 or (p.x = 5 or p.x = 7)) and p.l2) [restricted to current/previous controlled-behavior predicate: (p.x != 0 or p.l1) and (p.x != 7 or p.l2)]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.x = 4 and p.l2 or ((p.x = 2 or p.x = 6) and p.l2 or (p.x = 1 or p.x = 3 or (p.x = 5 or p.x = 7)) and p.l2) -> (p.x != 0 or p.l1) and (p.x != 7 or p.l2) [backward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 1, p := p.l2 / p.x := 5, p := p.l2), restricted to current/previous controlled-behavior predicate: (p.x != 0 or p.l1) and (p.x != 7 or p.l2)]
+Backward reachability: iteration 2.
+Backward controlled-behavior: (p.x != 0 or p.l1) and (p.x != 7 or p.l2) [fixed point].
+
+Round 2: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: p.x = 0 and p.l2 or p.x = 7 and p.l1 [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 2: finished, controlled behavior is stable.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: (p.x != 0 or p.l1) and (p.x != 7 or p.l2))
+    Edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 1, p := p.l2 / p.x := 5, p := p.l2)
+
+Controlled system:                     exactly 14 states.
+
+Initial (synthesis result):            (p.x != 0 or p.l1) and (p.x != 7 or p.l2)
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) and p.l1 or ((p.x = 1 or p.x = 5) and p.l1 or p.x = 3 and p.l1)
+Initial (removed by supervisor):       p.x = 7 and p.l1
+Initial (added by supervisor):         p.x != 7 or p.l2
+
+Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
+  Initial: (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) and p.l1 or ((p.x = 1 or p.x = 5) and p.l1 or p.x = 3 and p.l1) -> p.x != 7 [assume p.l1].
+
+Constructing output CIF specification.
+Writing output CIF file "datasynth/edge_granularity_errors03_per_event.ctrlsys.real.cif".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors03_per_event.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors03_per_event.ctrlsys.cif
new file mode 100644
index 0000000000000000000000000000000000000000..079631ca7d6588bf7c1d18f59ecc688b1fe2b998
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors03_per_event.ctrlsys.cif
@@ -0,0 +1,17 @@
+uncontrollable e;
+plant automaton p:
+  disc int[0..7] x in any;
+  location l1:
+    initial;
+    edge e do x := x + 1 goto l2;
+    edge e do x := 5 goto l2;
+  location l2:
+    marked;
+end
+supervisor automaton sup:
+  alphabet;
+  initial p.x != 7;
+  location:
+    initial;
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors03_per_event.statespace.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors03_per_event.statespace.cif
new file mode 100644
index 0000000000000000000000000000000000000000..94de2bedc4b5f428a9013287e48f30168ffcb335
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors03_per_event.statespace.cif
@@ -0,0 +1,45 @@
+uncontrollable e;
+automaton statespace:
+  alphabet e;
+  location loc1:
+    initial;
+    edge e goto loc8;
+    edge e goto loc9;
+  location loc2:
+    initial;
+    edge e goto loc10;
+    edge e goto loc9;
+  location loc3:
+    initial;
+    edge e goto loc11;
+    edge e goto loc9;
+  location loc4:
+    initial;
+    edge e goto loc12;
+    edge e goto loc9;
+  location loc5:
+    initial;
+    edge e goto loc9;
+  location loc6:
+    initial;
+    edge e goto loc13;
+    edge e goto loc9;
+  location loc7:
+    initial;
+    edge e goto loc14;
+    edge e goto loc9;
+  location loc8:
+    marked;
+  location loc9:
+    marked;
+  location loc10:
+    marked;
+  location loc11:
+    marked;
+  location loc12:
+    marked;
+  location loc13:
+    marked;
+  location loc14:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors04_per_edge.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors04_per_edge.cif
new file mode 100644
index 0000000000000000000000000000000000000000..fa374cb2f2d3f020a5d15d61c8b506a7b126e1e4
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors04_per_edge.cif
@@ -0,0 +1,28 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..7] x in any;
+
+  location l1:
+    initial;
+
+    // Same guards, same overflow.
+    edge e when x = 7 do x := x + 1 goto l2;
+    edge e when x = 7 do x := x + 1 goto l2;
+
+  location l2:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors04_per_edge.cif.err b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors04_per_edge.cif.err
new file mode 100644
index 0000000000000000000000000000000000000000..95e550ab22fe99975ad9d89b94b2dab14fd7eafd
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors04_per_edge.cif.err
@@ -0,0 +1 @@
+ERROR: Empty supervisor.
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors04_per_edge.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors04_per_edge.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..652d0183afd38d57a328bfbf17d79759aecb7f68
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors04_per_edge.cif.out
@@ -0,0 +1,182 @@
+Reading CIF file "datasynth/edge_granularity_errors04_per_edge.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      1 * 2     2 * 2       2 * 2       100%
+  2      discrete variable  int[0..7]  p.x   1      3 * 2     8 * 2       8 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 5
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 10
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [iteration 1]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 2
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..7]  p.x   0      3 * 2     8 * 2       8 * 2       100%
+  2      location pointer   n/a        p     1      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.l2
+Marked    (auts/locs marker predicate):      p.l2
+Marked    (uncontrolled system):             p.l2
+Marked    (system, combined mark/plant inv): p.l2
+Marked    (system, combined mark/state inv): p.l2
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: p.x = 7 and p.l1) (assignments: p.x := p.x + 1, p := p.l2)
+    Edge: (event: e) (guard: p.x = 7 and p.l1) (assignments: p.x := p.x + 1, p := p.l2)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward reachability: iteration 1.
+Controlled behavior: true -> p.l2.
+
+Round 1: finished, no initialization possible.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: p.l2)
+    Edge: (event: e) (guard: p.x = 7 and p.l1) (assignments: p.x := p.x + 1, p := p.l2)
+    Edge: (event: e) (guard: p.x = 7 and p.l1) (assignments: p.x := p.x + 1, p := p.l2)
+
+Controlled system:                     exactly 0 states.
+
+Initial (synthesis result):            p.l2
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           false
+Initial (removed by supervisor):       p.l1
+Initial (added by supervisor):         p.l2
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors04_per_event.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors04_per_event.cif
new file mode 100644
index 0000000000000000000000000000000000000000..fa374cb2f2d3f020a5d15d61c8b506a7b126e1e4
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors04_per_event.cif
@@ -0,0 +1,28 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..7] x in any;
+
+  location l1:
+    initial;
+
+    // Same guards, same overflow.
+    edge e when x = 7 do x := x + 1 goto l2;
+    edge e when x = 7 do x := x + 1 goto l2;
+
+  location l2:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors04_per_event.cif.err b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors04_per_event.cif.err
new file mode 100644
index 0000000000000000000000000000000000000000..95e550ab22fe99975ad9d89b94b2dab14fd7eafd
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors04_per_event.cif.err
@@ -0,0 +1 @@
+ERROR: Empty supervisor.
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors04_per_event.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors04_per_event.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..39a896c56eed14658d36cb11863aed839b988404
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors04_per_event.cif.out
@@ -0,0 +1,180 @@
+Reading CIF file "datasynth/edge_granularity_errors04_per_event.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      1 * 2     2 * 2       2 * 2       100%
+  2      discrete variable  int[0..7]  p.x   1      3 * 2     8 * 2       8 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 5
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 10
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [iteration 1]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 2
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..7]  p.x   0      3 * 2     8 * 2       8 * 2       100%
+  2      location pointer   n/a        p     1      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.l2
+Marked    (auts/locs marker predicate):      p.l2
+Marked    (uncontrolled system):             p.l2
+Marked    (system, combined mark/plant inv): p.l2
+Marked    (system, combined mark/state inv): p.l2
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: p.x = 7 and p.l1) (assignments: p.x := p.x + 1, p := p.l2 / p.x := p.x + 1, p := p.l2)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward reachability: iteration 1.
+Controlled behavior: true -> p.l2.
+
+Round 1: finished, no initialization possible.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: p.l2)
+    Edge: (event: e) (guard: p.x = 7 and p.l1) (assignments: p.x := p.x + 1, p := p.l2 / p.x := p.x + 1, p := p.l2)
+
+Controlled system:                     exactly 0 states.
+
+Initial (synthesis result):            p.l2
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           false
+Initial (removed by supervisor):       p.l1
+Initial (added by supervisor):         p.l2
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors05_per_edge.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors05_per_edge.cif
new file mode 100644
index 0000000000000000000000000000000000000000..18354a10cc0ab85ded58c21ba1bf9a48cbbf5096
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors05_per_edge.cif
@@ -0,0 +1,28 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..7] x in any;
+
+  location l1:
+    initial;
+
+    // Same guards, different overflow.
+    edge e when x = 7 do x := x + 1 goto l2;
+    edge e when x = 7 do x := x + 2 goto l2;
+
+  location l2:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors05_per_edge.cif.err b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors05_per_edge.cif.err
new file mode 100644
index 0000000000000000000000000000000000000000..95e550ab22fe99975ad9d89b94b2dab14fd7eafd
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors05_per_edge.cif.err
@@ -0,0 +1 @@
+ERROR: Empty supervisor.
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors05_per_edge.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors05_per_edge.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..b8ef395a7cc09cf961a59c909b5fc9931cddd279
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors05_per_edge.cif.out
@@ -0,0 +1,182 @@
+Reading CIF file "datasynth/edge_granularity_errors05_per_edge.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      1 * 2     2 * 2       2 * 2       100%
+  2      discrete variable  int[0..7]  p.x   1      3 * 2     8 * 2       8 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 5
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 10
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [iteration 1]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 2
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..7]  p.x   0      3 * 2     8 * 2       8 * 2       100%
+  2      location pointer   n/a        p     1      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.l2
+Marked    (auts/locs marker predicate):      p.l2
+Marked    (uncontrolled system):             p.l2
+Marked    (system, combined mark/plant inv): p.l2
+Marked    (system, combined mark/state inv): p.l2
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: p.x = 7 and p.l1) (assignments: p.x := p.x + 1, p := p.l2)
+    Edge: (event: e) (guard: p.x = 7 and p.l1) (assignments: p.x := p.x + 2, p := p.l2)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward reachability: iteration 1.
+Controlled behavior: true -> p.l2.
+
+Round 1: finished, no initialization possible.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: p.l2)
+    Edge: (event: e) (guard: p.x = 7 and p.l1) (assignments: p.x := p.x + 1, p := p.l2)
+    Edge: (event: e) (guard: p.x = 7 and p.l1) (assignments: p.x := p.x + 2, p := p.l2)
+
+Controlled system:                     exactly 0 states.
+
+Initial (synthesis result):            p.l2
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           false
+Initial (removed by supervisor):       p.l1
+Initial (added by supervisor):         p.l2
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors05_per_event.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors05_per_event.cif
new file mode 100644
index 0000000000000000000000000000000000000000..18354a10cc0ab85ded58c21ba1bf9a48cbbf5096
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors05_per_event.cif
@@ -0,0 +1,28 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..7] x in any;
+
+  location l1:
+    initial;
+
+    // Same guards, different overflow.
+    edge e when x = 7 do x := x + 1 goto l2;
+    edge e when x = 7 do x := x + 2 goto l2;
+
+  location l2:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors05_per_event.cif.err b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors05_per_event.cif.err
new file mode 100644
index 0000000000000000000000000000000000000000..95e550ab22fe99975ad9d89b94b2dab14fd7eafd
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors05_per_event.cif.err
@@ -0,0 +1 @@
+ERROR: Empty supervisor.
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors05_per_event.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors05_per_event.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..022c43397f3776a4cd31a255ee97ff54ef884edf
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors05_per_event.cif.out
@@ -0,0 +1,180 @@
+Reading CIF file "datasynth/edge_granularity_errors05_per_event.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      1 * 2     2 * 2       2 * 2       100%
+  2      discrete variable  int[0..7]  p.x   1      3 * 2     8 * 2       8 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 5
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 10
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [iteration 1]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 2
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..7]  p.x   0      3 * 2     8 * 2       8 * 2       100%
+  2      location pointer   n/a        p     1      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.l2
+Marked    (auts/locs marker predicate):      p.l2
+Marked    (uncontrolled system):             p.l2
+Marked    (system, combined mark/plant inv): p.l2
+Marked    (system, combined mark/state inv): p.l2
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: p.x = 7 and p.l1) (assignments: p.x := p.x + 1, p := p.l2 / p.x := p.x + 2, p := p.l2)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward reachability: iteration 1.
+Controlled behavior: true -> p.l2.
+
+Round 1: finished, no initialization possible.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: p.l2)
+    Edge: (event: e) (guard: p.x = 7 and p.l1) (assignments: p.x := p.x + 1, p := p.l2 / p.x := p.x + 2, p := p.l2)
+
+Controlled system:                     exactly 0 states.
+
+Initial (synthesis result):            p.l2
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           false
+Initial (removed by supervisor):       p.l1
+Initial (added by supervisor):         p.l2
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors06_per_edge.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors06_per_edge.cif
new file mode 100644
index 0000000000000000000000000000000000000000..dce884ad79305b597d27d64f60c1b10673d93983
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors06_per_edge.cif
@@ -0,0 +1,28 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..7] x in any;
+
+  location l1:
+    initial;
+
+    // Different guards, same overflow.
+    edge e when x = 6 do x := x + 2 goto l2;
+    edge e when x = 7 do x := x + 1 goto l2;
+
+  location l2:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors06_per_edge.cif.err b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors06_per_edge.cif.err
new file mode 100644
index 0000000000000000000000000000000000000000..95e550ab22fe99975ad9d89b94b2dab14fd7eafd
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors06_per_edge.cif.err
@@ -0,0 +1 @@
+ERROR: Empty supervisor.
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors06_per_edge.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors06_per_edge.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..a1c9c0eef29024028debcc2d265094cce15ee14c
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors06_per_edge.cif.out
@@ -0,0 +1,182 @@
+Reading CIF file "datasynth/edge_granularity_errors06_per_edge.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      1 * 2     2 * 2       2 * 2       100%
+  2      discrete variable  int[0..7]  p.x   1      3 * 2     8 * 2       8 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 5
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 10
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [iteration 1]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 2
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..7]  p.x   0      3 * 2     8 * 2       8 * 2       100%
+  2      location pointer   n/a        p     1      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.l2
+Marked    (auts/locs marker predicate):      p.l2
+Marked    (uncontrolled system):             p.l2
+Marked    (system, combined mark/plant inv): p.l2
+Marked    (system, combined mark/state inv): p.l2
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: p.x = 6 and p.l1) (assignments: p.x := p.x + 2, p := p.l2)
+    Edge: (event: e) (guard: p.x = 7 and p.l1) (assignments: p.x := p.x + 1, p := p.l2)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward reachability: iteration 1.
+Controlled behavior: true -> p.l2.
+
+Round 1: finished, no initialization possible.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: p.l2)
+    Edge: (event: e) (guard: p.x = 6 and p.l1) (assignments: p.x := p.x + 2, p := p.l2)
+    Edge: (event: e) (guard: p.x = 7 and p.l1) (assignments: p.x := p.x + 1, p := p.l2)
+
+Controlled system:                     exactly 0 states.
+
+Initial (synthesis result):            p.l2
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           false
+Initial (removed by supervisor):       p.l1
+Initial (added by supervisor):         p.l2
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors06_per_event.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors06_per_event.cif
new file mode 100644
index 0000000000000000000000000000000000000000..dce884ad79305b597d27d64f60c1b10673d93983
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors06_per_event.cif
@@ -0,0 +1,28 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..7] x in any;
+
+  location l1:
+    initial;
+
+    // Different guards, same overflow.
+    edge e when x = 6 do x := x + 2 goto l2;
+    edge e when x = 7 do x := x + 1 goto l2;
+
+  location l2:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors06_per_event.cif.err b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors06_per_event.cif.err
new file mode 100644
index 0000000000000000000000000000000000000000..95e550ab22fe99975ad9d89b94b2dab14fd7eafd
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors06_per_event.cif.err
@@ -0,0 +1 @@
+ERROR: Empty supervisor.
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors06_per_event.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors06_per_event.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..20272e5b5b3d5699726d419781b36bcc3b3bf2cc
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors06_per_event.cif.out
@@ -0,0 +1,180 @@
+Reading CIF file "datasynth/edge_granularity_errors06_per_event.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      1 * 2     2 * 2       2 * 2       100%
+  2      discrete variable  int[0..7]  p.x   1      3 * 2     8 * 2       8 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 5
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 10
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [iteration 1]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 2
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..7]  p.x   0      3 * 2     8 * 2       8 * 2       100%
+  2      location pointer   n/a        p     1      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.l2
+Marked    (auts/locs marker predicate):      p.l2
+Marked    (uncontrolled system):             p.l2
+Marked    (system, combined mark/plant inv): p.l2
+Marked    (system, combined mark/state inv): p.l2
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: (p.x = 6 or p.x = 7) and p.l1) (assignments: p.x := p.x + 2, p := p.l2 / p.x := p.x + 1, p := p.l2)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward reachability: iteration 1.
+Controlled behavior: true -> p.l2.
+
+Round 1: finished, no initialization possible.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: p.l2)
+    Edge: (event: e) (guard: (p.x = 6 or p.x = 7) and p.l1) (assignments: p.x := p.x + 2, p := p.l2 / p.x := p.x + 1, p := p.l2)
+
+Controlled system:                     exactly 0 states.
+
+Initial (synthesis result):            p.l2
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           false
+Initial (removed by supervisor):       p.l1
+Initial (added by supervisor):         p.l2
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors07_per_edge.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors07_per_edge.cif
new file mode 100644
index 0000000000000000000000000000000000000000..da1735b9e9f8b7027542e7a02a6b65d8f9178d35
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors07_per_edge.cif
@@ -0,0 +1,28 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..7] x in any;
+
+  location l1:
+    initial;
+
+    // Different guards, different overflow.
+    edge e when x = 4 do x := x + 7 goto l2;
+    edge e when x = 5 do x := x - 7 goto l2;
+
+  location l2:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors07_per_edge.cif.err b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors07_per_edge.cif.err
new file mode 100644
index 0000000000000000000000000000000000000000..95e550ab22fe99975ad9d89b94b2dab14fd7eafd
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors07_per_edge.cif.err
@@ -0,0 +1 @@
+ERROR: Empty supervisor.
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors07_per_edge.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors07_per_edge.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..39d85b6958352c4d153771d20d1a87b78b7ca458
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors07_per_edge.cif.out
@@ -0,0 +1,182 @@
+Reading CIF file "datasynth/edge_granularity_errors07_per_edge.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      1 * 2     2 * 2       2 * 2       100%
+  2      discrete variable  int[0..7]  p.x   1      3 * 2     8 * 2       8 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 5
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 10
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [iteration 1]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 2
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..7]  p.x   0      3 * 2     8 * 2       8 * 2       100%
+  2      location pointer   n/a        p     1      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.l2
+Marked    (auts/locs marker predicate):      p.l2
+Marked    (uncontrolled system):             p.l2
+Marked    (system, combined mark/plant inv): p.l2
+Marked    (system, combined mark/state inv): p.l2
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: p.x = 4 and p.l1) (assignments: p.x := p.x + 7, p := p.l2)
+    Edge: (event: e) (guard: p.x = 5 and p.l1) (assignments: p.x := p.x - 7, p := p.l2)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward reachability: iteration 1.
+Controlled behavior: true -> p.l2.
+
+Round 1: finished, no initialization possible.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: p.l2)
+    Edge: (event: e) (guard: p.x = 4 and p.l1) (assignments: p.x := p.x + 7, p := p.l2)
+    Edge: (event: e) (guard: p.x = 5 and p.l1) (assignments: p.x := p.x - 7, p := p.l2)
+
+Controlled system:                     exactly 0 states.
+
+Initial (synthesis result):            p.l2
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           false
+Initial (removed by supervisor):       p.l1
+Initial (added by supervisor):         p.l2
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors07_per_event.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors07_per_event.cif
new file mode 100644
index 0000000000000000000000000000000000000000..da1735b9e9f8b7027542e7a02a6b65d8f9178d35
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors07_per_event.cif
@@ -0,0 +1,28 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..7] x in any;
+
+  location l1:
+    initial;
+
+    // Different guards, different overflow.
+    edge e when x = 4 do x := x + 7 goto l2;
+    edge e when x = 5 do x := x - 7 goto l2;
+
+  location l2:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors07_per_event.cif.err b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors07_per_event.cif.err
new file mode 100644
index 0000000000000000000000000000000000000000..95e550ab22fe99975ad9d89b94b2dab14fd7eafd
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors07_per_event.cif.err
@@ -0,0 +1 @@
+ERROR: Empty supervisor.
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors07_per_event.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors07_per_event.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..50fbccea59df78213e680813b2fa3ad626be9852
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors07_per_event.cif.out
@@ -0,0 +1,180 @@
+Reading CIF file "datasynth/edge_granularity_errors07_per_event.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      1 * 2     2 * 2       2 * 2       100%
+  2      discrete variable  int[0..7]  p.x   1      3 * 2     8 * 2       8 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 5
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 10
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [iteration 1]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 2
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..7]  p.x   0      3 * 2     8 * 2       8 * 2       100%
+  2      location pointer   n/a        p     1      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.l2
+Marked    (auts/locs marker predicate):      p.l2
+Marked    (uncontrolled system):             p.l2
+Marked    (system, combined mark/plant inv): p.l2
+Marked    (system, combined mark/state inv): p.l2
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: (p.x = 4 or p.x = 5) and p.l1) (assignments: p.x := p.x + 7, p := p.l2 / p.x := p.x - 7, p := p.l2)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward reachability: iteration 1.
+Controlled behavior: true -> p.l2.
+
+Round 1: finished, no initialization possible.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: p.l2)
+    Edge: (event: e) (guard: (p.x = 4 or p.x = 5) and p.l1) (assignments: p.x := p.x + 7, p := p.l2 / p.x := p.x - 7, p := p.l2)
+
+Controlled system:                     exactly 0 states.
+
+Initial (synthesis result):            p.l2
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           false
+Initial (removed by supervisor):       p.l1
+Initial (added by supervisor):         p.l2
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors08_per_edge.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors08_per_edge.cif
new file mode 100644
index 0000000000000000000000000000000000000000..245960198d458550dab93d96e55f51a00e9d2a22
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors08_per_edge.cif
@@ -0,0 +1,28 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..7] x in any;
+
+  location l1:
+    initial;
+
+    // Partially overlapping guards, same update, all overflow.
+    edge e when x = 5 or x = 6 do x := x + 3 goto l2;
+    edge e when x = 6 or x = 7 do x := x + 3 goto l2;
+
+  location l2:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors08_per_edge.cif.err b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors08_per_edge.cif.err
new file mode 100644
index 0000000000000000000000000000000000000000..95e550ab22fe99975ad9d89b94b2dab14fd7eafd
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors08_per_edge.cif.err
@@ -0,0 +1 @@
+ERROR: Empty supervisor.
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors08_per_edge.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors08_per_edge.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..d997c3913920b50b3792a55a9a08e59adac4115f
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors08_per_edge.cif.out
@@ -0,0 +1,182 @@
+Reading CIF file "datasynth/edge_granularity_errors08_per_edge.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      1 * 2     2 * 2       2 * 2       100%
+  2      discrete variable  int[0..7]  p.x   1      3 * 2     8 * 2       8 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 7
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+        Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+        Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 7
+
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 7
+
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 10
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [iteration 1]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 2
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..7]  p.x   0      3 * 2     8 * 2       8 * 2       100%
+  2      location pointer   n/a        p     1      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.l2
+Marked    (auts/locs marker predicate):      p.l2
+Marked    (uncontrolled system):             p.l2
+Marked    (system, combined mark/plant inv): p.l2
+Marked    (system, combined mark/state inv): p.l2
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: p.x = 6 and p.l1 or p.x = 5 and p.l1) (assignments: p.x := p.x + 3, p := p.l2)
+    Edge: (event: e) (guard: (p.x = 6 or p.x = 7) and p.l1) (assignments: p.x := p.x + 3, p := p.l2)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward reachability: iteration 1.
+Controlled behavior: true -> p.l2.
+
+Round 1: finished, no initialization possible.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: p.l2)
+    Edge: (event: e) (guard: p.x = 6 and p.l1 or p.x = 5 and p.l1) (assignments: p.x := p.x + 3, p := p.l2)
+    Edge: (event: e) (guard: (p.x = 6 or p.x = 7) and p.l1) (assignments: p.x := p.x + 3, p := p.l2)
+
+Controlled system:                     exactly 0 states.
+
+Initial (synthesis result):            p.l2
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           false
+Initial (removed by supervisor):       p.l1
+Initial (added by supervisor):         p.l2
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors08_per_event.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors08_per_event.cif
new file mode 100644
index 0000000000000000000000000000000000000000..245960198d458550dab93d96e55f51a00e9d2a22
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors08_per_event.cif
@@ -0,0 +1,28 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..7] x in any;
+
+  location l1:
+    initial;
+
+    // Partially overlapping guards, same update, all overflow.
+    edge e when x = 5 or x = 6 do x := x + 3 goto l2;
+    edge e when x = 6 or x = 7 do x := x + 3 goto l2;
+
+  location l2:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors08_per_event.cif.err b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors08_per_event.cif.err
new file mode 100644
index 0000000000000000000000000000000000000000..95e550ab22fe99975ad9d89b94b2dab14fd7eafd
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors08_per_event.cif.err
@@ -0,0 +1 @@
+ERROR: Empty supervisor.
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors08_per_event.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors08_per_event.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..8691a92197fc62171afdbd9a3e54b905cfdaa616
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors08_per_event.cif.out
@@ -0,0 +1,180 @@
+Reading CIF file "datasynth/edge_granularity_errors08_per_event.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      1 * 2     2 * 2       2 * 2       100%
+  2      discrete variable  int[0..7]  p.x   1      3 * 2     8 * 2       8 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 7
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+        Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+        Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 7
+
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 7
+
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 10
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [iteration 1]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 2
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..7]  p.x   0      3 * 2     8 * 2       8 * 2       100%
+  2      location pointer   n/a        p     1      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.l2
+Marked    (auts/locs marker predicate):      p.l2
+Marked    (uncontrolled system):             p.l2
+Marked    (system, combined mark/plant inv): p.l2
+Marked    (system, combined mark/state inv): p.l2
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: p.x = 6 and p.l1 or (p.x = 5 or p.x = 7) and p.l1) (assignments: p.x := p.x + 3, p := p.l2 / p.x := p.x + 3, p := p.l2)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward reachability: iteration 1.
+Controlled behavior: true -> p.l2.
+
+Round 1: finished, no initialization possible.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: p.l2)
+    Edge: (event: e) (guard: p.x = 6 and p.l1 or (p.x = 5 or p.x = 7) and p.l1) (assignments: p.x := p.x + 3, p := p.l2 / p.x := p.x + 3, p := p.l2)
+
+Controlled system:                     exactly 0 states.
+
+Initial (synthesis result):            p.l2
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           false
+Initial (removed by supervisor):       p.l1
+Initial (added by supervisor):         p.l2
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors09_per_edge.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors09_per_edge.cif
new file mode 100644
index 0000000000000000000000000000000000000000..9ca3cb65958b38f503d4e3cbe8a2c900a4b500bb
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors09_per_edge.cif
@@ -0,0 +1,28 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..7] x in any;
+
+  location l1:
+    initial;
+
+    // Partially overlapping guards, same update, some overflow.
+    edge e when x = 5 or x = 6 do x := x + 2 goto l2;
+    edge e when x = 6 or x = 7 do x := x + 2 goto l2;
+
+  location l2:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors09_per_edge.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors09_per_edge.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..65c2f037681d1f60fbe11fcb218af5f262538c96
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors09_per_edge.cif.out
@@ -0,0 +1,220 @@
+Reading CIF file "datasynth/edge_granularity_errors09_per_edge.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      1 * 2     2 * 2       2 * 2       100%
+  2      discrete variable  int[0..7]  p.x   1      3 * 2     8 * 2       8 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 7
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+        Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+        Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 7
+
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 7
+
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 10
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [iteration 1]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 2
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..7]  p.x   0      3 * 2     8 * 2       8 * 2       100%
+  2      location pointer   n/a        p     1      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.l2
+Marked    (auts/locs marker predicate):      p.l2
+Marked    (uncontrolled system):             p.l2
+Marked    (system, combined mark/plant inv): p.l2
+Marked    (system, combined mark/state inv): p.l2
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: p.x = 6 and p.l1 or p.x = 5 and p.l1) (assignments: p.x := p.x + 2, p := p.l2)
+    Edge: (event: e) (guard: (p.x = 6 or p.x = 7) and p.l1) (assignments: p.x := p.x + 2, p := p.l2)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.l2 -> (p.x = 1 or p.x = 3 or (p.x = 5 or (p.x = 7 or p.l2))) and ((p.x != 1 or p.l2) and (not(p.x = 3 or p.x = 7) or p.l2)) [backward reach with edge: (event: e) (guard: p.x = 6 and p.l1 or p.x = 5 and p.l1) (assignments: p.x := p.x + 2, p := p.l2), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 2.
+Backward controlled-behavior: (p.x = 1 or p.x = 3 or (p.x = 5 or (p.x = 7 or p.l2))) and ((p.x != 1 or p.l2) and (not(p.x = 3 or p.x = 7) or p.l2)) [fixed point].
+Controlled behavior: true -> (p.x = 1 or p.x = 3 or (p.x = 5 or (p.x = 7 or p.l2))) and ((p.x != 1 or p.l2) and (not(p.x = 3 or p.x = 7) or p.l2)).
+
+Round 1: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) and p.l1 or (p.x = 1 and p.l1 or (p.x = 3 or p.x = 7) and p.l1) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 1: computing forward controlled-behavior predicate.
+Forward controlled-behavior: p.l1 [initialization predicate]
+Forward controlled-behavior: p.l1 -> p.x = 5 and p.l1 [restricted to current/previous controlled-behavior predicate: (p.x = 1 or p.x = 3 or (p.x = 5 or (p.x = 7 or p.l2))) and ((p.x != 1 or p.l2) and (not(p.x = 3 or p.x = 7) or p.l2))]
+Forward reachability: iteration 1.
+Forward controlled-behavior: p.x = 5 and p.l1 -> p.x = 5 and p.l1 or p.x = 7 and p.l2 [forward reach with edge: (event: e) (guard: p.x = 6 and p.l1 or p.x = 5 and p.l1) (assignments: p.x := p.x + 2, p := p.l2), restricted to current/previous controlled-behavior predicate: (p.x = 1 or p.x = 3 or (p.x = 5 or (p.x = 7 or p.l2))) and ((p.x != 1 or p.l2) and (not(p.x = 3 or p.x = 7) or p.l2))]
+Forward reachability: iteration 2.
+Forward controlled-behavior: p.x = 5 and p.l1 or p.x = 7 and p.l2 [fixed point].
+Controlled behavior: (p.x = 1 or p.x = 3 or (p.x = 5 or (p.x = 7 or p.l2))) and ((p.x != 1 or p.l2) and (not(p.x = 3 or p.x = 7) or p.l2)) -> p.x = 5 and p.l1 or p.x = 7 and p.l2.
+
+Round 1: finished, need another round.
+
+Round 2: started.
+
+Round 2: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward controlled-behavior: p.l2 -> p.x = 7 and p.l2 [restricted to current/previous controlled-behavior predicate: p.x = 5 and p.l1 or p.x = 7 and p.l2]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.x = 7 and p.l2 -> p.x = 5 and p.l1 or p.x = 7 and p.l2 [backward reach with edge: (event: e) (guard: p.x = 6 and p.l1 or p.x = 5 and p.l1) (assignments: p.x := p.x + 2, p := p.l2), restricted to current/previous controlled-behavior predicate: p.x = 5 and p.l1 or p.x = 7 and p.l2]
+Backward reachability: iteration 2.
+Backward controlled-behavior: p.x = 5 and p.l1 or p.x = 7 and p.l2 [fixed point].
+
+Round 2: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.x != 5 or p.l2) and (p.x != 7 or p.l1) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 2: finished, controlled behavior is stable.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: p.x = 5 and p.l1 or p.x = 7 and p.l2)
+    Edge: (event: e) (guard: p.x = 6 and p.l1 or p.x = 5 and p.l1) (assignments: p.x := p.x + 2, p := p.l2)
+    Edge: (event: e) (guard: (p.x = 6 or p.x = 7) and p.l1) (assignments: p.x := p.x + 2, p := p.l2)
+
+Controlled system:                     exactly 2 states.
+
+Initial (synthesis result):            p.x = 5 and p.l1 or p.x = 7 and p.l2
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           p.x = 5 and p.l1
+Initial (removed by supervisor):       (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) and p.l1 or (p.x = 1 and p.l1 or (p.x = 3 or p.x = 7) and p.l1)
+Initial (added by supervisor):         (p.x = 1 or p.x = 3 or (p.x = 5 or (p.x = 7 or p.l2))) and ((p.x != 1 or p.l2) and (not(p.x = 3 or p.x = 7) or p.l2))
+
+Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
+  Initial: p.x = 5 and p.l1 -> p.x = 5 [assume p.l1].
+
+Constructing output CIF specification.
+Writing output CIF file "datasynth/edge_granularity_errors09_per_edge.ctrlsys.real.cif".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors09_per_edge.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors09_per_edge.ctrlsys.cif
new file mode 100644
index 0000000000000000000000000000000000000000..d263d6eb6c351ed1473813baadb18e02f8153cab
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors09_per_edge.ctrlsys.cif
@@ -0,0 +1,17 @@
+uncontrollable e;
+plant automaton p:
+  disc int[0..7] x in any;
+  location l1:
+    initial;
+    edge e when x = 5 or x = 6 do x := x + 2 goto l2;
+    edge e when x = 6 or x = 7 do x := x + 2 goto l2;
+  location l2:
+    marked;
+end
+supervisor automaton sup:
+  alphabet;
+  initial p.x = 5;
+  location:
+    initial;
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors09_per_edge.statespace.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors09_per_edge.statespace.cif
new file mode 100644
index 0000000000000000000000000000000000000000..ab6b0f55f234a3d137a005a63099d668cd29d997
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors09_per_edge.statespace.cif
@@ -0,0 +1,9 @@
+uncontrollable e;
+automaton statespace:
+  alphabet e;
+  location loc1:
+    initial;
+    edge e goto loc2;
+  location loc2:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors09_per_event.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors09_per_event.cif
new file mode 100644
index 0000000000000000000000000000000000000000..9ca3cb65958b38f503d4e3cbe8a2c900a4b500bb
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors09_per_event.cif
@@ -0,0 +1,28 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..7] x in any;
+
+  location l1:
+    initial;
+
+    // Partially overlapping guards, same update, some overflow.
+    edge e when x = 5 or x = 6 do x := x + 2 goto l2;
+    edge e when x = 6 or x = 7 do x := x + 2 goto l2;
+
+  location l2:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors09_per_event.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors09_per_event.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..9b6b89e81e34f10eb5ae610b7c2e640c86628591
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors09_per_event.cif.out
@@ -0,0 +1,218 @@
+Reading CIF file "datasynth/edge_granularity_errors09_per_event.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      1 * 2     2 * 2       2 * 2       100%
+  2      discrete variable  int[0..7]  p.x   1      3 * 2     8 * 2       8 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 7
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+        Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+        Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 7
+
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 7
+
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 10
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [iteration 1]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 2
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..7]  p.x   0      3 * 2     8 * 2       8 * 2       100%
+  2      location pointer   n/a        p     1      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.l2
+Marked    (auts/locs marker predicate):      p.l2
+Marked    (uncontrolled system):             p.l2
+Marked    (system, combined mark/plant inv): p.l2
+Marked    (system, combined mark/state inv): p.l2
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: p.x = 6 and p.l1 or (p.x = 5 or p.x = 7) and p.l1) (assignments: p.x := p.x + 2, p := p.l2 / p.x := p.x + 2, p := p.l2)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.l2 -> (p.x = 1 or p.x = 3 or (p.x = 5 or (p.x = 7 or p.l2))) and ((p.x != 1 or p.l2) and (not(p.x = 3 or p.x = 7) or p.l2)) [backward reach with edge: (event: e) (guard: p.x = 6 and p.l1 or (p.x = 5 or p.x = 7) and p.l1) (assignments: p.x := p.x + 2, p := p.l2 / p.x := p.x + 2, p := p.l2), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 2.
+Backward controlled-behavior: (p.x = 1 or p.x = 3 or (p.x = 5 or (p.x = 7 or p.l2))) and ((p.x != 1 or p.l2) and (not(p.x = 3 or p.x = 7) or p.l2)) [fixed point].
+Controlled behavior: true -> (p.x = 1 or p.x = 3 or (p.x = 5 or (p.x = 7 or p.l2))) and ((p.x != 1 or p.l2) and (not(p.x = 3 or p.x = 7) or p.l2)).
+
+Round 1: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) and p.l1 or (p.x = 1 and p.l1 or (p.x = 3 or p.x = 7) and p.l1) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 1: computing forward controlled-behavior predicate.
+Forward controlled-behavior: p.l1 [initialization predicate]
+Forward controlled-behavior: p.l1 -> p.x = 5 and p.l1 [restricted to current/previous controlled-behavior predicate: (p.x = 1 or p.x = 3 or (p.x = 5 or (p.x = 7 or p.l2))) and ((p.x != 1 or p.l2) and (not(p.x = 3 or p.x = 7) or p.l2))]
+Forward reachability: iteration 1.
+Forward controlled-behavior: p.x = 5 and p.l1 -> p.x = 5 and p.l1 or p.x = 7 and p.l2 [forward reach with edge: (event: e) (guard: p.x = 6 and p.l1 or (p.x = 5 or p.x = 7) and p.l1) (assignments: p.x := p.x + 2, p := p.l2 / p.x := p.x + 2, p := p.l2), restricted to current/previous controlled-behavior predicate: (p.x = 1 or p.x = 3 or (p.x = 5 or (p.x = 7 or p.l2))) and ((p.x != 1 or p.l2) and (not(p.x = 3 or p.x = 7) or p.l2))]
+Forward reachability: iteration 2.
+Forward controlled-behavior: p.x = 5 and p.l1 or p.x = 7 and p.l2 [fixed point].
+Controlled behavior: (p.x = 1 or p.x = 3 or (p.x = 5 or (p.x = 7 or p.l2))) and ((p.x != 1 or p.l2) and (not(p.x = 3 or p.x = 7) or p.l2)) -> p.x = 5 and p.l1 or p.x = 7 and p.l2.
+
+Round 1: finished, need another round.
+
+Round 2: started.
+
+Round 2: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward controlled-behavior: p.l2 -> p.x = 7 and p.l2 [restricted to current/previous controlled-behavior predicate: p.x = 5 and p.l1 or p.x = 7 and p.l2]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.x = 7 and p.l2 -> p.x = 5 and p.l1 or p.x = 7 and p.l2 [backward reach with edge: (event: e) (guard: p.x = 6 and p.l1 or (p.x = 5 or p.x = 7) and p.l1) (assignments: p.x := p.x + 2, p := p.l2 / p.x := p.x + 2, p := p.l2), restricted to current/previous controlled-behavior predicate: p.x = 5 and p.l1 or p.x = 7 and p.l2]
+Backward reachability: iteration 2.
+Backward controlled-behavior: p.x = 5 and p.l1 or p.x = 7 and p.l2 [fixed point].
+
+Round 2: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.x != 5 or p.l2) and (p.x != 7 or p.l1) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 2: finished, controlled behavior is stable.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: p.x = 5 and p.l1 or p.x = 7 and p.l2)
+    Edge: (event: e) (guard: p.x = 6 and p.l1 or (p.x = 5 or p.x = 7) and p.l1) (assignments: p.x := p.x + 2, p := p.l2 / p.x := p.x + 2, p := p.l2)
+
+Controlled system:                     exactly 2 states.
+
+Initial (synthesis result):            p.x = 5 and p.l1 or p.x = 7 and p.l2
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           p.x = 5 and p.l1
+Initial (removed by supervisor):       (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) and p.l1 or (p.x = 1 and p.l1 or (p.x = 3 or p.x = 7) and p.l1)
+Initial (added by supervisor):         (p.x = 1 or p.x = 3 or (p.x = 5 or (p.x = 7 or p.l2))) and ((p.x != 1 or p.l2) and (not(p.x = 3 or p.x = 7) or p.l2))
+
+Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
+  Initial: p.x = 5 and p.l1 -> p.x = 5 [assume p.l1].
+
+Constructing output CIF specification.
+Writing output CIF file "datasynth/edge_granularity_errors09_per_event.ctrlsys.real.cif".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors09_per_event.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors09_per_event.ctrlsys.cif
new file mode 100644
index 0000000000000000000000000000000000000000..d263d6eb6c351ed1473813baadb18e02f8153cab
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors09_per_event.ctrlsys.cif
@@ -0,0 +1,17 @@
+uncontrollable e;
+plant automaton p:
+  disc int[0..7] x in any;
+  location l1:
+    initial;
+    edge e when x = 5 or x = 6 do x := x + 2 goto l2;
+    edge e when x = 6 or x = 7 do x := x + 2 goto l2;
+  location l2:
+    marked;
+end
+supervisor automaton sup:
+  alphabet;
+  initial p.x = 5;
+  location:
+    initial;
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors09_per_event.statespace.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors09_per_event.statespace.cif
new file mode 100644
index 0000000000000000000000000000000000000000..ab6b0f55f234a3d137a005a63099d668cd29d997
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors09_per_event.statespace.cif
@@ -0,0 +1,9 @@
+uncontrollable e;
+automaton statespace:
+  alphabet e;
+  location loc1:
+    initial;
+    edge e goto loc2;
+  location loc2:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors10_per_edge.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors10_per_edge.cif
new file mode 100644
index 0000000000000000000000000000000000000000..00891a654e51c8b74b49bbcb1992432c2dae1f9e
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors10_per_edge.cif
@@ -0,0 +1,28 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..7] x in any;
+
+  location l1:
+    initial;
+
+    // Partially overlapping guards, different update, all overflow.
+    edge e when x = 5 or x = 6 do x := x + 3 goto l2;
+    edge e when x = 6 or x = 7 do x := x + 4 goto l2;
+
+  location l2:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors10_per_edge.cif.err b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors10_per_edge.cif.err
new file mode 100644
index 0000000000000000000000000000000000000000..95e550ab22fe99975ad9d89b94b2dab14fd7eafd
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors10_per_edge.cif.err
@@ -0,0 +1 @@
+ERROR: Empty supervisor.
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors10_per_edge.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors10_per_edge.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..fe65d4b83859a464ea2edc3be83ba4eae274df02
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors10_per_edge.cif.out
@@ -0,0 +1,182 @@
+Reading CIF file "datasynth/edge_granularity_errors10_per_edge.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      1 * 2     2 * 2       2 * 2       100%
+  2      discrete variable  int[0..7]  p.x   1      3 * 2     8 * 2       8 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 7
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+        Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+        Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 7
+
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 7
+
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 10
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [iteration 1]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 2
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..7]  p.x   0      3 * 2     8 * 2       8 * 2       100%
+  2      location pointer   n/a        p     1      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.l2
+Marked    (auts/locs marker predicate):      p.l2
+Marked    (uncontrolled system):             p.l2
+Marked    (system, combined mark/plant inv): p.l2
+Marked    (system, combined mark/state inv): p.l2
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: p.x = 6 and p.l1 or p.x = 5 and p.l1) (assignments: p.x := p.x + 3, p := p.l2)
+    Edge: (event: e) (guard: (p.x = 6 or p.x = 7) and p.l1) (assignments: p.x := p.x + 4, p := p.l2)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward reachability: iteration 1.
+Controlled behavior: true -> p.l2.
+
+Round 1: finished, no initialization possible.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: p.l2)
+    Edge: (event: e) (guard: p.x = 6 and p.l1 or p.x = 5 and p.l1) (assignments: p.x := p.x + 3, p := p.l2)
+    Edge: (event: e) (guard: (p.x = 6 or p.x = 7) and p.l1) (assignments: p.x := p.x + 4, p := p.l2)
+
+Controlled system:                     exactly 0 states.
+
+Initial (synthesis result):            p.l2
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           false
+Initial (removed by supervisor):       p.l1
+Initial (added by supervisor):         p.l2
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors10_per_event.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors10_per_event.cif
new file mode 100644
index 0000000000000000000000000000000000000000..00891a654e51c8b74b49bbcb1992432c2dae1f9e
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors10_per_event.cif
@@ -0,0 +1,28 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..7] x in any;
+
+  location l1:
+    initial;
+
+    // Partially overlapping guards, different update, all overflow.
+    edge e when x = 5 or x = 6 do x := x + 3 goto l2;
+    edge e when x = 6 or x = 7 do x := x + 4 goto l2;
+
+  location l2:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors10_per_event.cif.err b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors10_per_event.cif.err
new file mode 100644
index 0000000000000000000000000000000000000000..95e550ab22fe99975ad9d89b94b2dab14fd7eafd
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors10_per_event.cif.err
@@ -0,0 +1 @@
+ERROR: Empty supervisor.
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors10_per_event.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors10_per_event.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..05a761b34c343f571224995fc3c5c4959d86064f
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors10_per_event.cif.out
@@ -0,0 +1,180 @@
+Reading CIF file "datasynth/edge_granularity_errors10_per_event.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      1 * 2     2 * 2       2 * 2       100%
+  2      discrete variable  int[0..7]  p.x   1      3 * 2     8 * 2       8 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 7
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+        Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+        Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 7
+
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 7
+
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 10
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [iteration 1]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 2
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..7]  p.x   0      3 * 2     8 * 2       8 * 2       100%
+  2      location pointer   n/a        p     1      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.l2
+Marked    (auts/locs marker predicate):      p.l2
+Marked    (uncontrolled system):             p.l2
+Marked    (system, combined mark/plant inv): p.l2
+Marked    (system, combined mark/state inv): p.l2
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: p.x = 6 and p.l1 or (p.x = 5 or p.x = 7) and p.l1) (assignments: p.x := p.x + 3, p := p.l2 / p.x := p.x + 4, p := p.l2)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward reachability: iteration 1.
+Controlled behavior: true -> p.l2.
+
+Round 1: finished, no initialization possible.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: p.l2)
+    Edge: (event: e) (guard: p.x = 6 and p.l1 or (p.x = 5 or p.x = 7) and p.l1) (assignments: p.x := p.x + 3, p := p.l2 / p.x := p.x + 4, p := p.l2)
+
+Controlled system:                     exactly 0 states.
+
+Initial (synthesis result):            p.l2
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           false
+Initial (removed by supervisor):       p.l1
+Initial (added by supervisor):         p.l2
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors11_per_edge.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors11_per_edge.cif
new file mode 100644
index 0000000000000000000000000000000000000000..b0f43082d4182c10870f84805f3a5935727d3e9b
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors11_per_edge.cif
@@ -0,0 +1,28 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..7] x in any;
+
+  location l1:
+    initial;
+
+    // Partially overlapping guards, different update, some overflow.
+    edge e when x = 5 or x = 6 do x := x + 2 goto l2;
+    edge e when x = 6 or x = 7 do x := x + 3 goto l2;
+
+  location l2:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors11_per_edge.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors11_per_edge.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..f825098d4d70cb0927b731307b0db0d5e4214158
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors11_per_edge.cif.out
@@ -0,0 +1,220 @@
+Reading CIF file "datasynth/edge_granularity_errors11_per_edge.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      1 * 2     2 * 2       2 * 2       100%
+  2      discrete variable  int[0..7]  p.x   1      3 * 2     8 * 2       8 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 7
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+        Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+        Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 7
+
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 7
+
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 10
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [iteration 1]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 2
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..7]  p.x   0      3 * 2     8 * 2       8 * 2       100%
+  2      location pointer   n/a        p     1      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.l2
+Marked    (auts/locs marker predicate):      p.l2
+Marked    (uncontrolled system):             p.l2
+Marked    (system, combined mark/plant inv): p.l2
+Marked    (system, combined mark/state inv): p.l2
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: p.x = 6 and p.l1 or p.x = 5 and p.l1) (assignments: p.x := p.x + 2, p := p.l2)
+    Edge: (event: e) (guard: (p.x = 6 or p.x = 7) and p.l1) (assignments: p.x := p.x + 3, p := p.l2)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.l2 -> (p.x = 1 or p.x = 3 or (p.x = 5 or (p.x = 7 or p.l2))) and ((p.x != 1 or p.l2) and (not(p.x = 3 or p.x = 7) or p.l2)) [backward reach with edge: (event: e) (guard: p.x = 6 and p.l1 or p.x = 5 and p.l1) (assignments: p.x := p.x + 2, p := p.l2), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 2.
+Backward controlled-behavior: (p.x = 1 or p.x = 3 or (p.x = 5 or (p.x = 7 or p.l2))) and ((p.x != 1 or p.l2) and (not(p.x = 3 or p.x = 7) or p.l2)) [fixed point].
+Controlled behavior: true -> (p.x = 1 or p.x = 3 or (p.x = 5 or (p.x = 7 or p.l2))) and ((p.x != 1 or p.l2) and (not(p.x = 3 or p.x = 7) or p.l2)).
+
+Round 1: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) and p.l1 or (p.x = 1 and p.l1 or (p.x = 3 or p.x = 7) and p.l1) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 1: computing forward controlled-behavior predicate.
+Forward controlled-behavior: p.l1 [initialization predicate]
+Forward controlled-behavior: p.l1 -> p.x = 5 and p.l1 [restricted to current/previous controlled-behavior predicate: (p.x = 1 or p.x = 3 or (p.x = 5 or (p.x = 7 or p.l2))) and ((p.x != 1 or p.l2) and (not(p.x = 3 or p.x = 7) or p.l2))]
+Forward reachability: iteration 1.
+Forward controlled-behavior: p.x = 5 and p.l1 -> p.x = 5 and p.l1 or p.x = 7 and p.l2 [forward reach with edge: (event: e) (guard: p.x = 6 and p.l1 or p.x = 5 and p.l1) (assignments: p.x := p.x + 2, p := p.l2), restricted to current/previous controlled-behavior predicate: (p.x = 1 or p.x = 3 or (p.x = 5 or (p.x = 7 or p.l2))) and ((p.x != 1 or p.l2) and (not(p.x = 3 or p.x = 7) or p.l2))]
+Forward reachability: iteration 2.
+Forward controlled-behavior: p.x = 5 and p.l1 or p.x = 7 and p.l2 [fixed point].
+Controlled behavior: (p.x = 1 or p.x = 3 or (p.x = 5 or (p.x = 7 or p.l2))) and ((p.x != 1 or p.l2) and (not(p.x = 3 or p.x = 7) or p.l2)) -> p.x = 5 and p.l1 or p.x = 7 and p.l2.
+
+Round 1: finished, need another round.
+
+Round 2: started.
+
+Round 2: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward controlled-behavior: p.l2 -> p.x = 7 and p.l2 [restricted to current/previous controlled-behavior predicate: p.x = 5 and p.l1 or p.x = 7 and p.l2]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.x = 7 and p.l2 -> p.x = 5 and p.l1 or p.x = 7 and p.l2 [backward reach with edge: (event: e) (guard: p.x = 6 and p.l1 or p.x = 5 and p.l1) (assignments: p.x := p.x + 2, p := p.l2), restricted to current/previous controlled-behavior predicate: p.x = 5 and p.l1 or p.x = 7 and p.l2]
+Backward reachability: iteration 2.
+Backward controlled-behavior: p.x = 5 and p.l1 or p.x = 7 and p.l2 [fixed point].
+
+Round 2: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.x != 5 or p.l2) and (p.x != 7 or p.l1) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 2: finished, controlled behavior is stable.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: p.x = 5 and p.l1 or p.x = 7 and p.l2)
+    Edge: (event: e) (guard: p.x = 6 and p.l1 or p.x = 5 and p.l1) (assignments: p.x := p.x + 2, p := p.l2)
+    Edge: (event: e) (guard: (p.x = 6 or p.x = 7) and p.l1) (assignments: p.x := p.x + 3, p := p.l2)
+
+Controlled system:                     exactly 2 states.
+
+Initial (synthesis result):            p.x = 5 and p.l1 or p.x = 7 and p.l2
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           p.x = 5 and p.l1
+Initial (removed by supervisor):       (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) and p.l1 or (p.x = 1 and p.l1 or (p.x = 3 or p.x = 7) and p.l1)
+Initial (added by supervisor):         (p.x = 1 or p.x = 3 or (p.x = 5 or (p.x = 7 or p.l2))) and ((p.x != 1 or p.l2) and (not(p.x = 3 or p.x = 7) or p.l2))
+
+Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
+  Initial: p.x = 5 and p.l1 -> p.x = 5 [assume p.l1].
+
+Constructing output CIF specification.
+Writing output CIF file "datasynth/edge_granularity_errors11_per_edge.ctrlsys.real.cif".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors11_per_edge.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors11_per_edge.ctrlsys.cif
new file mode 100644
index 0000000000000000000000000000000000000000..48e5c81179a4fa69efe28dd146d8db15960a969c
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors11_per_edge.ctrlsys.cif
@@ -0,0 +1,17 @@
+uncontrollable e;
+plant automaton p:
+  disc int[0..7] x in any;
+  location l1:
+    initial;
+    edge e when x = 5 or x = 6 do x := x + 2 goto l2;
+    edge e when x = 6 or x = 7 do x := x + 3 goto l2;
+  location l2:
+    marked;
+end
+supervisor automaton sup:
+  alphabet;
+  initial p.x = 5;
+  location:
+    initial;
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors11_per_edge.statespace.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors11_per_edge.statespace.cif
new file mode 100644
index 0000000000000000000000000000000000000000..ab6b0f55f234a3d137a005a63099d668cd29d997
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors11_per_edge.statespace.cif
@@ -0,0 +1,9 @@
+uncontrollable e;
+automaton statespace:
+  alphabet e;
+  location loc1:
+    initial;
+    edge e goto loc2;
+  location loc2:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors11_per_event.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors11_per_event.cif
new file mode 100644
index 0000000000000000000000000000000000000000..b0f43082d4182c10870f84805f3a5935727d3e9b
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors11_per_event.cif
@@ -0,0 +1,28 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..7] x in any;
+
+  location l1:
+    initial;
+
+    // Partially overlapping guards, different update, some overflow.
+    edge e when x = 5 or x = 6 do x := x + 2 goto l2;
+    edge e when x = 6 or x = 7 do x := x + 3 goto l2;
+
+  location l2:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors11_per_event.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors11_per_event.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..2e93b21290645f299e3971d35d020b5d2a31cc43
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors11_per_event.cif.out
@@ -0,0 +1,218 @@
+Reading CIF file "datasynth/edge_granularity_errors11_per_event.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      1 * 2     2 * 2       2 * 2       100%
+  2      discrete variable  int[0..7]  p.x   1      3 * 2     8 * 2       8 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 7
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+        Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+        Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 7
+
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 7
+
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [before]
+          Total span:   1 (total)   0.14 (avg/edge) / WES:   0.571429 (total)   0.081633 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 10
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [iteration 1]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 2
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..7]  p.x   0      3 * 2     8 * 2       8 * 2       100%
+  2      location pointer   n/a        p     1      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.l2
+Marked    (auts/locs marker predicate):      p.l2
+Marked    (uncontrolled system):             p.l2
+Marked    (system, combined mark/plant inv): p.l2
+Marked    (system, combined mark/state inv): p.l2
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: p.x = 6 and p.l1 or (p.x = 5 or p.x = 7) and p.l1) (assignments: p.x := p.x + 2, p := p.l2 / p.x := p.x + 3, p := p.l2)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.l2 -> (p.x = 1 or p.x = 3 or (p.x = 5 or (p.x = 7 or p.l2))) and ((p.x != 1 or p.l2) and (not(p.x = 3 or p.x = 7) or p.l2)) [backward reach with edge: (event: e) (guard: p.x = 6 and p.l1 or (p.x = 5 or p.x = 7) and p.l1) (assignments: p.x := p.x + 2, p := p.l2 / p.x := p.x + 3, p := p.l2), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 2.
+Backward controlled-behavior: (p.x = 1 or p.x = 3 or (p.x = 5 or (p.x = 7 or p.l2))) and ((p.x != 1 or p.l2) and (not(p.x = 3 or p.x = 7) or p.l2)) [fixed point].
+Controlled behavior: true -> (p.x = 1 or p.x = 3 or (p.x = 5 or (p.x = 7 or p.l2))) and ((p.x != 1 or p.l2) and (not(p.x = 3 or p.x = 7) or p.l2)).
+
+Round 1: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) and p.l1 or (p.x = 1 and p.l1 or (p.x = 3 or p.x = 7) and p.l1) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 1: computing forward controlled-behavior predicate.
+Forward controlled-behavior: p.l1 [initialization predicate]
+Forward controlled-behavior: p.l1 -> p.x = 5 and p.l1 [restricted to current/previous controlled-behavior predicate: (p.x = 1 or p.x = 3 or (p.x = 5 or (p.x = 7 or p.l2))) and ((p.x != 1 or p.l2) and (not(p.x = 3 or p.x = 7) or p.l2))]
+Forward reachability: iteration 1.
+Forward controlled-behavior: p.x = 5 and p.l1 -> p.x = 5 and p.l1 or p.x = 7 and p.l2 [forward reach with edge: (event: e) (guard: p.x = 6 and p.l1 or (p.x = 5 or p.x = 7) and p.l1) (assignments: p.x := p.x + 2, p := p.l2 / p.x := p.x + 3, p := p.l2), restricted to current/previous controlled-behavior predicate: (p.x = 1 or p.x = 3 or (p.x = 5 or (p.x = 7 or p.l2))) and ((p.x != 1 or p.l2) and (not(p.x = 3 or p.x = 7) or p.l2))]
+Forward reachability: iteration 2.
+Forward controlled-behavior: p.x = 5 and p.l1 or p.x = 7 and p.l2 [fixed point].
+Controlled behavior: (p.x = 1 or p.x = 3 or (p.x = 5 or (p.x = 7 or p.l2))) and ((p.x != 1 or p.l2) and (not(p.x = 3 or p.x = 7) or p.l2)) -> p.x = 5 and p.l1 or p.x = 7 and p.l2.
+
+Round 1: finished, need another round.
+
+Round 2: started.
+
+Round 2: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward controlled-behavior: p.l2 -> p.x = 7 and p.l2 [restricted to current/previous controlled-behavior predicate: p.x = 5 and p.l1 or p.x = 7 and p.l2]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.x = 7 and p.l2 -> p.x = 5 and p.l1 or p.x = 7 and p.l2 [backward reach with edge: (event: e) (guard: p.x = 6 and p.l1 or (p.x = 5 or p.x = 7) and p.l1) (assignments: p.x := p.x + 2, p := p.l2 / p.x := p.x + 3, p := p.l2), restricted to current/previous controlled-behavior predicate: p.x = 5 and p.l1 or p.x = 7 and p.l2]
+Backward reachability: iteration 2.
+Backward controlled-behavior: p.x = 5 and p.l1 or p.x = 7 and p.l2 [fixed point].
+
+Round 2: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.x != 5 or p.l2) and (p.x != 7 or p.l1) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 2: finished, controlled behavior is stable.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: p.x = 5 and p.l1 or p.x = 7 and p.l2)
+    Edge: (event: e) (guard: p.x = 6 and p.l1 or (p.x = 5 or p.x = 7) and p.l1) (assignments: p.x := p.x + 2, p := p.l2 / p.x := p.x + 3, p := p.l2)
+
+Controlled system:                     exactly 2 states.
+
+Initial (synthesis result):            p.x = 5 and p.l1 or p.x = 7 and p.l2
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           p.x = 5 and p.l1
+Initial (removed by supervisor):       (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) and p.l1 or (p.x = 1 and p.l1 or (p.x = 3 or p.x = 7) and p.l1)
+Initial (added by supervisor):         (p.x = 1 or p.x = 3 or (p.x = 5 or (p.x = 7 or p.l2))) and ((p.x != 1 or p.l2) and (not(p.x = 3 or p.x = 7) or p.l2))
+
+Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
+  Initial: p.x = 5 and p.l1 -> p.x = 5 [assume p.l1].
+
+Constructing output CIF specification.
+Writing output CIF file "datasynth/edge_granularity_errors11_per_event.ctrlsys.real.cif".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors11_per_event.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors11_per_event.ctrlsys.cif
new file mode 100644
index 0000000000000000000000000000000000000000..48e5c81179a4fa69efe28dd146d8db15960a969c
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors11_per_event.ctrlsys.cif
@@ -0,0 +1,17 @@
+uncontrollable e;
+plant automaton p:
+  disc int[0..7] x in any;
+  location l1:
+    initial;
+    edge e when x = 5 or x = 6 do x := x + 2 goto l2;
+    edge e when x = 6 or x = 7 do x := x + 3 goto l2;
+  location l2:
+    marked;
+end
+supervisor automaton sup:
+  alphabet;
+  initial p.x = 5;
+  location:
+    initial;
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors11_per_event.statespace.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors11_per_event.statespace.cif
new file mode 100644
index 0000000000000000000000000000000000000000..ab6b0f55f234a3d137a005a63099d668cd29d997
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors11_per_event.statespace.cif
@@ -0,0 +1,9 @@
+uncontrollable e;
+automaton statespace:
+  alphabet e;
+  location loc1:
+    initial;
+    edge e goto loc2;
+  location loc2:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors12_per_edge.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors12_per_edge.cif
new file mode 100644
index 0000000000000000000000000000000000000000..771c4702ff5099776e26db692b45ab564f907d05
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors12_per_edge.cif
@@ -0,0 +1,28 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..7] x in any;
+
+  location l1:
+    initial;
+
+    // Partially overlapping guards, different overflow.
+    edge e when x <= 4 do x := x + 6 goto l2;
+    edge e when x >= 4 do x := x - 6 goto l2;
+
+  location l2:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors12_per_edge.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors12_per_edge.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..f2f3c3091c154ea7d3260060435ec3c5b622a7dc
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors12_per_edge.cif.out
@@ -0,0 +1,223 @@
+Reading CIF file "datasynth/edge_granularity_errors12_per_edge.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      1 * 2     2 * 2       2 * 2       100%
+  2      discrete variable  int[0..7]  p.x   1      3 * 2     8 * 2       8 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 5
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 10
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [iteration 1]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 2
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..7]  p.x   0      3 * 2     8 * 2       8 * 2       100%
+  2      location pointer   n/a        p     1      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.l2
+Marked    (auts/locs marker predicate):      p.l2
+Marked    (uncontrolled system):             p.l2
+Marked    (system, combined mark/plant inv): p.l2
+Marked    (system, combined mark/state inv): p.l2
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: (p.x = 0 or p.x = 4) and p.l1 or (p.x = 2 and p.l1 or (p.x = 1 or p.x = 3) and p.l1)) (assignments: p.x := p.x + 6, p := p.l2)
+    Edge: (event: e) (guard: 4 <= p.x and (p.x <= 7 and p.l1)) (assignments: p.x := p.x - 6, p := p.l2)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.l2 -> (not(p.x = 4 or p.x = 5) or p.l2) and (p.x = 0 or p.x = 1 or (p.x = 4 or (p.x = 5 or p.l2))) [backward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 4) and p.l1 or (p.x = 2 and p.l1 or (p.x = 1 or p.x = 3) and p.l1)) (assignments: p.x := p.x + 6, p := p.l2), restricted to current/previous controlled-behavior predicate: true]
+Backward controlled-behavior: (not(p.x = 4 or p.x = 5) or p.l2) and (p.x = 0 or p.x = 1 or (p.x = 4 or (p.x = 5 or p.l2))) -> (not(p.x = 4 or p.x = 5) or p.l2) and (not(p.x = 2 or p.x = 3) or p.l2) [backward reach with edge: (event: e) (guard: 4 <= p.x and (p.x <= 7 and p.l1)) (assignments: p.x := p.x - 6, p := p.l2), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 2.
+Backward controlled-behavior: (not(p.x = 4 or p.x = 5) or p.l2) and (not(p.x = 2 or p.x = 3) or p.l2) [fixed point].
+Controlled behavior: true -> (not(p.x = 4 or p.x = 5) or p.l2) and (not(p.x = 2 or p.x = 3) or p.l2).
+
+Round 1: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.x = 4 or p.x = 5) and p.l1 or (p.x = 2 or p.x = 3) and p.l1 [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 1: computing forward controlled-behavior predicate.
+Forward controlled-behavior: p.l1 [initialization predicate]
+Forward controlled-behavior: p.l1 -> (p.x = 0 or p.x = 1) and p.l1 or (p.x = 6 or p.x = 7) and p.l1 [restricted to current/previous controlled-behavior predicate: (not(p.x = 4 or p.x = 5) or p.l2) and (not(p.x = 2 or p.x = 3) or p.l2)]
+Forward reachability: iteration 1.
+Forward controlled-behavior: (p.x = 0 or p.x = 1) and p.l1 or (p.x = 6 or p.x = 7) and p.l1 -> (p.x = 0 or p.x = 1) and p.l1 or (p.x = 6 or p.x = 7) [forward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 4) and p.l1 or (p.x = 2 and p.l1 or (p.x = 1 or p.x = 3) and p.l1)) (assignments: p.x := p.x + 6, p := p.l2), restricted to current/previous controlled-behavior predicate: (not(p.x = 4 or p.x = 5) or p.l2) and (not(p.x = 2 or p.x = 3) or p.l2)]
+Forward controlled-behavior: (p.x = 0 or p.x = 1) and p.l1 or (p.x = 6 or p.x = 7) -> p.x = 0 or p.x = 1 or (p.x = 6 or p.x = 7) [forward reach with edge: (event: e) (guard: 4 <= p.x and (p.x <= 7 and p.l1)) (assignments: p.x := p.x - 6, p := p.l2), restricted to current/previous controlled-behavior predicate: (not(p.x = 4 or p.x = 5) or p.l2) and (not(p.x = 2 or p.x = 3) or p.l2)]
+Forward reachability: iteration 2.
+Forward controlled-behavior: p.x = 0 or p.x = 1 or (p.x = 6 or p.x = 7) [fixed point].
+Controlled behavior: (not(p.x = 4 or p.x = 5) or p.l2) and (not(p.x = 2 or p.x = 3) or p.l2) -> p.x = 0 or p.x = 1 or (p.x = 6 or p.x = 7).
+
+Round 1: finished, need another round.
+
+Round 2: started.
+
+Round 2: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward controlled-behavior: p.l2 -> (p.x = 0 or p.x = 1) and p.l2 or (p.x = 6 or p.x = 7) and p.l2 [restricted to current/previous controlled-behavior predicate: p.x = 0 or p.x = 1 or (p.x = 6 or p.x = 7)]
+Backward reachability: iteration 1.
+Backward controlled-behavior: (p.x = 0 or p.x = 1) and p.l2 or (p.x = 6 or p.x = 7) and p.l2 -> p.x = 0 or (p.x = 1 or (p.x = 6 or p.x = 7) and p.l2) [backward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 4) and p.l1 or (p.x = 2 and p.l1 or (p.x = 1 or p.x = 3) and p.l1)) (assignments: p.x := p.x + 6, p := p.l2), restricted to current/previous controlled-behavior predicate: p.x = 0 or p.x = 1 or (p.x = 6 or p.x = 7)]
+Backward controlled-behavior: p.x = 0 or (p.x = 1 or (p.x = 6 or p.x = 7) and p.l2) -> p.x = 0 or p.x = 1 or (p.x = 6 or p.x = 7) [backward reach with edge: (event: e) (guard: 4 <= p.x and (p.x <= 7 and p.l1)) (assignments: p.x := p.x - 6, p := p.l2), restricted to current/previous controlled-behavior predicate: p.x = 0 or p.x = 1 or (p.x = 6 or p.x = 7)]
+Backward reachability: iteration 2.
+Backward controlled-behavior: p.x = 0 or p.x = 1 or (p.x = 6 or p.x = 7) [fixed point].
+
+Round 2: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: 2 <= p.x and p.x <= 7 and (0 <= p.x and p.x <= 5) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 2: finished, controlled behavior is stable.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: p.x = 0 or p.x = 1 or (p.x = 6 or p.x = 7))
+    Edge: (event: e) (guard: (p.x = 0 or p.x = 4) and p.l1 or (p.x = 2 and p.l1 or (p.x = 1 or p.x = 3) and p.l1)) (assignments: p.x := p.x + 6, p := p.l2)
+    Edge: (event: e) (guard: 4 <= p.x and (p.x <= 7 and p.l1)) (assignments: p.x := p.x - 6, p := p.l2)
+
+Controlled system:                     exactly 8 states.
+
+Initial (synthesis result):            p.x = 0 or p.x = 1 or (p.x = 6 or p.x = 7)
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           (p.x = 0 or p.x = 1) and p.l1 or (p.x = 6 or p.x = 7) and p.l1
+Initial (removed by supervisor):       (p.x = 4 or p.x = 5) and p.l1 or (p.x = 2 or p.x = 3) and p.l1
+Initial (added by supervisor):         (not(p.x = 4 or p.x = 5) or p.l2) and (not(p.x = 2 or p.x = 3) or p.l2)
+
+Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
+  Initial: (p.x = 0 or p.x = 1) and p.l1 or (p.x = 6 or p.x = 7) and p.l1 -> p.x = 0 or p.x = 1 or (p.x = 6 or p.x = 7) [assume p.l1].
+
+Constructing output CIF specification.
+Writing output CIF file "datasynth/edge_granularity_errors12_per_edge.ctrlsys.real.cif".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors12_per_edge.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors12_per_edge.ctrlsys.cif
new file mode 100644
index 0000000000000000000000000000000000000000..fbd16372c852a0d09221e5080d528735a8e15f90
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors12_per_edge.ctrlsys.cif
@@ -0,0 +1,17 @@
+uncontrollable e;
+plant automaton p:
+  disc int[0..7] x in any;
+  location l1:
+    initial;
+    edge e when x <= 4 do x := x + 6 goto l2;
+    edge e when x >= 4 do x := x - 6 goto l2;
+  location l2:
+    marked;
+end
+supervisor automaton sup:
+  alphabet;
+  initial p.x = 0 or p.x = 1 or (p.x = 6 or p.x = 7);
+  location:
+    initial;
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors12_per_edge.statespace.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors12_per_edge.statespace.cif
new file mode 100644
index 0000000000000000000000000000000000000000..c47f3ace5f6335718ffb018fbcbb63e248d2ca19
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors12_per_edge.statespace.cif
@@ -0,0 +1,24 @@
+uncontrollable e;
+automaton statespace:
+  alphabet e;
+  location loc1:
+    initial;
+    edge e goto loc5;
+  location loc2:
+    initial;
+    edge e goto loc6;
+  location loc3:
+    initial;
+    edge e goto loc7;
+  location loc4:
+    initial;
+    edge e goto loc8;
+  location loc5:
+    marked;
+  location loc6:
+    marked;
+  location loc7:
+    marked;
+  location loc8:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors12_per_event.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors12_per_event.cif
new file mode 100644
index 0000000000000000000000000000000000000000..771c4702ff5099776e26db692b45ab564f907d05
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors12_per_event.cif
@@ -0,0 +1,28 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..7] x in any;
+
+  location l1:
+    initial;
+
+    // Partially overlapping guards, different overflow.
+    edge e when x <= 4 do x := x + 6 goto l2;
+    edge e when x >= 4 do x := x - 6 goto l2;
+
+  location l2:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors12_per_event.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors12_per_event.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..9e8f351d2fad79149b0a9c742ccccb287f80ea3d
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors12_per_event.cif.out
@@ -0,0 +1,218 @@
+Reading CIF file "datasynth/edge_granularity_errors12_per_event.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      1 * 2     2 * 2       2 * 2       100%
+  2      discrete variable  int[0..7]  p.x   1      3 * 2     8 * 2       8 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 5
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+        Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [before]
+          Total span:   1 (total)   0.20 (avg/edge) / WES:   0.600000 (total)   0.120000 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 10
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [iteration 1]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 2
+
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [before]
+      Total span:   2 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.500000 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..7]  p.x   0      3 * 2     8 * 2       8 * 2       100%
+  2      location pointer   n/a        p     1      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.l2
+Marked    (auts/locs marker predicate):      p.l2
+Marked    (uncontrolled system):             p.l2
+Marked    (system, combined mark/plant inv): p.l2
+Marked    (system, combined mark/state inv): p.l2
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 6, p := p.l2 / p.x := p.x - 6, p := p.l2)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.l2 -> (not(p.x = 4 or p.x = 5) or p.l2) and (not(p.x = 2 or p.x = 3) or p.l2) [backward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 6, p := p.l2 / p.x := p.x - 6, p := p.l2), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 2.
+Backward controlled-behavior: (not(p.x = 4 or p.x = 5) or p.l2) and (not(p.x = 2 or p.x = 3) or p.l2) [fixed point].
+Controlled behavior: true -> (not(p.x = 4 or p.x = 5) or p.l2) and (not(p.x = 2 or p.x = 3) or p.l2).
+
+Round 1: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.x = 4 or p.x = 5) and p.l1 or (p.x = 2 or p.x = 3) and p.l1 [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 1: computing forward controlled-behavior predicate.
+Forward controlled-behavior: p.l1 [initialization predicate]
+Forward controlled-behavior: p.l1 -> (p.x = 0 or p.x = 1) and p.l1 or (p.x = 6 or p.x = 7) and p.l1 [restricted to current/previous controlled-behavior predicate: (not(p.x = 4 or p.x = 5) or p.l2) and (not(p.x = 2 or p.x = 3) or p.l2)]
+Forward reachability: iteration 1.
+Forward controlled-behavior: (p.x = 0 or p.x = 1) and p.l1 or (p.x = 6 or p.x = 7) and p.l1 -> p.x = 0 or p.x = 1 or (p.x = 6 or p.x = 7) [forward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 6, p := p.l2 / p.x := p.x - 6, p := p.l2), restricted to current/previous controlled-behavior predicate: (not(p.x = 4 or p.x = 5) or p.l2) and (not(p.x = 2 or p.x = 3) or p.l2)]
+Forward reachability: iteration 2.
+Forward controlled-behavior: p.x = 0 or p.x = 1 or (p.x = 6 or p.x = 7) [fixed point].
+Controlled behavior: (not(p.x = 4 or p.x = 5) or p.l2) and (not(p.x = 2 or p.x = 3) or p.l2) -> p.x = 0 or p.x = 1 or (p.x = 6 or p.x = 7).
+
+Round 1: finished, need another round.
+
+Round 2: started.
+
+Round 2: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward controlled-behavior: p.l2 -> (p.x = 0 or p.x = 1) and p.l2 or (p.x = 6 or p.x = 7) and p.l2 [restricted to current/previous controlled-behavior predicate: p.x = 0 or p.x = 1 or (p.x = 6 or p.x = 7)]
+Backward reachability: iteration 1.
+Backward controlled-behavior: (p.x = 0 or p.x = 1) and p.l2 or (p.x = 6 or p.x = 7) and p.l2 -> p.x = 0 or p.x = 1 or (p.x = 6 or p.x = 7) [backward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 6, p := p.l2 / p.x := p.x - 6, p := p.l2), restricted to current/previous controlled-behavior predicate: p.x = 0 or p.x = 1 or (p.x = 6 or p.x = 7)]
+Backward reachability: iteration 2.
+Backward controlled-behavior: p.x = 0 or p.x = 1 or (p.x = 6 or p.x = 7) [fixed point].
+
+Round 2: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: 2 <= p.x and p.x <= 7 and (0 <= p.x and p.x <= 5) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 2: finished, controlled behavior is stable.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: p.x = 0 or p.x = 1 or (p.x = 6 or p.x = 7))
+    Edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + 6, p := p.l2 / p.x := p.x - 6, p := p.l2)
+
+Controlled system:                     exactly 8 states.
+
+Initial (synthesis result):            p.x = 0 or p.x = 1 or (p.x = 6 or p.x = 7)
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           (p.x = 0 or p.x = 1) and p.l1 or (p.x = 6 or p.x = 7) and p.l1
+Initial (removed by supervisor):       (p.x = 4 or p.x = 5) and p.l1 or (p.x = 2 or p.x = 3) and p.l1
+Initial (added by supervisor):         (not(p.x = 4 or p.x = 5) or p.l2) and (not(p.x = 2 or p.x = 3) or p.l2)
+
+Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
+  Initial: (p.x = 0 or p.x = 1) and p.l1 or (p.x = 6 or p.x = 7) and p.l1 -> p.x = 0 or p.x = 1 or (p.x = 6 or p.x = 7) [assume p.l1].
+
+Constructing output CIF specification.
+Writing output CIF file "datasynth/edge_granularity_errors12_per_event.ctrlsys.real.cif".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors12_per_event.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors12_per_event.ctrlsys.cif
new file mode 100644
index 0000000000000000000000000000000000000000..fbd16372c852a0d09221e5080d528735a8e15f90
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors12_per_event.ctrlsys.cif
@@ -0,0 +1,17 @@
+uncontrollable e;
+plant automaton p:
+  disc int[0..7] x in any;
+  location l1:
+    initial;
+    edge e when x <= 4 do x := x + 6 goto l2;
+    edge e when x >= 4 do x := x - 6 goto l2;
+  location l2:
+    marked;
+end
+supervisor automaton sup:
+  alphabet;
+  initial p.x = 0 or p.x = 1 or (p.x = 6 or p.x = 7);
+  location:
+    initial;
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors12_per_event.statespace.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors12_per_event.statespace.cif
new file mode 100644
index 0000000000000000000000000000000000000000..c47f3ace5f6335718ffb018fbcbb63e248d2ca19
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors12_per_event.statespace.cif
@@ -0,0 +1,24 @@
+uncontrollable e;
+automaton statespace:
+  alphabet e;
+  location loc1:
+    initial;
+    edge e goto loc5;
+  location loc2:
+    initial;
+    edge e goto loc6;
+  location loc3:
+    initial;
+    edge e goto loc7;
+  location loc4:
+    initial;
+    edge e goto loc8;
+  location loc5:
+    marked;
+  location loc6:
+    marked;
+  location loc7:
+    marked;
+  location loc8:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors13_per_edge.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors13_per_edge.cif
new file mode 100644
index 0000000000000000000000000000000000000000..398524a34c252da5f733bc4fb02d1088fc1c62cc
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors13_per_edge.cif
@@ -0,0 +1,29 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..7] x in any;
+
+  location l1:
+    initial;
+
+    // Different summation errors.
+    edge e do x := x + x         goto l2;
+    edge e do x := x + x + x     goto l2;
+    edge e do x := x + x + x + x goto l2;
+
+  location l2:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors13_per_edge.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors13_per_edge.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..91ca0e1f8136d6a4da4d5a23be0697d0affad8b6
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors13_per_edge.cif.out
@@ -0,0 +1,229 @@
+Reading CIF file "datasynth/edge_granularity_errors13_per_edge.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      1 * 2     2 * 2       2 * 2       100%
+  2      discrete variable  int[0..7]  p.x   1      3 * 2     8 * 2       8 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 4
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.25 (avg/edge) / WES:   0.625000 (total)   0.156250 (avg/edge) [before]
+        Total span:   1 (total)   0.25 (avg/edge) / WES:   0.625000 (total)   0.156250 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.25 (avg/edge) / WES:   0.625000 (total)   0.156250 (avg/edge) [before]
+        Total span:   1 (total)   0.25 (avg/edge) / WES:   0.625000 (total)   0.156250 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.25 (avg/edge) / WES:   0.625000 (total)   0.156250 (avg/edge) [before]
+          Total span:   1 (total)   0.25 (avg/edge) / WES:   0.625000 (total)   0.156250 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 4
+
+          Total span:   1 (total)   0.25 (avg/edge) / WES:   0.625000 (total)   0.156250 (avg/edge) [before]
+          Total span:   1 (total)   0.25 (avg/edge) / WES:   0.625000 (total)   0.156250 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.25 (avg/edge) / WES:   0.625000 (total)   0.156250 (avg/edge) [before]
+          Total span:   1 (total)   0.25 (avg/edge) / WES:   0.625000 (total)   0.156250 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 4
+
+          Total span:   1 (total)   0.25 (avg/edge) / WES:   0.625000 (total)   0.156250 (avg/edge) [before]
+          Total span:   1 (total)   0.25 (avg/edge) / WES:   0.625000 (total)   0.156250 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 3
+      Maximum number of iterations: 10
+
+      Total span:   3 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.333333 (avg/edge) [before]
+      Total span:   3 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.333333 (avg/edge) [iteration 1]
+      Total span:   3 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.333333 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 3
+      Window length: 2
+
+      Total span:   3 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.333333 (avg/edge) [before]
+      Total span:   3 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.333333 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..7]  p.x   0      3 * 2     8 * 2       8 * 2       100%
+  2      location pointer   n/a        p     1      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.l2
+Marked    (auts/locs marker predicate):      p.l2
+Marked    (uncontrolled system):             p.l2
+Marked    (system, combined mark/plant inv): p.l2
+Marked    (system, combined mark/state inv): p.l2
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + p.x, p := p.l2)
+    Edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + p.x + p.x, p := p.l2)
+    Edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + p.x + p.x + p.x, p := p.l2)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.l2 -> 0 <= p.x and p.x <= 3 or p.l2 [backward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + p.x, p := p.l2), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 2.
+Backward controlled-behavior: 0 <= p.x and p.x <= 3 or p.l2 [fixed point].
+Controlled behavior: true -> 0 <= p.x and p.x <= 3 or p.l2.
+
+Round 1: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: 4 <= p.x and (p.x <= 7 and p.l1) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+Backward uncontrolled bad-state: 4 <= p.x and (p.x <= 7 and p.l1) -> (p.x = 4 or p.x = 6) and p.l1 or (p.x = 5 and p.l1 or (p.x = 3 or p.x = 7) and p.l1) [backward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + p.x + p.x, p := p.l2)]
+Backward uncontrolled bad-state: (p.x = 4 or p.x = 6) and p.l1 or (p.x = 5 and p.l1 or (p.x = 3 or p.x = 7) and p.l1) -> (p.x = 4 or p.x = 5) and p.l1 or (p.x = 2 or p.x = 3 or (p.x = 6 or p.x = 7)) and p.l1 [backward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + p.x + p.x + p.x, p := p.l2)]
+Backward reachability: iteration 2.
+Backward uncontrolled bad-state: (p.x = 4 or p.x = 5) and p.l1 or (p.x = 2 or p.x = 3 or (p.x = 6 or p.x = 7)) and p.l1 [fixed point].
+Controlled behavior: 0 <= p.x and p.x <= 3 or p.l2 -> (not(p.x = 4 or p.x = 5) or p.l2) and (p.x = 0 or p.x = 1 or (p.x = 4 or (p.x = 5 or p.l2))).
+
+Round 1: computing forward controlled-behavior predicate.
+Forward controlled-behavior: p.l1 [initialization predicate]
+Forward controlled-behavior: p.l1 -> (p.x = 0 or p.x = 1) and p.l1 [restricted to current/previous controlled-behavior predicate: (not(p.x = 4 or p.x = 5) or p.l2) and (p.x = 0 or p.x = 1 or (p.x = 4 or (p.x = 5 or p.l2)))]
+Forward reachability: iteration 1.
+Forward controlled-behavior: (p.x = 0 or p.x = 1) and p.l1 -> p.x = 0 or (p.x = 2 and p.l2 or p.x = 1 and p.l1) [forward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + p.x, p := p.l2), restricted to current/previous controlled-behavior predicate: (not(p.x = 4 or p.x = 5) or p.l2) and (p.x = 0 or p.x = 1 or (p.x = 4 or (p.x = 5 or p.l2)))]
+Forward controlled-behavior: p.x = 0 or (p.x = 2 and p.l2 or p.x = 1 and p.l1) -> p.x = 0 or p.x = 2 and p.l2 or (p.x = 1 and p.l1 or p.x = 3 and p.l2) [forward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + p.x + p.x, p := p.l2), restricted to current/previous controlled-behavior predicate: (not(p.x = 4 or p.x = 5) or p.l2) and (p.x = 0 or p.x = 1 or (p.x = 4 or (p.x = 5 or p.l2)))]
+Forward controlled-behavior: p.x = 0 or p.x = 2 and p.l2 or (p.x = 1 and p.l1 or p.x = 3 and p.l2) -> p.x = 0 or p.x = 4 and p.l2 or (p.x = 2 and p.l2 or (p.x = 1 and p.l1 or p.x = 3 and p.l2)) [forward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + p.x + p.x + p.x, p := p.l2), restricted to current/previous controlled-behavior predicate: (not(p.x = 4 or p.x = 5) or p.l2) and (p.x = 0 or p.x = 1 or (p.x = 4 or (p.x = 5 or p.l2)))]
+Forward reachability: iteration 2.
+Forward controlled-behavior: p.x = 0 or p.x = 4 and p.l2 or (p.x = 2 and p.l2 or (p.x = 1 and p.l1 or p.x = 3 and p.l2)) [fixed point].
+Controlled behavior: (not(p.x = 4 or p.x = 5) or p.l2) and (p.x = 0 or p.x = 1 or (p.x = 4 or (p.x = 5 or p.l2))) -> p.x = 0 or p.x = 4 and p.l2 or (p.x = 2 and p.l2 or (p.x = 1 and p.l1 or p.x = 3 and p.l2)).
+
+Round 1: finished, need another round.
+
+Round 2: started.
+
+Round 2: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward controlled-behavior: p.l2 -> (p.x = 0 or p.x = 4) and p.l2 or (p.x = 2 and p.l2 or p.x = 3 and p.l2) [restricted to current/previous controlled-behavior predicate: p.x = 0 or p.x = 4 and p.l2 or (p.x = 2 and p.l2 or (p.x = 1 and p.l1 or p.x = 3 and p.l2))]
+Backward reachability: iteration 1.
+Backward controlled-behavior: (p.x = 0 or p.x = 4) and p.l2 or (p.x = 2 and p.l2 or p.x = 3 and p.l2) -> p.x = 0 or p.x = 4 and p.l2 or (p.x = 2 and p.l2 or (p.x = 1 and p.l1 or p.x = 3 and p.l2)) [backward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + p.x, p := p.l2), restricted to current/previous controlled-behavior predicate: p.x = 0 or p.x = 4 and p.l2 or (p.x = 2 and p.l2 or (p.x = 1 and p.l1 or p.x = 3 and p.l2))]
+Backward reachability: iteration 2.
+Backward controlled-behavior: p.x = 0 or p.x = 4 and p.l2 or (p.x = 2 and p.l2 or (p.x = 1 and p.l1 or p.x = 3 and p.l2)) [fixed point].
+
+Round 2: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: p.x != 0 and (p.x != 4 or p.l1) and ((p.x != 2 or p.l1) and ((p.x != 1 or p.l2) and (p.x != 3 or p.l1))) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 2: finished, controlled behavior is stable.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: p.x = 0 or p.x = 4 and p.l2 or (p.x = 2 and p.l2 or (p.x = 1 and p.l1 or p.x = 3 and p.l2)))
+    Edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + p.x, p := p.l2)
+    Edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + p.x + p.x, p := p.l2)
+    Edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + p.x + p.x + p.x, p := p.l2)
+
+Controlled system:                     exactly 6 states.
+
+Initial (synthesis result):            p.x = 0 or p.x = 4 and p.l2 or (p.x = 2 and p.l2 or (p.x = 1 and p.l1 or p.x = 3 and p.l2))
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           (p.x = 0 or p.x = 1) and p.l1
+Initial (removed by supervisor):       (p.x = 4 or p.x = 5) and p.l1 or (p.x = 2 or p.x = 3 or (p.x = 6 or p.x = 7)) and p.l1
+Initial (added by supervisor):         (not(p.x = 4 or p.x = 5) or p.l2) and (p.x = 0 or p.x = 1 or (p.x = 4 or (p.x = 5 or p.l2)))
+
+Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
+  Initial: (p.x = 0 or p.x = 1) and p.l1 -> p.x = 0 or p.x = 1 [assume p.l1].
+
+Constructing output CIF specification.
+Writing output CIF file "datasynth/edge_granularity_errors13_per_edge.ctrlsys.real.cif".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors13_per_edge.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors13_per_edge.ctrlsys.cif
new file mode 100644
index 0000000000000000000000000000000000000000..0bf8aaaf8038e31169fbc26d9017a2fa10dde0c4
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors13_per_edge.ctrlsys.cif
@@ -0,0 +1,18 @@
+uncontrollable e;
+plant automaton p:
+  disc int[0..7] x in any;
+  location l1:
+    initial;
+    edge e do x := x + x goto l2;
+    edge e do x := x + x + x goto l2;
+    edge e do x := x + x + x + x goto l2;
+  location l2:
+    marked;
+end
+supervisor automaton sup:
+  alphabet;
+  initial p.x = 0 or p.x = 1;
+  location:
+    initial;
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors13_per_edge.statespace.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors13_per_edge.statespace.cif
new file mode 100644
index 0000000000000000000000000000000000000000..2d86ab3861052003998a603a34caf2b335298725
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors13_per_edge.statespace.cif
@@ -0,0 +1,20 @@
+uncontrollable e;
+automaton statespace:
+  alphabet e;
+  location loc1:
+    initial;
+    edge e goto loc3;
+  location loc2:
+    initial;
+    edge e goto loc4;
+    edge e goto loc5;
+    edge e goto loc6;
+  location loc3:
+    marked;
+  location loc4:
+    marked;
+  location loc5:
+    marked;
+  location loc6:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors13_per_event.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors13_per_event.cif
new file mode 100644
index 0000000000000000000000000000000000000000..398524a34c252da5f733bc4fb02d1088fc1c62cc
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors13_per_event.cif
@@ -0,0 +1,29 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..7] x in any;
+
+  location l1:
+    initial;
+
+    // Different summation errors.
+    edge e do x := x + x         goto l2;
+    edge e do x := x + x + x     goto l2;
+    edge e do x := x + x + x + x goto l2;
+
+  location l2:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors13_per_event.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors13_per_event.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..8e4b7bf9c50af4767edafcfb7380401af7f39308
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors13_per_event.cif.out
@@ -0,0 +1,218 @@
+Reading CIF file "datasynth/edge_granularity_errors13_per_event.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      1 * 2     2 * 2       2 * 2       100%
+  2      discrete variable  int[0..7]  p.x   1      3 * 2     8 * 2       8 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 4
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.25 (avg/edge) / WES:   0.625000 (total)   0.156250 (avg/edge) [before]
+        Total span:   1 (total)   0.25 (avg/edge) / WES:   0.625000 (total)   0.156250 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 1
+
+        Total span:   1 (total)   0.25 (avg/edge) / WES:   0.625000 (total)   0.156250 (avg/edge) [before]
+        Total span:   1 (total)   0.25 (avg/edge) / WES:   0.625000 (total)   0.156250 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.25 (avg/edge) / WES:   0.625000 (total)   0.156250 (avg/edge) [before]
+          Total span:   1 (total)   0.25 (avg/edge) / WES:   0.625000 (total)   0.156250 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 4
+
+          Total span:   1 (total)   0.25 (avg/edge) / WES:   0.625000 (total)   0.156250 (avg/edge) [before]
+          Total span:   1 (total)   0.25 (avg/edge) / WES:   0.625000 (total)   0.156250 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 1
+
+          Total span:   1 (total)   0.25 (avg/edge) / WES:   0.625000 (total)   0.156250 (avg/edge) [before]
+          Total span:   1 (total)   0.25 (avg/edge) / WES:   0.625000 (total)   0.156250 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 4
+
+          Total span:   1 (total)   0.25 (avg/edge) / WES:   0.625000 (total)   0.156250 (avg/edge) [before]
+          Total span:   1 (total)   0.25 (avg/edge) / WES:   0.625000 (total)   0.156250 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 3
+      Maximum number of iterations: 10
+
+      Total span:   3 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.333333 (avg/edge) [before]
+      Total span:   3 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.333333 (avg/edge) [iteration 1]
+      Total span:   3 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.333333 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 3
+      Window length: 2
+
+      Total span:   3 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.333333 (avg/edge) [before]
+      Total span:   3 (total)   1.00 (avg/edge) / WES:   1.000000 (total)   0.333333 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..7]  p.x   0      3 * 2     8 * 2       8 * 2       100%
+  2      location pointer   n/a        p     1      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      2      8         20          20          100%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.l2
+Marked    (auts/locs marker predicate):      p.l2
+Marked    (uncontrolled system):             p.l2
+Marked    (system, combined mark/plant inv): p.l2
+Marked    (system, combined mark/state inv): p.l2
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + p.x, p := p.l2 / p.x := p.x + p.x + p.x, p := p.l2 / p.x := p.x + p.x + p.x + p.x, p := p.l2)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.l2 -> (not(p.x = 4 or p.x = 5) or p.l2) and (p.x = 0 or p.x = 1 or (p.x = 4 or (p.x = 5 or p.l2))) [backward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + p.x, p := p.l2 / p.x := p.x + p.x + p.x, p := p.l2 / p.x := p.x + p.x + p.x + p.x, p := p.l2), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 2.
+Backward controlled-behavior: (not(p.x = 4 or p.x = 5) or p.l2) and (p.x = 0 or p.x = 1 or (p.x = 4 or (p.x = 5 or p.l2))) [fixed point].
+Controlled behavior: true -> (not(p.x = 4 or p.x = 5) or p.l2) and (p.x = 0 or p.x = 1 or (p.x = 4 or (p.x = 5 or p.l2))).
+
+Round 1: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.x = 4 or p.x = 5) and p.l1 or (p.x = 2 or p.x = 3 or (p.x = 6 or p.x = 7)) and p.l1 [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 1: computing forward controlled-behavior predicate.
+Forward controlled-behavior: p.l1 [initialization predicate]
+Forward controlled-behavior: p.l1 -> (p.x = 0 or p.x = 1) and p.l1 [restricted to current/previous controlled-behavior predicate: (not(p.x = 4 or p.x = 5) or p.l2) and (p.x = 0 or p.x = 1 or (p.x = 4 or (p.x = 5 or p.l2)))]
+Forward reachability: iteration 1.
+Forward controlled-behavior: (p.x = 0 or p.x = 1) and p.l1 -> p.x = 0 or p.x = 4 and p.l2 or (p.x = 2 and p.l2 or (p.x = 1 and p.l1 or p.x = 3 and p.l2)) [forward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + p.x, p := p.l2 / p.x := p.x + p.x + p.x, p := p.l2 / p.x := p.x + p.x + p.x + p.x, p := p.l2), restricted to current/previous controlled-behavior predicate: (not(p.x = 4 or p.x = 5) or p.l2) and (p.x = 0 or p.x = 1 or (p.x = 4 or (p.x = 5 or p.l2)))]
+Forward reachability: iteration 2.
+Forward controlled-behavior: p.x = 0 or p.x = 4 and p.l2 or (p.x = 2 and p.l2 or (p.x = 1 and p.l1 or p.x = 3 and p.l2)) [fixed point].
+Controlled behavior: (not(p.x = 4 or p.x = 5) or p.l2) and (p.x = 0 or p.x = 1 or (p.x = 4 or (p.x = 5 or p.l2))) -> p.x = 0 or p.x = 4 and p.l2 or (p.x = 2 and p.l2 or (p.x = 1 and p.l1 or p.x = 3 and p.l2)).
+
+Round 1: finished, need another round.
+
+Round 2: started.
+
+Round 2: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.l2 [marker predicate]
+Backward controlled-behavior: p.l2 -> (p.x = 0 or p.x = 4) and p.l2 or (p.x = 2 and p.l2 or p.x = 3 and p.l2) [restricted to current/previous controlled-behavior predicate: p.x = 0 or p.x = 4 and p.l2 or (p.x = 2 and p.l2 or (p.x = 1 and p.l1 or p.x = 3 and p.l2))]
+Backward reachability: iteration 1.
+Backward controlled-behavior: (p.x = 0 or p.x = 4) and p.l2 or (p.x = 2 and p.l2 or p.x = 3 and p.l2) -> p.x = 0 or p.x = 4 and p.l2 or (p.x = 2 and p.l2 or (p.x = 1 and p.l1 or p.x = 3 and p.l2)) [backward reach with edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + p.x, p := p.l2 / p.x := p.x + p.x + p.x, p := p.l2 / p.x := p.x + p.x + p.x + p.x, p := p.l2), restricted to current/previous controlled-behavior predicate: p.x = 0 or p.x = 4 and p.l2 or (p.x = 2 and p.l2 or (p.x = 1 and p.l1 or p.x = 3 and p.l2))]
+Backward reachability: iteration 2.
+Backward controlled-behavior: p.x = 0 or p.x = 4 and p.l2 or (p.x = 2 and p.l2 or (p.x = 1 and p.l1 or p.x = 3 and p.l2)) [fixed point].
+
+Round 2: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: p.x != 0 and (p.x != 4 or p.l1) and ((p.x != 2 or p.l1) and ((p.x != 1 or p.l2) and (p.x != 3 or p.l1))) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 2: finished, controlled behavior is stable.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: p.x = 0 or p.x = 4 and p.l2 or (p.x = 2 and p.l2 or (p.x = 1 and p.l1 or p.x = 3 and p.l2)))
+    Edge: (event: e) (guard: p.l1) (assignments: p.x := p.x + p.x, p := p.l2 / p.x := p.x + p.x + p.x, p := p.l2 / p.x := p.x + p.x + p.x + p.x, p := p.l2)
+
+Controlled system:                     exactly 6 states.
+
+Initial (synthesis result):            p.x = 0 or p.x = 4 and p.l2 or (p.x = 2 and p.l2 or (p.x = 1 and p.l1 or p.x = 3 and p.l2))
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           (p.x = 0 or p.x = 1) and p.l1
+Initial (removed by supervisor):       (p.x = 4 or p.x = 5) and p.l1 or (p.x = 2 or p.x = 3 or (p.x = 6 or p.x = 7)) and p.l1
+Initial (added by supervisor):         (not(p.x = 4 or p.x = 5) or p.l2) and (p.x = 0 or p.x = 1 or (p.x = 4 or (p.x = 5 or p.l2)))
+
+Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
+  Initial: (p.x = 0 or p.x = 1) and p.l1 -> p.x = 0 or p.x = 1 [assume p.l1].
+
+Constructing output CIF specification.
+Writing output CIF file "datasynth/edge_granularity_errors13_per_event.ctrlsys.real.cif".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors13_per_event.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors13_per_event.ctrlsys.cif
new file mode 100644
index 0000000000000000000000000000000000000000..0bf8aaaf8038e31169fbc26d9017a2fa10dde0c4
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors13_per_event.ctrlsys.cif
@@ -0,0 +1,18 @@
+uncontrollable e;
+plant automaton p:
+  disc int[0..7] x in any;
+  location l1:
+    initial;
+    edge e do x := x + x goto l2;
+    edge e do x := x + x + x goto l2;
+    edge e do x := x + x + x + x goto l2;
+  location l2:
+    marked;
+end
+supervisor automaton sup:
+  alphabet;
+  initial p.x = 0 or p.x = 1;
+  location:
+    initial;
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors13_per_event.statespace.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors13_per_event.statespace.cif
new file mode 100644
index 0000000000000000000000000000000000000000..2d86ab3861052003998a603a34caf2b335298725
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_errors13_per_event.statespace.cif
@@ -0,0 +1,20 @@
+uncontrollable e;
+automaton statespace:
+  alphabet e;
+  location loc1:
+    initial;
+    edge e goto loc3;
+  location loc2:
+    initial;
+    edge e goto loc4;
+    edge e goto loc5;
+    edge e goto loc6;
+  location loc3:
+    marked;
+  location loc4:
+    marked;
+  location loc5:
+    marked;
+  location loc6:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates1_per_edge.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates1_per_edge.cif
new file mode 100644
index 0000000000000000000000000000000000000000..c9c888912c8c421ded05d92fc81cbded5500374b
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates1_per_edge.cif
@@ -0,0 +1,29 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..3] x in any;
+  disc int[0..3] y in any;
+
+  location l1: // x = 0, y in any
+    initial;
+
+    // Same guards, same updates.
+    edge e when x = 0 do y := 2 goto y2;
+    edge e when x = 0 do y := 2 goto y2;
+
+  location y2: // x = 0, y = 2
+    marked y = 2;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates1_per_edge.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates1_per_edge.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..a54ac1692dcfb65278a5cd115c52c49beec52ee6
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates1_per_edge.cif.out
@@ -0,0 +1,223 @@
+Reading CIF file "datasynth/edge_granularity_guards_updates1_per_edge.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      1 * 2     2 * 2       2 * 2       100%
+  2      discrete variable  int[0..3]  p.x   1      2 * 2     4 * 2       4 * 2       100%
+  3      discrete variable  int[0..3]  p.y   2      2 * 2     4 * 2       4 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      3      10        20          20          100%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 5
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 3
+
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 3
+
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 3
+
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 3
+
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 20
+
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [before]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [iteration 1]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 3
+
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [before]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..3]  p.y   0      2 * 2     4 * 2       4 * 2       100%
+  2      discrete variable  int[0..3]  p.x   1      2 * 2     4 * 2       4 * 2       100%
+  3      location pointer   n/a        p     2      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      3      10        20          20          100%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variable 1):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.y = 2 and p.y2
+Marked    (auts/locs marker predicate):      p.y = 2 and p.y2
+Marked    (uncontrolled system):             p.y = 2 and p.y2
+Marked    (system, combined mark/plant inv): p.y = 2 and p.y2
+Marked    (system, combined mark/state inv): p.y = 2 and p.y2
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2)
+    Edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.y = 2 and p.y2 [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.y = 2 and p.y2 -> p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and p.x = 0 or (p.y = 2 and (p.x = 2 and p.y2) or (p.y = 2 and ((p.x = 1 or p.x = 3) and p.y2) or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1))) [backward reach with edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 2.
+Backward controlled-behavior: p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and p.x = 0 or (p.y = 2 and (p.x = 2 and p.y2) or (p.y = 2 and ((p.x = 1 or p.x = 3) and p.y2) or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1))) [fixed point].
+Controlled behavior: true -> p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and p.x = 0 or (p.y = 2 and (p.x = 2 and p.y2) or (p.y = 2 and ((p.x = 1 or p.x = 3) and p.y2) or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1))).
+
+Round 1: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.y != 0 or (p.x != 0 or p.y2)) and (p.y != 2 or p.x != 0) and ((p.y != 2 or (p.x != 2 or p.l1)) and ((p.y != 2 or p.x = 0 or (p.x = 2 or p.l1)) and (p.y = 0 or p.y = 2 or (p.x != 0 or p.y2)))) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 1: computing forward controlled-behavior predicate.
+Forward controlled-behavior: p.l1 [initialization predicate]
+Forward controlled-behavior: p.l1 -> p.x = 0 and p.l1 [restricted to current/previous controlled-behavior predicate: p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and p.x = 0 or (p.y = 2 and (p.x = 2 and p.y2) or (p.y = 2 and ((p.x = 1 or p.x = 3) and p.y2) or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1)))]
+Forward reachability: iteration 1.
+Forward controlled-behavior: p.x = 0 and p.l1 -> p.y = 0 and (p.x = 0 and p.l1) or (p.y = 2 and p.x = 0 or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1)) [forward reach with edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2), restricted to current/previous controlled-behavior predicate: p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and p.x = 0 or (p.y = 2 and (p.x = 2 and p.y2) or (p.y = 2 and ((p.x = 1 or p.x = 3) and p.y2) or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1)))]
+Forward reachability: iteration 2.
+Forward controlled-behavior: p.y = 0 and (p.x = 0 and p.l1) or (p.y = 2 and p.x = 0 or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1)) [fixed point].
+Controlled behavior: p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and p.x = 0 or (p.y = 2 and (p.x = 2 and p.y2) or (p.y = 2 and ((p.x = 1 or p.x = 3) and p.y2) or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1))) -> p.y = 0 and (p.x = 0 and p.l1) or (p.y = 2 and p.x = 0 or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1)).
+
+Round 1: finished, need another round.
+
+Round 2: started.
+
+Round 2: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.y = 2 and p.y2 [marker predicate]
+Backward controlled-behavior: p.y = 2 and p.y2 -> p.y = 2 and (p.x = 0 and p.y2) [restricted to current/previous controlled-behavior predicate: p.y = 0 and (p.x = 0 and p.l1) or (p.y = 2 and p.x = 0 or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1))]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.y = 2 and (p.x = 0 and p.y2) -> p.y = 0 and (p.x = 0 and p.l1) or (p.y = 2 and p.x = 0 or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1)) [backward reach with edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2), restricted to current/previous controlled-behavior predicate: p.y = 0 and (p.x = 0 and p.l1) or (p.y = 2 and p.x = 0 or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1))]
+Backward reachability: iteration 2.
+Backward controlled-behavior: p.y = 0 and (p.x = 0 and p.l1) or (p.y = 2 and p.x = 0 or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1)) [fixed point].
+
+Round 2: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.y != 0 or (p.x != 0 or p.y2)) and ((p.y != 2 or p.x != 0) and (p.y = 0 or p.y = 2 or (p.x != 0 or p.y2))) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 2: finished, controlled behavior is stable.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: p.y = 0 and (p.x = 0 and p.l1) or (p.y = 2 and p.x = 0 or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1)))
+    Edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2)
+    Edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2)
+
+Controlled system:                     exactly 5 states.
+
+Initial (synthesis result):            p.y = 0 and (p.x = 0 and p.l1) or (p.y = 2 and p.x = 0 or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1))
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           p.x = 0 and p.l1
+Initial (removed by supervisor):       p.x = 2 and p.l1 or (p.x = 1 or p.x = 3) and p.l1
+Initial (added by supervisor):         (p.x != 2 or p.y2) and (p.x = 0 or (p.x = 2 or p.y2))
+
+Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
+  Initial: p.x = 0 and p.l1 -> p.x = 0 [assume p.l1].
+
+Constructing output CIF specification.
+Writing output CIF file "datasynth/edge_granularity_guards_updates1_per_edge.ctrlsys.real.cif".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates1_per_edge.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates1_per_edge.ctrlsys.cif
new file mode 100644
index 0000000000000000000000000000000000000000..054c15e4d6d00dbeeea8ad7018c1f4c20fb0b344
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates1_per_edge.ctrlsys.cif
@@ -0,0 +1,18 @@
+uncontrollable e;
+plant automaton p:
+  disc int[0..3] x in any;
+  disc int[0..3] y in any;
+  location l1:
+    initial;
+    edge e when x = 0 do y := 2 goto y2;
+    edge e when x = 0 do y := 2 goto y2;
+  location y2:
+    marked y = 2;
+end
+supervisor automaton sup:
+  alphabet;
+  initial p.x = 0;
+  location:
+    initial;
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates1_per_edge.statespace.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates1_per_edge.statespace.cif
new file mode 100644
index 0000000000000000000000000000000000000000..503fffb5f374aa8f549610596a3c11d04114f86a
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates1_per_edge.statespace.cif
@@ -0,0 +1,18 @@
+uncontrollable e;
+automaton statespace:
+  alphabet e;
+  location loc1:
+    initial;
+    edge e goto loc5;
+  location loc2:
+    initial;
+    edge e goto loc5;
+  location loc3:
+    initial;
+    edge e goto loc5;
+  location loc4:
+    initial;
+    edge e goto loc5;
+  location loc5:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates1_per_event.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates1_per_event.cif
new file mode 100644
index 0000000000000000000000000000000000000000..c9c888912c8c421ded05d92fc81cbded5500374b
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates1_per_event.cif
@@ -0,0 +1,29 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..3] x in any;
+  disc int[0..3] y in any;
+
+  location l1: // x = 0, y in any
+    initial;
+
+    // Same guards, same updates.
+    edge e when x = 0 do y := 2 goto y2;
+    edge e when x = 0 do y := 2 goto y2;
+
+  location y2: // x = 0, y = 2
+    marked y = 2;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates1_per_event.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates1_per_event.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..e7c237d31724acab2696981b4b901497d079f4a5
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates1_per_event.cif.out
@@ -0,0 +1,221 @@
+Reading CIF file "datasynth/edge_granularity_guards_updates1_per_event.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      1 * 2     2 * 2       2 * 2       100%
+  2      discrete variable  int[0..3]  p.x   1      2 * 2     4 * 2       4 * 2       100%
+  3      discrete variable  int[0..3]  p.y   2      2 * 2     4 * 2       4 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      3      10        20          20          100%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 5
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 3
+
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 3
+
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 3
+
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 3
+
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 20
+
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [before]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [iteration 1]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 3
+
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [before]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..3]  p.y   0      2 * 2     4 * 2       4 * 2       100%
+  2      discrete variable  int[0..3]  p.x   1      2 * 2     4 * 2       4 * 2       100%
+  3      location pointer   n/a        p     2      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      3      10        20          20          100%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variable 1):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.y = 2 and p.y2
+Marked    (auts/locs marker predicate):      p.y = 2 and p.y2
+Marked    (uncontrolled system):             p.y = 2 and p.y2
+Marked    (system, combined mark/plant inv): p.y = 2 and p.y2
+Marked    (system, combined mark/state inv): p.y = 2 and p.y2
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2 / p.y := 2, p := p.y2)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.y = 2 and p.y2 [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.y = 2 and p.y2 -> p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and p.x = 0 or (p.y = 2 and (p.x = 2 and p.y2) or (p.y = 2 and ((p.x = 1 or p.x = 3) and p.y2) or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1))) [backward reach with edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2 / p.y := 2, p := p.y2), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 2.
+Backward controlled-behavior: p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and p.x = 0 or (p.y = 2 and (p.x = 2 and p.y2) or (p.y = 2 and ((p.x = 1 or p.x = 3) and p.y2) or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1))) [fixed point].
+Controlled behavior: true -> p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and p.x = 0 or (p.y = 2 and (p.x = 2 and p.y2) or (p.y = 2 and ((p.x = 1 or p.x = 3) and p.y2) or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1))).
+
+Round 1: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.y != 0 or (p.x != 0 or p.y2)) and (p.y != 2 or p.x != 0) and ((p.y != 2 or (p.x != 2 or p.l1)) and ((p.y != 2 or p.x = 0 or (p.x = 2 or p.l1)) and (p.y = 0 or p.y = 2 or (p.x != 0 or p.y2)))) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 1: computing forward controlled-behavior predicate.
+Forward controlled-behavior: p.l1 [initialization predicate]
+Forward controlled-behavior: p.l1 -> p.x = 0 and p.l1 [restricted to current/previous controlled-behavior predicate: p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and p.x = 0 or (p.y = 2 and (p.x = 2 and p.y2) or (p.y = 2 and ((p.x = 1 or p.x = 3) and p.y2) or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1)))]
+Forward reachability: iteration 1.
+Forward controlled-behavior: p.x = 0 and p.l1 -> p.y = 0 and (p.x = 0 and p.l1) or (p.y = 2 and p.x = 0 or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1)) [forward reach with edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2 / p.y := 2, p := p.y2), restricted to current/previous controlled-behavior predicate: p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and p.x = 0 or (p.y = 2 and (p.x = 2 and p.y2) or (p.y = 2 and ((p.x = 1 or p.x = 3) and p.y2) or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1)))]
+Forward reachability: iteration 2.
+Forward controlled-behavior: p.y = 0 and (p.x = 0 and p.l1) or (p.y = 2 and p.x = 0 or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1)) [fixed point].
+Controlled behavior: p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and p.x = 0 or (p.y = 2 and (p.x = 2 and p.y2) or (p.y = 2 and ((p.x = 1 or p.x = 3) and p.y2) or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1))) -> p.y = 0 and (p.x = 0 and p.l1) or (p.y = 2 and p.x = 0 or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1)).
+
+Round 1: finished, need another round.
+
+Round 2: started.
+
+Round 2: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.y = 2 and p.y2 [marker predicate]
+Backward controlled-behavior: p.y = 2 and p.y2 -> p.y = 2 and (p.x = 0 and p.y2) [restricted to current/previous controlled-behavior predicate: p.y = 0 and (p.x = 0 and p.l1) or (p.y = 2 and p.x = 0 or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1))]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.y = 2 and (p.x = 0 and p.y2) -> p.y = 0 and (p.x = 0 and p.l1) or (p.y = 2 and p.x = 0 or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1)) [backward reach with edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2 / p.y := 2, p := p.y2), restricted to current/previous controlled-behavior predicate: p.y = 0 and (p.x = 0 and p.l1) or (p.y = 2 and p.x = 0 or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1))]
+Backward reachability: iteration 2.
+Backward controlled-behavior: p.y = 0 and (p.x = 0 and p.l1) or (p.y = 2 and p.x = 0 or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1)) [fixed point].
+
+Round 2: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.y != 0 or (p.x != 0 or p.y2)) and ((p.y != 2 or p.x != 0) and (p.y = 0 or p.y = 2 or (p.x != 0 or p.y2))) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 2: finished, controlled behavior is stable.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: p.y = 0 and (p.x = 0 and p.l1) or (p.y = 2 and p.x = 0 or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1)))
+    Edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2 / p.y := 2, p := p.y2)
+
+Controlled system:                     exactly 5 states.
+
+Initial (synthesis result):            p.y = 0 and (p.x = 0 and p.l1) or (p.y = 2 and p.x = 0 or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1))
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           p.x = 0 and p.l1
+Initial (removed by supervisor):       p.x = 2 and p.l1 or (p.x = 1 or p.x = 3) and p.l1
+Initial (added by supervisor):         (p.x != 2 or p.y2) and (p.x = 0 or (p.x = 2 or p.y2))
+
+Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
+  Initial: p.x = 0 and p.l1 -> p.x = 0 [assume p.l1].
+
+Constructing output CIF specification.
+Writing output CIF file "datasynth/edge_granularity_guards_updates1_per_event.ctrlsys.real.cif".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates1_per_event.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates1_per_event.ctrlsys.cif
new file mode 100644
index 0000000000000000000000000000000000000000..054c15e4d6d00dbeeea8ad7018c1f4c20fb0b344
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates1_per_event.ctrlsys.cif
@@ -0,0 +1,18 @@
+uncontrollable e;
+plant automaton p:
+  disc int[0..3] x in any;
+  disc int[0..3] y in any;
+  location l1:
+    initial;
+    edge e when x = 0 do y := 2 goto y2;
+    edge e when x = 0 do y := 2 goto y2;
+  location y2:
+    marked y = 2;
+end
+supervisor automaton sup:
+  alphabet;
+  initial p.x = 0;
+  location:
+    initial;
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates1_per_event.statespace.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates1_per_event.statespace.cif
new file mode 100644
index 0000000000000000000000000000000000000000..503fffb5f374aa8f549610596a3c11d04114f86a
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates1_per_event.statespace.cif
@@ -0,0 +1,18 @@
+uncontrollable e;
+automaton statespace:
+  alphabet e;
+  location loc1:
+    initial;
+    edge e goto loc5;
+  location loc2:
+    initial;
+    edge e goto loc5;
+  location loc3:
+    initial;
+    edge e goto loc5;
+  location loc4:
+    initial;
+    edge e goto loc5;
+  location loc5:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates2_per_edge.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates2_per_edge.cif
new file mode 100644
index 0000000000000000000000000000000000000000..d502d9ee67d8b9a46a1871bdcf710f7a7f4d1165
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates2_per_edge.cif
@@ -0,0 +1,32 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..3] x in any;
+  disc int[0..3] y in any;
+
+  location l1: // x = 0, y in any
+    initial;
+
+    // Same guards, different updates.
+    edge e when x = 0 do y := 2 goto y2;
+    edge e when x = 0 do y := 3 goto y3;
+
+  location y2: // x = 0, y = 2
+    marked y = 2;
+
+  location y3: // x = 0, y = 3
+    marked y = 3;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates2_per_edge.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates2_per_edge.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..71599260a7ba537f54f52bc1d8ba61858e390007
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates2_per_edge.cif.out
@@ -0,0 +1,228 @@
+Reading CIF file "datasynth/edge_granularity_guards_updates2_per_edge.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      2 * 2     3 * 2       4 * 2       75%
+  2      discrete variable  int[0..3]  p.x   1      2 * 2     4 * 2       4 * 2       100%
+  3      discrete variable  int[0..3]  p.y   2      2 * 2     4 * 2       4 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      3      12        22          24          ~92%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 5
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 3
+
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 3
+
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 3
+
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 3
+
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 20
+
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [before]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [iteration 1]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 3
+
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [before]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..3]  p.y   0      2 * 2     4 * 2       4 * 2       100%
+  2      discrete variable  int[0..3]  p.x   1      2 * 2     4 * 2       4 * 2       100%
+  3      location pointer   n/a        p     2      2 * 2     3 * 2       4 * 2       75%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      3      12        22          24          ~92%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variable 1):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.y = 2 and p.y2 or p.y = 3 and p.y3
+Marked    (auts/locs marker predicate):      p.y = 2 and p.y2 or p.y = 3 and p.y3
+Marked    (uncontrolled system):             p.y = 2 and p.y2 or p.y = 3 and p.y3
+Marked    (system, combined mark/plant inv): p.y = 2 and p.y2 or p.y = 3 and p.y3
+Marked    (system, combined mark/state inv): p.y = 2 and p.y2 or p.y = 3 and p.y3
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2)
+    Edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 3, p := p.y3)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Controlled behavior: true -> true [range: true, variable: location pointer for automaton "p" (group: 2, domain: 4+5, BDD variables: 2, CIF/BDD values: 3/4)].
+
+Extended controlled-behavior predicate using variable ranges: true.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.y = 2 and p.y2 or p.y = 3 and p.y3 [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.y = 2 and p.y2 or p.y = 3 and p.y3 -> p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 2 and (p.x = 2 and p.y2) or p.y = 2 and ((p.x = 1 or p.x = 3) and p.y2)) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2) or (p.y = 3 and (p.x = 2 and p.y3) or p.y = 3 and ((p.x = 1 or p.x = 3) and p.y3))) [backward reach with edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 2.
+Backward controlled-behavior: p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 2 and (p.x = 2 and p.y2) or p.y = 2 and ((p.x = 1 or p.x = 3) and p.y2)) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2) or (p.y = 3 and (p.x = 2 and p.y3) or p.y = 3 and ((p.x = 1 or p.x = 3) and p.y3))) [fixed point].
+Controlled behavior: true -> p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 2 and (p.x = 2 and p.y2) or p.y = 2 and ((p.x = 1 or p.x = 3) and p.y2)) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2) or (p.y = 3 and (p.x = 2 and p.y3) or p.y = 3 and ((p.x = 1 or p.x = 3) and p.y3))).
+
+Round 1: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.y != 0 or (p.x != 0 or not p.l1)) and (p.y != 2 or (p.x != 0 or p.y3)) and ((p.y != 2 or (p.x != 2 or not p.y2)) and (p.y != 2 or p.x = 0 or (p.x = 2 or not p.y2))) and ((p.y != 1 or (p.x != 0 or not p.l1)) and (p.y != 3 or (p.x != 0 or p.y2)) and ((p.y != 3 or (p.x != 2 or not p.y3)) and (p.y != 3 or p.x = 0 or (p.x = 2 or not p.y3)))) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 1: computing forward controlled-behavior predicate.
+Forward controlled-behavior: p.l1 [initialization predicate]
+Forward controlled-behavior: p.l1 -> p.x = 0 and p.l1 [restricted to current/previous controlled-behavior predicate: p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 2 and (p.x = 2 and p.y2) or p.y = 2 and ((p.x = 1 or p.x = 3) and p.y2)) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2) or (p.y = 3 and (p.x = 2 and p.y3) or p.y = 3 and ((p.x = 1 or p.x = 3) and p.y3)))]
+Forward reachability: iteration 1.
+Forward controlled-behavior: p.x = 0 and p.l1 -> p.y = 0 and (p.x = 0 and p.l1) or (p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1)) [forward reach with edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2), restricted to current/previous controlled-behavior predicate: p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 2 and (p.x = 2 and p.y2) or p.y = 2 and ((p.x = 1 or p.x = 3) and p.y2)) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2) or (p.y = 3 and (p.x = 2 and p.y3) or p.y = 3 and ((p.x = 1 or p.x = 3) and p.y3)))]
+Forward controlled-behavior: p.y = 0 and (p.x = 0 and p.l1) or (p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1)) -> p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2)) [forward reach with edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 2 and (p.x = 2 and p.y2) or p.y = 2 and ((p.x = 1 or p.x = 3) and p.y2)) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2) or (p.y = 3 and (p.x = 2 and p.y3) or p.y = 3 and ((p.x = 1 or p.x = 3) and p.y3)))]
+Forward reachability: iteration 2.
+Forward controlled-behavior: p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2)) [fixed point].
+Controlled behavior: p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 2 and (p.x = 2 and p.y2) or p.y = 2 and ((p.x = 1 or p.x = 3) and p.y2)) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2) or (p.y = 3 and (p.x = 2 and p.y3) or p.y = 3 and ((p.x = 1 or p.x = 3) and p.y3))) -> p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2)).
+
+Round 1: finished, need another round.
+
+Round 2: started.
+
+Round 2: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.y = 2 and p.y2 or p.y = 3 and p.y3 [marker predicate]
+Backward controlled-behavior: p.y = 2 and p.y2 or p.y = 3 and p.y3 -> p.y = 2 and (p.x = 0 and p.y2) or p.y = 3 and (p.x = 0 and p.y3) [restricted to current/previous controlled-behavior predicate: p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2))]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.y = 2 and (p.x = 0 and p.y2) or p.y = 3 and (p.x = 0 and p.y3) -> p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2)) [backward reach with edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2), restricted to current/previous controlled-behavior predicate: p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2))]
+Backward reachability: iteration 2.
+Backward controlled-behavior: p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2)) [fixed point].
+
+Round 2: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.y != 0 or (p.x != 0 or not p.l1)) and (p.y != 2 or (p.x != 0 or p.y3)) and ((p.y != 1 or (p.x != 0 or not p.l1)) and (p.y != 3 or (p.x != 0 or p.y2))) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 2: finished, controlled behavior is stable.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2)))
+    Edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2)
+    Edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 3, p := p.y3)
+
+Controlled system:                     exactly 6 states.
+
+Initial (synthesis result):            p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2))
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           p.x = 0 and p.l1
+Initial (removed by supervisor):       p.x = 2 and p.l1 or (p.x = 1 or p.x = 3) and p.l1
+Initial (added by supervisor):         (p.x != 2 or not p.l1) and (p.x = 0 or (p.x = 2 or not p.l1))
+
+Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
+  Initial: p.x = 0 and p.l1 -> p.x = 0 [assume p.l1].
+
+Constructing output CIF specification.
+Writing output CIF file "datasynth/edge_granularity_guards_updates2_per_edge.ctrlsys.real.cif".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates2_per_edge.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates2_per_edge.ctrlsys.cif
new file mode 100644
index 0000000000000000000000000000000000000000..b864c268b42b8b269e04b2e4ddc610825260dca3
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates2_per_edge.ctrlsys.cif
@@ -0,0 +1,20 @@
+uncontrollable e;
+plant automaton p:
+  disc int[0..3] x in any;
+  disc int[0..3] y in any;
+  location l1:
+    initial;
+    edge e when x = 0 do y := 2 goto y2;
+    edge e when x = 0 do y := 3 goto y3;
+  location y2:
+    marked y = 2;
+  location y3:
+    marked y = 3;
+end
+supervisor automaton sup:
+  alphabet;
+  initial p.x = 0;
+  location:
+    initial;
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates2_per_edge.statespace.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates2_per_edge.statespace.cif
new file mode 100644
index 0000000000000000000000000000000000000000..b5dea70e6adbc4fdac3ca464f1475c566de7cfd9
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates2_per_edge.statespace.cif
@@ -0,0 +1,24 @@
+uncontrollable e;
+automaton statespace:
+  alphabet e;
+  location loc1:
+    initial;
+    edge e goto loc5;
+    edge e goto loc6;
+  location loc2:
+    initial;
+    edge e goto loc5;
+    edge e goto loc6;
+  location loc3:
+    initial;
+    edge e goto loc5;
+    edge e goto loc6;
+  location loc4:
+    initial;
+    edge e goto loc5;
+    edge e goto loc6;
+  location loc5:
+    marked;
+  location loc6:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates2_per_event.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates2_per_event.cif
new file mode 100644
index 0000000000000000000000000000000000000000..d502d9ee67d8b9a46a1871bdcf710f7a7f4d1165
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates2_per_event.cif
@@ -0,0 +1,32 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..3] x in any;
+  disc int[0..3] y in any;
+
+  location l1: // x = 0, y in any
+    initial;
+
+    // Same guards, different updates.
+    edge e when x = 0 do y := 2 goto y2;
+    edge e when x = 0 do y := 3 goto y3;
+
+  location y2: // x = 0, y = 2
+    marked y = 2;
+
+  location y3: // x = 0, y = 3
+    marked y = 3;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates2_per_event.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates2_per_event.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..95d1b0b6b486d302bbf1017cdb716e86c6cf9724
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates2_per_event.cif.out
@@ -0,0 +1,225 @@
+Reading CIF file "datasynth/edge_granularity_guards_updates2_per_event.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      2 * 2     3 * 2       4 * 2       75%
+  2      discrete variable  int[0..3]  p.x   1      2 * 2     4 * 2       4 * 2       100%
+  3      discrete variable  int[0..3]  p.y   2      2 * 2     4 * 2       4 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      3      12        22          24          ~92%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 5
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 3
+
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 3
+
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 3
+
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 3
+
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 20
+
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [before]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [iteration 1]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 3
+
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [before]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..3]  p.y   0      2 * 2     4 * 2       4 * 2       100%
+  2      discrete variable  int[0..3]  p.x   1      2 * 2     4 * 2       4 * 2       100%
+  3      location pointer   n/a        p     2      2 * 2     3 * 2       4 * 2       75%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      3      12        22          24          ~92%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variable 1):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.y = 2 and p.y2 or p.y = 3 and p.y3
+Marked    (auts/locs marker predicate):      p.y = 2 and p.y2 or p.y = 3 and p.y3
+Marked    (uncontrolled system):             p.y = 2 and p.y2 or p.y = 3 and p.y3
+Marked    (system, combined mark/plant inv): p.y = 2 and p.y2 or p.y = 3 and p.y3
+Marked    (system, combined mark/state inv): p.y = 2 and p.y2 or p.y = 3 and p.y3
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2 / p.y := 3, p := p.y3)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Controlled behavior: true -> true [range: true, variable: location pointer for automaton "p" (group: 2, domain: 4+5, BDD variables: 2, CIF/BDD values: 3/4)].
+
+Extended controlled-behavior predicate using variable ranges: true.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.y = 2 and p.y2 or p.y = 3 and p.y3 [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.y = 2 and p.y2 or p.y = 3 and p.y3 -> p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 2 and (p.x = 2 and p.y2) or p.y = 2 and ((p.x = 1 or p.x = 3) and p.y2)) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2) or (p.y = 3 and (p.x = 2 and p.y3) or p.y = 3 and ((p.x = 1 or p.x = 3) and p.y3))) [backward reach with edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2 / p.y := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 2.
+Backward controlled-behavior: p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 2 and (p.x = 2 and p.y2) or p.y = 2 and ((p.x = 1 or p.x = 3) and p.y2)) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2) or (p.y = 3 and (p.x = 2 and p.y3) or p.y = 3 and ((p.x = 1 or p.x = 3) and p.y3))) [fixed point].
+Controlled behavior: true -> p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 2 and (p.x = 2 and p.y2) or p.y = 2 and ((p.x = 1 or p.x = 3) and p.y2)) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2) or (p.y = 3 and (p.x = 2 and p.y3) or p.y = 3 and ((p.x = 1 or p.x = 3) and p.y3))).
+
+Round 1: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.y != 0 or (p.x != 0 or not p.l1)) and (p.y != 2 or (p.x != 0 or p.y3)) and ((p.y != 2 or (p.x != 2 or not p.y2)) and (p.y != 2 or p.x = 0 or (p.x = 2 or not p.y2))) and ((p.y != 1 or (p.x != 0 or not p.l1)) and (p.y != 3 or (p.x != 0 or p.y2)) and ((p.y != 3 or (p.x != 2 or not p.y3)) and (p.y != 3 or p.x = 0 or (p.x = 2 or not p.y3)))) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 1: computing forward controlled-behavior predicate.
+Forward controlled-behavior: p.l1 [initialization predicate]
+Forward controlled-behavior: p.l1 -> p.x = 0 and p.l1 [restricted to current/previous controlled-behavior predicate: p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 2 and (p.x = 2 and p.y2) or p.y = 2 and ((p.x = 1 or p.x = 3) and p.y2)) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2) or (p.y = 3 and (p.x = 2 and p.y3) or p.y = 3 and ((p.x = 1 or p.x = 3) and p.y3)))]
+Forward reachability: iteration 1.
+Forward controlled-behavior: p.x = 0 and p.l1 -> p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2)) [forward reach with edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2 / p.y := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 2 and (p.x = 2 and p.y2) or p.y = 2 and ((p.x = 1 or p.x = 3) and p.y2)) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2) or (p.y = 3 and (p.x = 2 and p.y3) or p.y = 3 and ((p.x = 1 or p.x = 3) and p.y3)))]
+Forward reachability: iteration 2.
+Forward controlled-behavior: p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2)) [fixed point].
+Controlled behavior: p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 2 and (p.x = 2 and p.y2) or p.y = 2 and ((p.x = 1 or p.x = 3) and p.y2)) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2) or (p.y = 3 and (p.x = 2 and p.y3) or p.y = 3 and ((p.x = 1 or p.x = 3) and p.y3))) -> p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2)).
+
+Round 1: finished, need another round.
+
+Round 2: started.
+
+Round 2: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.y = 2 and p.y2 or p.y = 3 and p.y3 [marker predicate]
+Backward controlled-behavior: p.y = 2 and p.y2 or p.y = 3 and p.y3 -> p.y = 2 and (p.x = 0 and p.y2) or p.y = 3 and (p.x = 0 and p.y3) [restricted to current/previous controlled-behavior predicate: p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2))]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.y = 2 and (p.x = 0 and p.y2) or p.y = 3 and (p.x = 0 and p.y3) -> p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2)) [backward reach with edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2 / p.y := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2))]
+Backward reachability: iteration 2.
+Backward controlled-behavior: p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2)) [fixed point].
+
+Round 2: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.y != 0 or (p.x != 0 or not p.l1)) and (p.y != 2 or (p.x != 0 or p.y3)) and ((p.y != 1 or (p.x != 0 or not p.l1)) and (p.y != 3 or (p.x != 0 or p.y2))) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 2: finished, controlled behavior is stable.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2)))
+    Edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2 / p.y := 3, p := p.y3)
+
+Controlled system:                     exactly 6 states.
+
+Initial (synthesis result):            p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2))
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           p.x = 0 and p.l1
+Initial (removed by supervisor):       p.x = 2 and p.l1 or (p.x = 1 or p.x = 3) and p.l1
+Initial (added by supervisor):         (p.x != 2 or not p.l1) and (p.x = 0 or (p.x = 2 or not p.l1))
+
+Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
+  Initial: p.x = 0 and p.l1 -> p.x = 0 [assume p.l1].
+
+Constructing output CIF specification.
+Writing output CIF file "datasynth/edge_granularity_guards_updates2_per_event.ctrlsys.real.cif".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates2_per_event.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates2_per_event.ctrlsys.cif
new file mode 100644
index 0000000000000000000000000000000000000000..b864c268b42b8b269e04b2e4ddc610825260dca3
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates2_per_event.ctrlsys.cif
@@ -0,0 +1,20 @@
+uncontrollable e;
+plant automaton p:
+  disc int[0..3] x in any;
+  disc int[0..3] y in any;
+  location l1:
+    initial;
+    edge e when x = 0 do y := 2 goto y2;
+    edge e when x = 0 do y := 3 goto y3;
+  location y2:
+    marked y = 2;
+  location y3:
+    marked y = 3;
+end
+supervisor automaton sup:
+  alphabet;
+  initial p.x = 0;
+  location:
+    initial;
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates2_per_event.statespace.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates2_per_event.statespace.cif
new file mode 100644
index 0000000000000000000000000000000000000000..b5dea70e6adbc4fdac3ca464f1475c566de7cfd9
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates2_per_event.statespace.cif
@@ -0,0 +1,24 @@
+uncontrollable e;
+automaton statespace:
+  alphabet e;
+  location loc1:
+    initial;
+    edge e goto loc5;
+    edge e goto loc6;
+  location loc2:
+    initial;
+    edge e goto loc5;
+    edge e goto loc6;
+  location loc3:
+    initial;
+    edge e goto loc5;
+    edge e goto loc6;
+  location loc4:
+    initial;
+    edge e goto loc5;
+    edge e goto loc6;
+  location loc5:
+    marked;
+  location loc6:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates3_per_edge.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates3_per_edge.cif
new file mode 100644
index 0000000000000000000000000000000000000000..054d869520cffd57071561d803ff296f796929f3
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates3_per_edge.cif
@@ -0,0 +1,29 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..3] x in any;
+  disc int[0..3] y in any;
+
+  location l1: // x in {0, 1}, y in any
+    initial;
+
+    // Different guards, same updates.
+    edge e when x = 0 do y := 2 goto y2;
+    edge e when x = 1 do y := 2 goto y2;
+
+  location y2: // x in {0, 1}, y = 2
+    marked y = 2;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates3_per_edge.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates3_per_edge.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..035f3f6a05caa71ee272d3c3c003e80352673f5b
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates3_per_edge.cif.out
@@ -0,0 +1,226 @@
+Reading CIF file "datasynth/edge_granularity_guards_updates3_per_edge.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      1 * 2     2 * 2       2 * 2       100%
+  2      discrete variable  int[0..3]  p.x   1      2 * 2     4 * 2       4 * 2       100%
+  3      discrete variable  int[0..3]  p.y   2      2 * 2     4 * 2       4 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      3      10        20          20          100%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 5
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 3
+
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 3
+
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 3
+
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 3
+
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 20
+
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [before]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [iteration 1]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 3
+
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [before]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..3]  p.y   0      2 * 2     4 * 2       4 * 2       100%
+  2      discrete variable  int[0..3]  p.x   1      2 * 2     4 * 2       4 * 2       100%
+  3      location pointer   n/a        p     2      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      3      10        20          20          100%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variable 1):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.y = 2 and p.y2
+Marked    (auts/locs marker predicate):      p.y = 2 and p.y2
+Marked    (uncontrolled system):             p.y = 2 and p.y2
+Marked    (system, combined mark/plant inv): p.y = 2 and p.y2
+Marked    (system, combined mark/state inv): p.y = 2 and p.y2
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2)
+    Edge: (event: e) (guard: p.x = 1 and p.l1) (assignments: p.y := 2, p := p.y2)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.y = 2 and p.y2 [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.y = 2 and p.y2 -> p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and p.x = 0 or (p.y = 2 and (p.x = 2 and p.y2) or (p.y = 2 and ((p.x = 1 or p.x = 3) and p.y2) or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1))) [backward reach with edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2), restricted to current/previous controlled-behavior predicate: true]
+Backward controlled-behavior: p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and p.x = 0 or (p.y = 2 and (p.x = 2 and p.y2) or (p.y = 2 and ((p.x = 1 or p.x = 3) and p.y2) or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1))) -> p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or p.y = 2 and (p.x = 0 or p.x = 1) or (p.y = 2 and ((p.x = 2 or p.x = 3) and p.y2) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1)) [backward reach with edge: (event: e) (guard: p.x = 1 and p.l1) (assignments: p.y := 2, p := p.y2), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 2.
+Backward controlled-behavior: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or p.y = 2 and (p.x = 0 or p.x = 1) or (p.y = 2 and ((p.x = 2 or p.x = 3) and p.y2) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1)) [fixed point].
+Controlled behavior: true -> p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or p.y = 2 and (p.x = 0 or p.x = 1) or (p.y = 2 and ((p.x = 2 or p.x = 3) and p.y2) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1)).
+
+Round 1: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.y != 0 or p.x = 2 or (p.x = 3 or p.y2)) and (p.y != 2 or (p.x = 2 or p.x = 3)) and ((p.y != 2 or p.x = 0 or (p.x = 1 or p.l1)) and (p.y = 0 or p.y = 2 or (p.x = 2 or (p.x = 3 or p.y2)))) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 1: computing forward controlled-behavior predicate.
+Forward controlled-behavior: p.l1 [initialization predicate]
+Forward controlled-behavior: p.l1 -> (p.x = 0 or p.x = 1) and p.l1 [restricted to current/previous controlled-behavior predicate: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or p.y = 2 and (p.x = 0 or p.x = 1) or (p.y = 2 and ((p.x = 2 or p.x = 3) and p.y2) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1))]
+Forward reachability: iteration 1.
+Forward controlled-behavior: (p.x = 0 or p.x = 1) and p.l1 -> p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or p.y = 2 and p.x = 0 or (p.y = 2 and (p.x = 1 and p.l1) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1)) [forward reach with edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2), restricted to current/previous controlled-behavior predicate: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or p.y = 2 and (p.x = 0 or p.x = 1) or (p.y = 2 and ((p.x = 2 or p.x = 3) and p.y2) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1))]
+Forward controlled-behavior: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or p.y = 2 and p.x = 0 or (p.y = 2 and (p.x = 1 and p.l1) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1)) -> p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 or p.x = 1) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1)) [forward reach with edge: (event: e) (guard: p.x = 1 and p.l1) (assignments: p.y := 2, p := p.y2), restricted to current/previous controlled-behavior predicate: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or p.y = 2 and (p.x = 0 or p.x = 1) or (p.y = 2 and ((p.x = 2 or p.x = 3) and p.y2) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1))]
+Forward reachability: iteration 2.
+Forward controlled-behavior: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 or p.x = 1) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1)) [fixed point].
+Controlled behavior: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or p.y = 2 and (p.x = 0 or p.x = 1) or (p.y = 2 and ((p.x = 2 or p.x = 3) and p.y2) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1)) -> p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 or p.x = 1) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1)).
+
+Round 1: finished, need another round.
+
+Round 2: started.
+
+Round 2: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.y = 2 and p.y2 [marker predicate]
+Backward controlled-behavior: p.y = 2 and p.y2 -> p.y = 2 and ((p.x = 0 or p.x = 1) and p.y2) [restricted to current/previous controlled-behavior predicate: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 or p.x = 1) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1))]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.y = 2 and ((p.x = 0 or p.x = 1) and p.y2) -> p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and p.x = 0 or (p.y = 2 and (p.x = 1 and p.y2) or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1)) [backward reach with edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2), restricted to current/previous controlled-behavior predicate: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 or p.x = 1) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1))]
+Backward controlled-behavior: p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and p.x = 0 or (p.y = 2 and (p.x = 1 and p.y2) or (p.y = 1 or p.y = 3) and (p.x = 0 and p.l1)) -> p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 or p.x = 1) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1)) [backward reach with edge: (event: e) (guard: p.x = 1 and p.l1) (assignments: p.y := 2, p := p.y2), restricted to current/previous controlled-behavior predicate: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 or p.x = 1) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1))]
+Backward reachability: iteration 2.
+Backward controlled-behavior: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 or p.x = 1) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1)) [fixed point].
+
+Round 2: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.y != 0 or p.x = 2 or (p.x = 3 or p.y2)) and ((p.y != 2 or (p.x = 2 or p.x = 3)) and (p.y = 0 or p.y = 2 or (p.x = 2 or (p.x = 3 or p.y2)))) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 2: finished, controlled behavior is stable.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 or p.x = 1) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1)))
+    Edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2)
+    Edge: (event: e) (guard: p.x = 1 and p.l1) (assignments: p.y := 2, p := p.y2)
+
+Controlled system:                     exactly 10 states.
+
+Initial (synthesis result):            p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 or p.x = 1) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1))
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           (p.x = 0 or p.x = 1) and p.l1
+Initial (removed by supervisor):       (p.x = 2 or p.x = 3) and p.l1
+Initial (added by supervisor):         p.x = 0 or (p.x = 1 or p.y2)
+
+Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
+  Initial: (p.x = 0 or p.x = 1) and p.l1 -> p.x = 0 or p.x = 1 [assume p.l1].
+
+Constructing output CIF specification.
+Writing output CIF file "datasynth/edge_granularity_guards_updates3_per_edge.ctrlsys.real.cif".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates3_per_edge.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates3_per_edge.ctrlsys.cif
new file mode 100644
index 0000000000000000000000000000000000000000..eb6c0e205f80cd5689f0cd96b976f3026c848eca
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates3_per_edge.ctrlsys.cif
@@ -0,0 +1,18 @@
+uncontrollable e;
+plant automaton p:
+  disc int[0..3] x in any;
+  disc int[0..3] y in any;
+  location l1:
+    initial;
+    edge e when x = 0 do y := 2 goto y2;
+    edge e when x = 1 do y := 2 goto y2;
+  location y2:
+    marked y = 2;
+end
+supervisor automaton sup:
+  alphabet;
+  initial p.x = 0 or p.x = 1;
+  location:
+    initial;
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates3_per_edge.statespace.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates3_per_edge.statespace.cif
new file mode 100644
index 0000000000000000000000000000000000000000..325931837f4be270fd3f72468a23b51fccb5e25a
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates3_per_edge.statespace.cif
@@ -0,0 +1,32 @@
+uncontrollable e;
+automaton statespace:
+  alphabet e;
+  location loc1:
+    initial;
+    edge e goto loc9;
+  location loc2:
+    initial;
+    edge e goto loc9;
+  location loc3:
+    initial;
+    edge e goto loc9;
+  location loc4:
+    initial;
+    edge e goto loc9;
+  location loc5:
+    initial;
+    edge e goto loc10;
+  location loc6:
+    initial;
+    edge e goto loc10;
+  location loc7:
+    initial;
+    edge e goto loc10;
+  location loc8:
+    initial;
+    edge e goto loc10;
+  location loc9:
+    marked;
+  location loc10:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates3_per_event.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates3_per_event.cif
new file mode 100644
index 0000000000000000000000000000000000000000..054d869520cffd57071561d803ff296f796929f3
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates3_per_event.cif
@@ -0,0 +1,29 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..3] x in any;
+  disc int[0..3] y in any;
+
+  location l1: // x in {0, 1}, y in any
+    initial;
+
+    // Different guards, same updates.
+    edge e when x = 0 do y := 2 goto y2;
+    edge e when x = 1 do y := 2 goto y2;
+
+  location y2: // x in {0, 1}, y = 2
+    marked y = 2;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates3_per_event.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates3_per_event.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..ea10e2640b5eb05d6a6453216f191cd54f85c3e9
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates3_per_event.cif.out
@@ -0,0 +1,221 @@
+Reading CIF file "datasynth/edge_granularity_guards_updates3_per_event.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      1 * 2     2 * 2       2 * 2       100%
+  2      discrete variable  int[0..3]  p.x   1      2 * 2     4 * 2       4 * 2       100%
+  3      discrete variable  int[0..3]  p.y   2      2 * 2     4 * 2       4 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      3      10        20          20          100%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 5
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 3
+
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 3
+
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 3
+
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 3
+
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 20
+
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [before]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [iteration 1]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 3
+
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [before]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..3]  p.y   0      2 * 2     4 * 2       4 * 2       100%
+  2      discrete variable  int[0..3]  p.x   1      2 * 2     4 * 2       4 * 2       100%
+  3      location pointer   n/a        p     2      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      3      10        20          20          100%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variable 1):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.y = 2 and p.y2
+Marked    (auts/locs marker predicate):      p.y = 2 and p.y2
+Marked    (uncontrolled system):             p.y = 2 and p.y2
+Marked    (system, combined mark/plant inv): p.y = 2 and p.y2
+Marked    (system, combined mark/state inv): p.y = 2 and p.y2
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: (p.x = 0 or p.x = 1) and p.l1) (assignments: p.y := 2, p := p.y2 / p.y := 2, p := p.y2)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.y = 2 and p.y2 [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.y = 2 and p.y2 -> p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or p.y = 2 and (p.x = 0 or p.x = 1) or (p.y = 2 and ((p.x = 2 or p.x = 3) and p.y2) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1)) [backward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 1) and p.l1) (assignments: p.y := 2, p := p.y2 / p.y := 2, p := p.y2), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 2.
+Backward controlled-behavior: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or p.y = 2 and (p.x = 0 or p.x = 1) or (p.y = 2 and ((p.x = 2 or p.x = 3) and p.y2) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1)) [fixed point].
+Controlled behavior: true -> p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or p.y = 2 and (p.x = 0 or p.x = 1) or (p.y = 2 and ((p.x = 2 or p.x = 3) and p.y2) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1)).
+
+Round 1: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.y != 0 or p.x = 2 or (p.x = 3 or p.y2)) and (p.y != 2 or (p.x = 2 or p.x = 3)) and ((p.y != 2 or p.x = 0 or (p.x = 1 or p.l1)) and (p.y = 0 or p.y = 2 or (p.x = 2 or (p.x = 3 or p.y2)))) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 1: computing forward controlled-behavior predicate.
+Forward controlled-behavior: p.l1 [initialization predicate]
+Forward controlled-behavior: p.l1 -> (p.x = 0 or p.x = 1) and p.l1 [restricted to current/previous controlled-behavior predicate: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or p.y = 2 and (p.x = 0 or p.x = 1) or (p.y = 2 and ((p.x = 2 or p.x = 3) and p.y2) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1))]
+Forward reachability: iteration 1.
+Forward controlled-behavior: (p.x = 0 or p.x = 1) and p.l1 -> p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 or p.x = 1) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1)) [forward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 1) and p.l1) (assignments: p.y := 2, p := p.y2 / p.y := 2, p := p.y2), restricted to current/previous controlled-behavior predicate: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or p.y = 2 and (p.x = 0 or p.x = 1) or (p.y = 2 and ((p.x = 2 or p.x = 3) and p.y2) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1))]
+Forward reachability: iteration 2.
+Forward controlled-behavior: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 or p.x = 1) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1)) [fixed point].
+Controlled behavior: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or p.y = 2 and (p.x = 0 or p.x = 1) or (p.y = 2 and ((p.x = 2 or p.x = 3) and p.y2) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1)) -> p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 or p.x = 1) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1)).
+
+Round 1: finished, need another round.
+
+Round 2: started.
+
+Round 2: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.y = 2 and p.y2 [marker predicate]
+Backward controlled-behavior: p.y = 2 and p.y2 -> p.y = 2 and ((p.x = 0 or p.x = 1) and p.y2) [restricted to current/previous controlled-behavior predicate: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 or p.x = 1) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1))]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.y = 2 and ((p.x = 0 or p.x = 1) and p.y2) -> p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 or p.x = 1) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1)) [backward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 1) and p.l1) (assignments: p.y := 2, p := p.y2 / p.y := 2, p := p.y2), restricted to current/previous controlled-behavior predicate: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 or p.x = 1) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1))]
+Backward reachability: iteration 2.
+Backward controlled-behavior: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 or p.x = 1) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1)) [fixed point].
+
+Round 2: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.y != 0 or p.x = 2 or (p.x = 3 or p.y2)) and ((p.y != 2 or (p.x = 2 or p.x = 3)) and (p.y = 0 or p.y = 2 or (p.x = 2 or (p.x = 3 or p.y2)))) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 2: finished, controlled behavior is stable.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 or p.x = 1) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1)))
+    Edge: (event: e) (guard: (p.x = 0 or p.x = 1) and p.l1) (assignments: p.y := 2, p := p.y2 / p.y := 2, p := p.y2)
+
+Controlled system:                     exactly 10 states.
+
+Initial (synthesis result):            p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 or p.x = 1) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1))
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           (p.x = 0 or p.x = 1) and p.l1
+Initial (removed by supervisor):       (p.x = 2 or p.x = 3) and p.l1
+Initial (added by supervisor):         p.x = 0 or (p.x = 1 or p.y2)
+
+Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
+  Initial: (p.x = 0 or p.x = 1) and p.l1 -> p.x = 0 or p.x = 1 [assume p.l1].
+
+Constructing output CIF specification.
+Writing output CIF file "datasynth/edge_granularity_guards_updates3_per_event.ctrlsys.real.cif".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates3_per_event.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates3_per_event.ctrlsys.cif
new file mode 100644
index 0000000000000000000000000000000000000000..eb6c0e205f80cd5689f0cd96b976f3026c848eca
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates3_per_event.ctrlsys.cif
@@ -0,0 +1,18 @@
+uncontrollable e;
+plant automaton p:
+  disc int[0..3] x in any;
+  disc int[0..3] y in any;
+  location l1:
+    initial;
+    edge e when x = 0 do y := 2 goto y2;
+    edge e when x = 1 do y := 2 goto y2;
+  location y2:
+    marked y = 2;
+end
+supervisor automaton sup:
+  alphabet;
+  initial p.x = 0 or p.x = 1;
+  location:
+    initial;
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates3_per_event.statespace.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates3_per_event.statespace.cif
new file mode 100644
index 0000000000000000000000000000000000000000..325931837f4be270fd3f72468a23b51fccb5e25a
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates3_per_event.statespace.cif
@@ -0,0 +1,32 @@
+uncontrollable e;
+automaton statespace:
+  alphabet e;
+  location loc1:
+    initial;
+    edge e goto loc9;
+  location loc2:
+    initial;
+    edge e goto loc9;
+  location loc3:
+    initial;
+    edge e goto loc9;
+  location loc4:
+    initial;
+    edge e goto loc9;
+  location loc5:
+    initial;
+    edge e goto loc10;
+  location loc6:
+    initial;
+    edge e goto loc10;
+  location loc7:
+    initial;
+    edge e goto loc10;
+  location loc8:
+    initial;
+    edge e goto loc10;
+  location loc9:
+    marked;
+  location loc10:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates4_per_edge.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates4_per_edge.cif
new file mode 100644
index 0000000000000000000000000000000000000000..89f3bcf63e12f8aad5e8321b12ebc738ccbbc7e4
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates4_per_edge.cif
@@ -0,0 +1,32 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..3] x in any;
+  disc int[0..3] y in any;
+
+  location l1: // x in {0, 1}, y in any
+    initial;
+
+    // Different guards, different updates.
+    edge e when x = 0 do y := 2 goto y2;
+    edge e when x = 1 do y := 3 goto y3;
+
+  location y2: // x = 0, y = 2
+    marked y = 2;
+
+  location y3: // x = 1, y = 3
+    marked y = 3;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates4_per_edge.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates4_per_edge.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..6d4aef952013648c4f83525df7eafa3919a87949
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates4_per_edge.cif.out
@@ -0,0 +1,230 @@
+Reading CIF file "datasynth/edge_granularity_guards_updates4_per_edge.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      2 * 2     3 * 2       4 * 2       75%
+  2      discrete variable  int[0..3]  p.x   1      2 * 2     4 * 2       4 * 2       100%
+  3      discrete variable  int[0..3]  p.y   2      2 * 2     4 * 2       4 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      3      12        22          24          ~92%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 5
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 3
+
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 3
+
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 3
+
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 3
+
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 20
+
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [before]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [iteration 1]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 3
+
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [before]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..3]  p.y   0      2 * 2     4 * 2       4 * 2       100%
+  2      discrete variable  int[0..3]  p.x   1      2 * 2     4 * 2       4 * 2       100%
+  3      location pointer   n/a        p     2      2 * 2     3 * 2       4 * 2       75%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      3      12        22          24          ~92%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variable 1):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.y = 2 and p.y2 or p.y = 3 and p.y3
+Marked    (auts/locs marker predicate):      p.y = 2 and p.y2 or p.y = 3 and p.y3
+Marked    (uncontrolled system):             p.y = 2 and p.y2 or p.y = 3 and p.y3
+Marked    (system, combined mark/plant inv): p.y = 2 and p.y2 or p.y = 3 and p.y3
+Marked    (system, combined mark/state inv): p.y = 2 and p.y2 or p.y = 3 and p.y3
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2)
+    Edge: (event: e) (guard: p.x = 1 and p.l1) (assignments: p.y := 3, p := p.y3)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Controlled behavior: true -> true [range: true, variable: location pointer for automaton "p" (group: 2, domain: 4+5, BDD variables: 2, CIF/BDD values: 3/4)].
+
+Extended controlled-behavior predicate using variable ranges: true.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.y = 2 and p.y2 or p.y = 3 and p.y3 [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.y = 2 and p.y2 or p.y = 3 and p.y3 -> p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 2 and (p.x = 2 and p.y2) or p.y = 2 and ((p.x = 1 or p.x = 3) and p.y2)) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2) or (p.y = 3 and (p.x = 2 and p.y3) or p.y = 3 and ((p.x = 1 or p.x = 3) and p.y3))) [backward reach with edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2), restricted to current/previous controlled-behavior predicate: true]
+Backward controlled-behavior: p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 2 and (p.x = 2 and p.y2) or p.y = 2 and ((p.x = 1 or p.x = 3) and p.y2)) or (p.y = 1 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 0 and not p.y2) or (p.y = 3 and (p.x = 2 and p.y3) or p.y = 3 and ((p.x = 1 or p.x = 3) and p.y3))) -> p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and ((p.x = 0 or p.x = 1) and not p.y3) or p.y = 2 and ((p.x = 2 or p.x = 3) and p.y2)) or (p.y = 1 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 3 and ((p.x = 0 or p.x = 1) and not p.y2) or p.y = 3 and ((p.x = 2 or p.x = 3) and p.y3))) [backward reach with edge: (event: e) (guard: p.x = 1 and p.l1) (assignments: p.y := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 2.
+Backward controlled-behavior: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and ((p.x = 0 or p.x = 1) and not p.y3) or p.y = 2 and ((p.x = 2 or p.x = 3) and p.y2)) or (p.y = 1 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 3 and ((p.x = 0 or p.x = 1) and not p.y2) or p.y = 3 and ((p.x = 2 or p.x = 3) and p.y3))) [fixed point].
+Controlled behavior: true -> p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and ((p.x = 0 or p.x = 1) and not p.y3) or p.y = 2 and ((p.x = 2 or p.x = 3) and p.y2)) or (p.y = 1 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 3 and ((p.x = 0 or p.x = 1) and not p.y2) or p.y = 3 and ((p.x = 2 or p.x = 3) and p.y3))).
+
+Round 1: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.y != 0 or p.x = 2 or (p.x = 3 or not p.l1)) and ((p.y != 2 or p.x = 2 or (p.x = 3 or p.y3)) and (p.y != 2 or p.x = 0 or (p.x = 1 or not p.y2))) and ((p.y != 1 or p.x = 2 or (p.x = 3 or not p.l1)) and ((p.y != 3 or p.x = 2 or (p.x = 3 or p.y2)) and (p.y != 3 or p.x = 0 or (p.x = 1 or not p.y3)))) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 1: computing forward controlled-behavior predicate.
+Forward controlled-behavior: p.l1 [initialization predicate]
+Forward controlled-behavior: p.l1 -> (p.x = 0 or p.x = 1) and p.l1 [restricted to current/previous controlled-behavior predicate: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and ((p.x = 0 or p.x = 1) and not p.y3) or p.y = 2 and ((p.x = 2 or p.x = 3) and p.y2)) or (p.y = 1 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 3 and ((p.x = 0 or p.x = 1) and not p.y2) or p.y = 3 and ((p.x = 2 or p.x = 3) and p.y3)))]
+Forward reachability: iteration 1.
+Forward controlled-behavior: (p.x = 0 or p.x = 1) and p.l1 -> p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 2 and (p.x = 1 and p.l1) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1)) [forward reach with edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2), restricted to current/previous controlled-behavior predicate: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and ((p.x = 0 or p.x = 1) and not p.y3) or p.y = 2 and ((p.x = 2 or p.x = 3) and p.y2)) or (p.y = 1 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 3 and ((p.x = 0 or p.x = 1) and not p.y2) or p.y = 3 and ((p.x = 2 or p.x = 3) and p.y3)))]
+Forward controlled-behavior: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 2 and (p.x = 1 and p.l1) or (p.y = 1 or p.y = 3) and ((p.x = 0 or p.x = 1) and p.l1)) -> p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 and not p.y3) or p.y = 2 and (p.x = 1 and p.l1)) or (p.y = 1 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 3 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 1 and not p.y2))) [forward reach with edge: (event: e) (guard: p.x = 1 and p.l1) (assignments: p.y := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and ((p.x = 0 or p.x = 1) and not p.y3) or p.y = 2 and ((p.x = 2 or p.x = 3) and p.y2)) or (p.y = 1 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 3 and ((p.x = 0 or p.x = 1) and not p.y2) or p.y = 3 and ((p.x = 2 or p.x = 3) and p.y3)))]
+Forward reachability: iteration 2.
+Forward controlled-behavior: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 and not p.y3) or p.y = 2 and (p.x = 1 and p.l1)) or (p.y = 1 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 3 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 1 and not p.y2))) [fixed point].
+Controlled behavior: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and ((p.x = 0 or p.x = 1) and not p.y3) or p.y = 2 and ((p.x = 2 or p.x = 3) and p.y2)) or (p.y = 1 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 3 and ((p.x = 0 or p.x = 1) and not p.y2) or p.y = 3 and ((p.x = 2 or p.x = 3) and p.y3))) -> p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 and not p.y3) or p.y = 2 and (p.x = 1 and p.l1)) or (p.y = 1 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 3 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 1 and not p.y2))).
+
+Round 1: finished, need another round.
+
+Round 2: started.
+
+Round 2: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.y = 2 and p.y2 or p.y = 3 and p.y3 [marker predicate]
+Backward controlled-behavior: p.y = 2 and p.y2 or p.y = 3 and p.y3 -> p.y = 2 and (p.x = 0 and p.y2) or p.y = 3 and (p.x = 1 and p.y3) [restricted to current/previous controlled-behavior predicate: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 and not p.y3) or p.y = 2 and (p.x = 1 and p.l1)) or (p.y = 1 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 3 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 1 and not p.y2)))]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.y = 2 and (p.x = 0 and p.y2) or p.y = 3 and (p.x = 1 and p.y3) -> p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 1 and (p.x = 0 and p.l1) or (p.y = 3 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 1 and p.y3))) [backward reach with edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2), restricted to current/previous controlled-behavior predicate: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 and not p.y3) or p.y = 2 and (p.x = 1 and p.l1)) or (p.y = 1 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 3 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 1 and not p.y2)))]
+Backward controlled-behavior: p.y = 0 and (p.x = 0 and p.l1) or p.y = 2 and (p.x = 0 and not p.y3) or (p.y = 1 and (p.x = 0 and p.l1) or (p.y = 3 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 1 and p.y3))) -> p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 and not p.y3) or p.y = 2 and (p.x = 1 and p.l1)) or (p.y = 1 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 3 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 1 and not p.y2))) [backward reach with edge: (event: e) (guard: p.x = 1 and p.l1) (assignments: p.y := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 and not p.y3) or p.y = 2 and (p.x = 1 and p.l1)) or (p.y = 1 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 3 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 1 and not p.y2)))]
+Backward reachability: iteration 2.
+Backward controlled-behavior: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 and not p.y3) or p.y = 2 and (p.x = 1 and p.l1)) or (p.y = 1 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 3 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 1 and not p.y2))) [fixed point].
+
+Round 2: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.y != 0 or p.x = 2 or (p.x = 3 or not p.l1)) and ((p.y != 2 or (p.x != 0 or p.y3)) and (p.y != 2 or (p.x != 1 or not p.l1))) and ((p.y != 1 or p.x = 2 or (p.x = 3 or not p.l1)) and ((p.y != 3 or (p.x != 0 or not p.l1)) and (p.y != 3 or (p.x != 1 or p.y2)))) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 2: finished, controlled behavior is stable.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 and not p.y3) or p.y = 2 and (p.x = 1 and p.l1)) or (p.y = 1 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 3 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 1 and not p.y2))))
+    Edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2)
+    Edge: (event: e) (guard: p.x = 1 and p.l1) (assignments: p.y := 3, p := p.y3)
+
+Controlled system:                     exactly 10 states.
+
+Initial (synthesis result):            p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 and not p.y3) or p.y = 2 and (p.x = 1 and p.l1)) or (p.y = 1 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 3 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 1 and not p.y2)))
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           (p.x = 0 or p.x = 1) and p.l1
+Initial (removed by supervisor):       (p.x = 2 or p.x = 3) and p.l1
+Initial (added by supervisor):         p.x = 0 or (p.x = 1 or not p.l1)
+
+Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
+  Initial: (p.x = 0 or p.x = 1) and p.l1 -> p.x = 0 or p.x = 1 [assume p.l1].
+
+Constructing output CIF specification.
+Writing output CIF file "datasynth/edge_granularity_guards_updates4_per_edge.ctrlsys.real.cif".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates4_per_edge.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates4_per_edge.ctrlsys.cif
new file mode 100644
index 0000000000000000000000000000000000000000..7acbcb8a4dc4bd101bab06fd61bed73d17094605
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates4_per_edge.ctrlsys.cif
@@ -0,0 +1,20 @@
+uncontrollable e;
+plant automaton p:
+  disc int[0..3] x in any;
+  disc int[0..3] y in any;
+  location l1:
+    initial;
+    edge e when x = 0 do y := 2 goto y2;
+    edge e when x = 1 do y := 3 goto y3;
+  location y2:
+    marked y = 2;
+  location y3:
+    marked y = 3;
+end
+supervisor automaton sup:
+  alphabet;
+  initial p.x = 0 or p.x = 1;
+  location:
+    initial;
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates4_per_edge.statespace.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates4_per_edge.statespace.cif
new file mode 100644
index 0000000000000000000000000000000000000000..325931837f4be270fd3f72468a23b51fccb5e25a
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates4_per_edge.statespace.cif
@@ -0,0 +1,32 @@
+uncontrollable e;
+automaton statespace:
+  alphabet e;
+  location loc1:
+    initial;
+    edge e goto loc9;
+  location loc2:
+    initial;
+    edge e goto loc9;
+  location loc3:
+    initial;
+    edge e goto loc9;
+  location loc4:
+    initial;
+    edge e goto loc9;
+  location loc5:
+    initial;
+    edge e goto loc10;
+  location loc6:
+    initial;
+    edge e goto loc10;
+  location loc7:
+    initial;
+    edge e goto loc10;
+  location loc8:
+    initial;
+    edge e goto loc10;
+  location loc9:
+    marked;
+  location loc10:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates4_per_event.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates4_per_event.cif
new file mode 100644
index 0000000000000000000000000000000000000000..89f3bcf63e12f8aad5e8321b12ebc738ccbbc7e4
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates4_per_event.cif
@@ -0,0 +1,32 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..3] x in any;
+  disc int[0..3] y in any;
+
+  location l1: // x in {0, 1}, y in any
+    initial;
+
+    // Different guards, different updates.
+    edge e when x = 0 do y := 2 goto y2;
+    edge e when x = 1 do y := 3 goto y3;
+
+  location y2: // x = 0, y = 2
+    marked y = 2;
+
+  location y3: // x = 1, y = 3
+    marked y = 3;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates4_per_event.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates4_per_event.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..9410417518f1c79cb720111425518fd1104a3c0f
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates4_per_event.cif.out
@@ -0,0 +1,225 @@
+Reading CIF file "datasynth/edge_granularity_guards_updates4_per_event.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      2 * 2     3 * 2       4 * 2       75%
+  2      discrete variable  int[0..3]  p.x   1      2 * 2     4 * 2       4 * 2       100%
+  3      discrete variable  int[0..3]  p.y   2      2 * 2     4 * 2       4 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      3      12        22          24          ~92%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 5
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 3
+
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 3
+
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 3
+
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 3
+
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 5
+
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.533333 (total)   0.106667 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 20
+
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [before]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [iteration 1]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 3
+
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [before]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..3]  p.y   0      2 * 2     4 * 2       4 * 2       100%
+  2      discrete variable  int[0..3]  p.x   1      2 * 2     4 * 2       4 * 2       100%
+  3      location pointer   n/a        p     2      2 * 2     3 * 2       4 * 2       75%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      3      12        22          24          ~92%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variable 1):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.y = 2 and p.y2 or p.y = 3 and p.y3
+Marked    (auts/locs marker predicate):      p.y = 2 and p.y2 or p.y = 3 and p.y3
+Marked    (uncontrolled system):             p.y = 2 and p.y2 or p.y = 3 and p.y3
+Marked    (system, combined mark/plant inv): p.y = 2 and p.y2 or p.y = 3 and p.y3
+Marked    (system, combined mark/state inv): p.y = 2 and p.y2 or p.y = 3 and p.y3
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: (p.x = 0 or p.x = 1) and p.l1) (assignments: p.y := 2, p := p.y2 / p.y := 3, p := p.y3)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Controlled behavior: true -> true [range: true, variable: location pointer for automaton "p" (group: 2, domain: 4+5, BDD variables: 2, CIF/BDD values: 3/4)].
+
+Extended controlled-behavior predicate using variable ranges: true.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.y = 2 and p.y2 or p.y = 3 and p.y3 [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.y = 2 and p.y2 or p.y = 3 and p.y3 -> p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and ((p.x = 0 or p.x = 1) and not p.y3) or p.y = 2 and ((p.x = 2 or p.x = 3) and p.y2)) or (p.y = 1 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 3 and ((p.x = 0 or p.x = 1) and not p.y2) or p.y = 3 and ((p.x = 2 or p.x = 3) and p.y3))) [backward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 1) and p.l1) (assignments: p.y := 2, p := p.y2 / p.y := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 2.
+Backward controlled-behavior: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and ((p.x = 0 or p.x = 1) and not p.y3) or p.y = 2 and ((p.x = 2 or p.x = 3) and p.y2)) or (p.y = 1 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 3 and ((p.x = 0 or p.x = 1) and not p.y2) or p.y = 3 and ((p.x = 2 or p.x = 3) and p.y3))) [fixed point].
+Controlled behavior: true -> p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and ((p.x = 0 or p.x = 1) and not p.y3) or p.y = 2 and ((p.x = 2 or p.x = 3) and p.y2)) or (p.y = 1 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 3 and ((p.x = 0 or p.x = 1) and not p.y2) or p.y = 3 and ((p.x = 2 or p.x = 3) and p.y3))).
+
+Round 1: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.y != 0 or p.x = 2 or (p.x = 3 or not p.l1)) and ((p.y != 2 or p.x = 2 or (p.x = 3 or p.y3)) and (p.y != 2 or p.x = 0 or (p.x = 1 or not p.y2))) and ((p.y != 1 or p.x = 2 or (p.x = 3 or not p.l1)) and ((p.y != 3 or p.x = 2 or (p.x = 3 or p.y2)) and (p.y != 3 or p.x = 0 or (p.x = 1 or not p.y3)))) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 1: computing forward controlled-behavior predicate.
+Forward controlled-behavior: p.l1 [initialization predicate]
+Forward controlled-behavior: p.l1 -> (p.x = 0 or p.x = 1) and p.l1 [restricted to current/previous controlled-behavior predicate: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and ((p.x = 0 or p.x = 1) and not p.y3) or p.y = 2 and ((p.x = 2 or p.x = 3) and p.y2)) or (p.y = 1 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 3 and ((p.x = 0 or p.x = 1) and not p.y2) or p.y = 3 and ((p.x = 2 or p.x = 3) and p.y3)))]
+Forward reachability: iteration 1.
+Forward controlled-behavior: (p.x = 0 or p.x = 1) and p.l1 -> p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 and not p.y3) or p.y = 2 and (p.x = 1 and p.l1)) or (p.y = 1 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 3 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 1 and not p.y2))) [forward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 1) and p.l1) (assignments: p.y := 2, p := p.y2 / p.y := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and ((p.x = 0 or p.x = 1) and not p.y3) or p.y = 2 and ((p.x = 2 or p.x = 3) and p.y2)) or (p.y = 1 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 3 and ((p.x = 0 or p.x = 1) and not p.y2) or p.y = 3 and ((p.x = 2 or p.x = 3) and p.y3)))]
+Forward reachability: iteration 2.
+Forward controlled-behavior: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 and not p.y3) or p.y = 2 and (p.x = 1 and p.l1)) or (p.y = 1 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 3 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 1 and not p.y2))) [fixed point].
+Controlled behavior: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and ((p.x = 0 or p.x = 1) and not p.y3) or p.y = 2 and ((p.x = 2 or p.x = 3) and p.y2)) or (p.y = 1 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 3 and ((p.x = 0 or p.x = 1) and not p.y2) or p.y = 3 and ((p.x = 2 or p.x = 3) and p.y3))) -> p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 and not p.y3) or p.y = 2 and (p.x = 1 and p.l1)) or (p.y = 1 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 3 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 1 and not p.y2))).
+
+Round 1: finished, need another round.
+
+Round 2: started.
+
+Round 2: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.y = 2 and p.y2 or p.y = 3 and p.y3 [marker predicate]
+Backward controlled-behavior: p.y = 2 and p.y2 or p.y = 3 and p.y3 -> p.y = 2 and (p.x = 0 and p.y2) or p.y = 3 and (p.x = 1 and p.y3) [restricted to current/previous controlled-behavior predicate: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 and not p.y3) or p.y = 2 and (p.x = 1 and p.l1)) or (p.y = 1 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 3 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 1 and not p.y2)))]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.y = 2 and (p.x = 0 and p.y2) or p.y = 3 and (p.x = 1 and p.y3) -> p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 and not p.y3) or p.y = 2 and (p.x = 1 and p.l1)) or (p.y = 1 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 3 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 1 and not p.y2))) [backward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 1) and p.l1) (assignments: p.y := 2, p := p.y2 / p.y := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 and not p.y3) or p.y = 2 and (p.x = 1 and p.l1)) or (p.y = 1 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 3 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 1 and not p.y2)))]
+Backward reachability: iteration 2.
+Backward controlled-behavior: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 and not p.y3) or p.y = 2 and (p.x = 1 and p.l1)) or (p.y = 1 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 3 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 1 and not p.y2))) [fixed point].
+
+Round 2: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.y != 0 or p.x = 2 or (p.x = 3 or not p.l1)) and ((p.y != 2 or (p.x != 0 or p.y3)) and (p.y != 2 or (p.x != 1 or not p.l1))) and ((p.y != 1 or p.x = 2 or (p.x = 3 or not p.l1)) and ((p.y != 3 or (p.x != 0 or not p.l1)) and (p.y != 3 or (p.x != 1 or p.y2)))) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 2: finished, controlled behavior is stable.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 and not p.y3) or p.y = 2 and (p.x = 1 and p.l1)) or (p.y = 1 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 3 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 1 and not p.y2))))
+    Edge: (event: e) (guard: (p.x = 0 or p.x = 1) and p.l1) (assignments: p.y := 2, p := p.y2 / p.y := 3, p := p.y3)
+
+Controlled system:                     exactly 10 states.
+
+Initial (synthesis result):            p.y = 0 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 2 and (p.x = 0 and not p.y3) or p.y = 2 and (p.x = 1 and p.l1)) or (p.y = 1 and ((p.x = 0 or p.x = 1) and p.l1) or (p.y = 3 and (p.x = 0 and p.l1) or p.y = 3 and (p.x = 1 and not p.y2)))
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           (p.x = 0 or p.x = 1) and p.l1
+Initial (removed by supervisor):       (p.x = 2 or p.x = 3) and p.l1
+Initial (added by supervisor):         p.x = 0 or (p.x = 1 or not p.l1)
+
+Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
+  Initial: (p.x = 0 or p.x = 1) and p.l1 -> p.x = 0 or p.x = 1 [assume p.l1].
+
+Constructing output CIF specification.
+Writing output CIF file "datasynth/edge_granularity_guards_updates4_per_event.ctrlsys.real.cif".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates4_per_event.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates4_per_event.ctrlsys.cif
new file mode 100644
index 0000000000000000000000000000000000000000..7acbcb8a4dc4bd101bab06fd61bed73d17094605
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates4_per_event.ctrlsys.cif
@@ -0,0 +1,20 @@
+uncontrollable e;
+plant automaton p:
+  disc int[0..3] x in any;
+  disc int[0..3] y in any;
+  location l1:
+    initial;
+    edge e when x = 0 do y := 2 goto y2;
+    edge e when x = 1 do y := 3 goto y3;
+  location y2:
+    marked y = 2;
+  location y3:
+    marked y = 3;
+end
+supervisor automaton sup:
+  alphabet;
+  initial p.x = 0 or p.x = 1;
+  location:
+    initial;
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates4_per_event.statespace.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates4_per_event.statespace.cif
new file mode 100644
index 0000000000000000000000000000000000000000..325931837f4be270fd3f72468a23b51fccb5e25a
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates4_per_event.statespace.cif
@@ -0,0 +1,32 @@
+uncontrollable e;
+automaton statespace:
+  alphabet e;
+  location loc1:
+    initial;
+    edge e goto loc9;
+  location loc2:
+    initial;
+    edge e goto loc9;
+  location loc3:
+    initial;
+    edge e goto loc9;
+  location loc4:
+    initial;
+    edge e goto loc9;
+  location loc5:
+    initial;
+    edge e goto loc10;
+  location loc6:
+    initial;
+    edge e goto loc10;
+  location loc7:
+    initial;
+    edge e goto loc10;
+  location loc8:
+    initial;
+    edge e goto loc10;
+  location loc9:
+    marked;
+  location loc10:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates5_per_edge.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates5_per_edge.cif
new file mode 100644
index 0000000000000000000000000000000000000000..11dd44b90bd4f4b3fca97c765506d5f39d472aba
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates5_per_edge.cif
@@ -0,0 +1,29 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..3] x in any;
+  disc int[0..3] y in any;
+
+  location l1: // x in {0, 1, 2}, y in any
+    initial;
+
+    // Partially overlapping guards, same updates.
+    edge e when x = 0 or x = 1 do y := 3 goto y3;
+    edge e when x = 1 or x = 2 do y := 3 goto y3;
+
+  location y3: // x in {0, 1, 2}, y = 3
+    marked y = 3;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates5_per_edge.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates5_per_edge.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..9b9f22aa4cf8a19428fed4efacbe090aeb5afbca
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates5_per_edge.cif.out
@@ -0,0 +1,228 @@
+Reading CIF file "datasynth/edge_granularity_guards_updates5_per_edge.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      1 * 2     2 * 2       2 * 2       100%
+  2      discrete variable  int[0..3]  p.x   1      2 * 2     4 * 2       4 * 2       100%
+  3      discrete variable  int[0..3]  p.y   2      2 * 2     4 * 2       4 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      3      10        20          20          100%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 7
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 3
+
+        Total span:   2 (total)   0.29 (avg/edge) / WES:   0.444444 (total)   0.063492 (avg/edge) [before]
+        Total span:   2 (total)   0.29 (avg/edge) / WES:   0.444444 (total)   0.063492 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 3
+
+        Total span:   2 (total)   0.29 (avg/edge) / WES:   0.444444 (total)   0.063492 (avg/edge) [before]
+        Total span:   2 (total)   0.29 (avg/edge) / WES:   0.507937 (total)   0.072562 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 3
+
+          Total span:   2 (total)   0.29 (avg/edge) / WES:   0.444444 (total)   0.063492 (avg/edge) [before]
+          Total span:   2 (total)   0.29 (avg/edge) / WES:   0.444444 (total)   0.063492 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 7
+
+          Total span:   2 (total)   0.29 (avg/edge) / WES:   0.444444 (total)   0.063492 (avg/edge) [before]
+          Total span:   2 (total)   0.29 (avg/edge) / WES:   0.444444 (total)   0.063492 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 3
+
+          Total span:   2 (total)   0.29 (avg/edge) / WES:   0.444444 (total)   0.063492 (avg/edge) [before]
+          Total span:   2 (total)   0.29 (avg/edge) / WES:   0.507937 (total)   0.072562 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 7
+
+          Total span:   2 (total)   0.29 (avg/edge) / WES:   0.507937 (total)   0.072562 (avg/edge) [before]
+          Total span:   2 (total)   0.29 (avg/edge) / WES:   0.507937 (total)   0.072562 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 20
+
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [before]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [iteration 1]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 3
+
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [before]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..3]  p.x   0      2 * 2     4 * 2       4 * 2       100%
+  2      discrete variable  int[0..3]  p.y   1      2 * 2     4 * 2       4 * 2       100%
+  3      location pointer   n/a        p     2      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      3      10        20          20          100%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variable 1):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.y = 3 and p.y3
+Marked    (auts/locs marker predicate):      p.y = 3 and p.y3
+Marked    (uncontrolled system):             p.y = 3 and p.y3
+Marked    (system, combined mark/plant inv): p.y = 3 and p.y3
+Marked    (system, combined mark/state inv): p.y = 3 and p.y3
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: (p.x = 0 or p.x = 1) and p.l1) (assignments: p.y := 3, p := p.y3)
+    Edge: (event: e) (guard: p.x = 2 and p.l1 or p.x = 1 and p.l1) (assignments: p.y := 3, p := p.y3)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.y = 3 and p.y3 [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.y = 3 and p.y3 -> (p.x = 0 or p.x = 1) and ((p.y = 0 or p.y = 2) and p.l1) or (p.x = 0 or p.x = 1) and (p.y = 1 and p.l1) or ((p.x = 0 or p.x = 1) and p.y = 3 or (p.x = 2 or p.x = 3) and (p.y = 3 and p.y3)) [backward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 1) and p.l1) (assignments: p.y := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: true]
+Backward controlled-behavior: (p.x = 0 or p.x = 1) and ((p.y = 0 or p.y = 2) and p.l1) or (p.x = 0 or p.x = 1) and (p.y = 1 and p.l1) or ((p.x = 0 or p.x = 1) and p.y = 3 or (p.x = 2 or p.x = 3) and (p.y = 3 and p.y3)) -> (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.l1))) and ((p.x = 1 or p.x = 3 or (p.y != 1 or p.l1)) and (p.x != 1 or p.y = 1 or (p.y = 3 or p.l1))) and ((p.x != 1 or (p.y != 1 or p.l1)) and (p.x != 3 or (p.y = 1 or p.y = 3)) and ((p.x != 3 or p.y != 1) and (p.x != 3 or (p.y != 3 or p.y3)))) [backward reach with edge: (event: e) (guard: p.x = 2 and p.l1 or p.x = 1 and p.l1) (assignments: p.y := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 2.
+Backward controlled-behavior: (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.l1))) and ((p.x = 1 or p.x = 3 or (p.y != 1 or p.l1)) and (p.x != 1 or p.y = 1 or (p.y = 3 or p.l1))) and ((p.x != 1 or (p.y != 1 or p.l1)) and (p.x != 3 or (p.y = 1 or p.y = 3)) and ((p.x != 3 or p.y != 1) and (p.x != 3 or (p.y != 3 or p.y3)))) [fixed point].
+Controlled behavior: true -> (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.l1))) and ((p.x = 1 or p.x = 3 or (p.y != 1 or p.l1)) and (p.x != 1 or p.y = 1 or (p.y = 3 or p.l1))) and ((p.x != 1 or (p.y != 1 or p.l1)) and (p.x != 3 or (p.y = 1 or p.y = 3)) and ((p.x != 3 or p.y != 1) and (p.x != 3 or (p.y != 3 or p.y3)))).
+
+Round 1: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.y3))) and ((p.x = 1 or p.x = 3 or (p.y != 1 or p.y3)) and (p.x = 1 or (p.x = 3 or p.y != 3))) and ((p.x != 1 or p.y = 1 or (p.y = 3 or p.y3)) and (p.x != 1 or (p.y != 1 or p.y3)) and ((p.x != 1 or p.y != 3) and (p.x != 3 or (p.y != 3 or p.l1)))) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 1: computing forward controlled-behavior predicate.
+Forward controlled-behavior: p.l1 [initialization predicate]
+Forward controlled-behavior: p.l1 -> (p.x = 0 or p.x = 2) and p.l1 or p.x = 1 and p.l1 [restricted to current/previous controlled-behavior predicate: (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.l1))) and ((p.x = 1 or p.x = 3 or (p.y != 1 or p.l1)) and (p.x != 1 or p.y = 1 or (p.y = 3 or p.l1))) and ((p.x != 1 or (p.y != 1 or p.l1)) and (p.x != 3 or (p.y = 1 or p.y = 3)) and ((p.x != 3 or p.y != 1) and (p.x != 3 or (p.y != 3 or p.y3))))]
+Forward reachability: iteration 1.
+Forward controlled-behavior: (p.x = 0 or p.x = 2) and p.l1 or p.x = 1 and p.l1 -> (p.x != 0 or p.y = 1 or (p.y = 3 or p.l1)) and ((p.x != 0 or (p.y != 1 or p.l1)) and (p.x != 2 or p.l1)) and ((p.x != 1 or p.y = 1 or (p.y = 3 or p.l1)) and ((p.x != 1 or (p.y != 1 or p.l1)) and p.x != 3)) [forward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 1) and p.l1) (assignments: p.y := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.l1))) and ((p.x = 1 or p.x = 3 or (p.y != 1 or p.l1)) and (p.x != 1 or p.y = 1 or (p.y = 3 or p.l1))) and ((p.x != 1 or (p.y != 1 or p.l1)) and (p.x != 3 or (p.y = 1 or p.y = 3)) and ((p.x != 3 or p.y != 1) and (p.x != 3 or (p.y != 3 or p.y3))))]
+Forward controlled-behavior: (p.x != 0 or p.y = 1 or (p.y = 3 or p.l1)) and ((p.x != 0 or (p.y != 1 or p.l1)) and (p.x != 2 or p.l1)) and ((p.x != 1 or p.y = 1 or (p.y = 3 or p.l1)) and ((p.x != 1 or (p.y != 1 or p.l1)) and p.x != 3)) -> (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.l1))) and (p.x = 1 or p.x = 3 or (p.y != 1 or p.l1)) and ((p.x != 1 or p.y = 1 or (p.y = 3 or p.l1)) and ((p.x != 1 or (p.y != 1 or p.l1)) and p.x != 3)) [forward reach with edge: (event: e) (guard: p.x = 2 and p.l1 or p.x = 1 and p.l1) (assignments: p.y := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.l1))) and ((p.x = 1 or p.x = 3 or (p.y != 1 or p.l1)) and (p.x != 1 or p.y = 1 or (p.y = 3 or p.l1))) and ((p.x != 1 or (p.y != 1 or p.l1)) and (p.x != 3 or (p.y = 1 or p.y = 3)) and ((p.x != 3 or p.y != 1) and (p.x != 3 or (p.y != 3 or p.y3))))]
+Forward reachability: iteration 2.
+Forward controlled-behavior: (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.l1))) and (p.x = 1 or p.x = 3 or (p.y != 1 or p.l1)) and ((p.x != 1 or p.y = 1 or (p.y = 3 or p.l1)) and ((p.x != 1 or (p.y != 1 or p.l1)) and p.x != 3)) [fixed point].
+Controlled behavior: (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.l1))) and ((p.x = 1 or p.x = 3 or (p.y != 1 or p.l1)) and (p.x != 1 or p.y = 1 or (p.y = 3 or p.l1))) and ((p.x != 1 or (p.y != 1 or p.l1)) and (p.x != 3 or (p.y = 1 or p.y = 3)) and ((p.x != 3 or p.y != 1) and (p.x != 3 or (p.y != 3 or p.y3)))) -> (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.l1))) and (p.x = 1 or p.x = 3 or (p.y != 1 or p.l1)) and ((p.x != 1 or p.y = 1 or (p.y = 3 or p.l1)) and ((p.x != 1 or (p.y != 1 or p.l1)) and p.x != 3)).
+
+Round 1: finished, need another round.
+
+Round 2: started.
+
+Round 2: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.y = 3 and p.y3 [marker predicate]
+Backward controlled-behavior: p.y = 3 and p.y3 -> (p.x = 0 or p.x = 2) and (p.y = 3 and p.y3) or p.x = 1 and (p.y = 3 and p.y3) [restricted to current/previous controlled-behavior predicate: (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.l1))) and (p.x = 1 or p.x = 3 or (p.y != 1 or p.l1)) and ((p.x != 1 or p.y = 1 or (p.y = 3 or p.l1)) and ((p.x != 1 or (p.y != 1 or p.l1)) and p.x != 3))]
+Backward reachability: iteration 1.
+Backward controlled-behavior: (p.x = 0 or p.x = 2) and (p.y = 3 and p.y3) or p.x = 1 and (p.y = 3 and p.y3) -> p.x = 0 and ((p.y = 0 or p.y = 2) and p.l1) or (p.x = 0 and (p.y = 1 and p.l1) or p.x = 0 and p.y = 3) or (p.x = 2 and (p.y = 3 and p.y3) or p.x = 1 and ((p.y = 0 or p.y = 2) and p.l1) or (p.x = 1 and (p.y = 1 and p.l1) or p.x = 1 and p.y = 3)) [backward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 1) and p.l1) (assignments: p.y := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.l1))) and (p.x = 1 or p.x = 3 or (p.y != 1 or p.l1)) and ((p.x != 1 or p.y = 1 or (p.y = 3 or p.l1)) and ((p.x != 1 or (p.y != 1 or p.l1)) and p.x != 3))]
+Backward controlled-behavior: p.x = 0 and ((p.y = 0 or p.y = 2) and p.l1) or (p.x = 0 and (p.y = 1 and p.l1) or p.x = 0 and p.y = 3) or (p.x = 2 and (p.y = 3 and p.y3) or p.x = 1 and ((p.y = 0 or p.y = 2) and p.l1) or (p.x = 1 and (p.y = 1 and p.l1) or p.x = 1 and p.y = 3)) -> (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.l1))) and (p.x = 1 or p.x = 3 or (p.y != 1 or p.l1)) and ((p.x != 1 or p.y = 1 or (p.y = 3 or p.l1)) and ((p.x != 1 or (p.y != 1 or p.l1)) and p.x != 3)) [backward reach with edge: (event: e) (guard: p.x = 2 and p.l1 or p.x = 1 and p.l1) (assignments: p.y := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.l1))) and (p.x = 1 or p.x = 3 or (p.y != 1 or p.l1)) and ((p.x != 1 or p.y = 1 or (p.y = 3 or p.l1)) and ((p.x != 1 or (p.y != 1 or p.l1)) and p.x != 3))]
+Backward reachability: iteration 2.
+Backward controlled-behavior: (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.l1))) and (p.x = 1 or p.x = 3 or (p.y != 1 or p.l1)) and ((p.x != 1 or p.y = 1 or (p.y = 3 or p.l1)) and ((p.x != 1 or (p.y != 1 or p.l1)) and p.x != 3)) [fixed point].
+
+Round 2: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.x = 0 or p.x = 2) and ((p.y = 0 or p.y = 2) and p.y3) or (p.x = 0 or p.x = 2) and (p.y = 1 and p.y3) or (p.x = 1 and ((p.y = 0 or p.y = 2) and p.y3) or (p.x = 1 and (p.y = 1 and p.y3) or p.x = 3)) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 2: finished, controlled behavior is stable.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.l1))) and (p.x = 1 or p.x = 3 or (p.y != 1 or p.l1)) and ((p.x != 1 or p.y = 1 or (p.y = 3 or p.l1)) and ((p.x != 1 or (p.y != 1 or p.l1)) and p.x != 3)))
+    Edge: (event: e) (guard: (p.x = 0 or p.x = 1) and p.l1) (assignments: p.y := 3, p := p.y3)
+    Edge: (event: e) (guard: p.x = 2 and p.l1 or p.x = 1 and p.l1) (assignments: p.y := 3, p := p.y3)
+
+Controlled system:                     exactly 15 states.
+
+Initial (synthesis result):            (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.l1))) and (p.x = 1 or p.x = 3 or (p.y != 1 or p.l1)) and ((p.x != 1 or p.y = 1 or (p.y = 3 or p.l1)) and ((p.x != 1 or (p.y != 1 or p.l1)) and p.x != 3))
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           (p.x = 0 or p.x = 2) and p.l1 or p.x = 1 and p.l1
+Initial (removed by supervisor):       p.x = 3 and p.l1
+Initial (added by supervisor):         p.x != 3 or p.y3
+
+Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
+  Initial: (p.x = 0 or p.x = 2) and p.l1 or p.x = 1 and p.l1 -> p.x != 3 [assume p.l1].
+
+Constructing output CIF specification.
+Writing output CIF file "datasynth/edge_granularity_guards_updates5_per_edge.ctrlsys.real.cif".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates5_per_edge.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates5_per_edge.ctrlsys.cif
new file mode 100644
index 0000000000000000000000000000000000000000..fcb4c3b0c4e62b72477676fca40153c866b26965
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates5_per_edge.ctrlsys.cif
@@ -0,0 +1,18 @@
+uncontrollable e;
+plant automaton p:
+  disc int[0..3] x in any;
+  disc int[0..3] y in any;
+  location l1:
+    initial;
+    edge e when x = 0 or x = 1 do y := 3 goto y3;
+    edge e when x = 1 or x = 2 do y := 3 goto y3;
+  location y3:
+    marked y = 3;
+end
+supervisor automaton sup:
+  alphabet;
+  initial p.x != 3;
+  location:
+    initial;
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates5_per_edge.statespace.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates5_per_edge.statespace.cif
new file mode 100644
index 0000000000000000000000000000000000000000..47079b18b46b703fe1c45b6b5e20f6cedbd72a36
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates5_per_edge.statespace.cif
@@ -0,0 +1,46 @@
+uncontrollable e;
+automaton statespace:
+  alphabet e;
+  location loc1:
+    initial;
+    edge e goto loc13;
+  location loc2:
+    initial;
+    edge e goto loc13;
+  location loc3:
+    initial;
+    edge e goto loc13;
+  location loc4:
+    initial;
+    edge e goto loc13;
+  location loc5:
+    initial;
+    edge e goto loc14;
+  location loc6:
+    initial;
+    edge e goto loc14;
+  location loc7:
+    initial;
+    edge e goto loc14;
+  location loc8:
+    initial;
+    edge e goto loc14;
+  location loc9:
+    initial;
+    edge e goto loc15;
+  location loc10:
+    initial;
+    edge e goto loc15;
+  location loc11:
+    initial;
+    edge e goto loc15;
+  location loc12:
+    initial;
+    edge e goto loc15;
+  location loc13:
+    marked;
+  location loc14:
+    marked;
+  location loc15:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates5_per_event.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates5_per_event.cif
new file mode 100644
index 0000000000000000000000000000000000000000..11dd44b90bd4f4b3fca97c765506d5f39d472aba
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates5_per_event.cif
@@ -0,0 +1,29 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..3] x in any;
+  disc int[0..3] y in any;
+
+  location l1: // x in {0, 1, 2}, y in any
+    initial;
+
+    // Partially overlapping guards, same updates.
+    edge e when x = 0 or x = 1 do y := 3 goto y3;
+    edge e when x = 1 or x = 2 do y := 3 goto y3;
+
+  location y3: // x in {0, 1, 2}, y = 3
+    marked y = 3;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates5_per_event.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates5_per_event.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..4c0ede2ee120b8e5f5cd9d43d94b790af6b50b7d
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates5_per_event.cif.out
@@ -0,0 +1,223 @@
+Reading CIF file "datasynth/edge_granularity_guards_updates5_per_event.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      1 * 2     2 * 2       2 * 2       100%
+  2      discrete variable  int[0..3]  p.x   1      2 * 2     4 * 2       4 * 2       100%
+  3      discrete variable  int[0..3]  p.y   2      2 * 2     4 * 2       4 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      3      10        20          20          100%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 7
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 3
+
+        Total span:   2 (total)   0.29 (avg/edge) / WES:   0.444444 (total)   0.063492 (avg/edge) [before]
+        Total span:   2 (total)   0.29 (avg/edge) / WES:   0.444444 (total)   0.063492 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 3
+
+        Total span:   2 (total)   0.29 (avg/edge) / WES:   0.444444 (total)   0.063492 (avg/edge) [before]
+        Total span:   2 (total)   0.29 (avg/edge) / WES:   0.507937 (total)   0.072562 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 3
+
+          Total span:   2 (total)   0.29 (avg/edge) / WES:   0.444444 (total)   0.063492 (avg/edge) [before]
+          Total span:   2 (total)   0.29 (avg/edge) / WES:   0.444444 (total)   0.063492 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 7
+
+          Total span:   2 (total)   0.29 (avg/edge) / WES:   0.444444 (total)   0.063492 (avg/edge) [before]
+          Total span:   2 (total)   0.29 (avg/edge) / WES:   0.444444 (total)   0.063492 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 3
+
+          Total span:   2 (total)   0.29 (avg/edge) / WES:   0.444444 (total)   0.063492 (avg/edge) [before]
+          Total span:   2 (total)   0.29 (avg/edge) / WES:   0.507937 (total)   0.072562 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 7
+
+          Total span:   2 (total)   0.29 (avg/edge) / WES:   0.507937 (total)   0.072562 (avg/edge) [before]
+          Total span:   2 (total)   0.29 (avg/edge) / WES:   0.507937 (total)   0.072562 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 20
+
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [before]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [iteration 1]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 3
+
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [before]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..3]  p.x   0      2 * 2     4 * 2       4 * 2       100%
+  2      discrete variable  int[0..3]  p.y   1      2 * 2     4 * 2       4 * 2       100%
+  3      location pointer   n/a        p     2      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      3      10        20          20          100%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variable 1):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.y = 3 and p.y3
+Marked    (auts/locs marker predicate):      p.y = 3 and p.y3
+Marked    (uncontrolled system):             p.y = 3 and p.y3
+Marked    (system, combined mark/plant inv): p.y = 3 and p.y3
+Marked    (system, combined mark/state inv): p.y = 3 and p.y3
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: (p.x = 0 or p.x = 2) and p.l1 or p.x = 1 and p.l1) (assignments: p.y := 3, p := p.y3 / p.y := 3, p := p.y3)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.y = 3 and p.y3 [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.y = 3 and p.y3 -> (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.l1))) and ((p.x = 1 or p.x = 3 or (p.y != 1 or p.l1)) and (p.x != 1 or p.y = 1 or (p.y = 3 or p.l1))) and ((p.x != 1 or (p.y != 1 or p.l1)) and (p.x != 3 or (p.y = 1 or p.y = 3)) and ((p.x != 3 or p.y != 1) and (p.x != 3 or (p.y != 3 or p.y3)))) [backward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 2) and p.l1 or p.x = 1 and p.l1) (assignments: p.y := 3, p := p.y3 / p.y := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 2.
+Backward controlled-behavior: (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.l1))) and ((p.x = 1 or p.x = 3 or (p.y != 1 or p.l1)) and (p.x != 1 or p.y = 1 or (p.y = 3 or p.l1))) and ((p.x != 1 or (p.y != 1 or p.l1)) and (p.x != 3 or (p.y = 1 or p.y = 3)) and ((p.x != 3 or p.y != 1) and (p.x != 3 or (p.y != 3 or p.y3)))) [fixed point].
+Controlled behavior: true -> (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.l1))) and ((p.x = 1 or p.x = 3 or (p.y != 1 or p.l1)) and (p.x != 1 or p.y = 1 or (p.y = 3 or p.l1))) and ((p.x != 1 or (p.y != 1 or p.l1)) and (p.x != 3 or (p.y = 1 or p.y = 3)) and ((p.x != 3 or p.y != 1) and (p.x != 3 or (p.y != 3 or p.y3)))).
+
+Round 1: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.y3))) and ((p.x = 1 or p.x = 3 or (p.y != 1 or p.y3)) and (p.x = 1 or (p.x = 3 or p.y != 3))) and ((p.x != 1 or p.y = 1 or (p.y = 3 or p.y3)) and (p.x != 1 or (p.y != 1 or p.y3)) and ((p.x != 1 or p.y != 3) and (p.x != 3 or (p.y != 3 or p.l1)))) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 1: computing forward controlled-behavior predicate.
+Forward controlled-behavior: p.l1 [initialization predicate]
+Forward controlled-behavior: p.l1 -> (p.x = 0 or p.x = 2) and p.l1 or p.x = 1 and p.l1 [restricted to current/previous controlled-behavior predicate: (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.l1))) and ((p.x = 1 or p.x = 3 or (p.y != 1 or p.l1)) and (p.x != 1 or p.y = 1 or (p.y = 3 or p.l1))) and ((p.x != 1 or (p.y != 1 or p.l1)) and (p.x != 3 or (p.y = 1 or p.y = 3)) and ((p.x != 3 or p.y != 1) and (p.x != 3 or (p.y != 3 or p.y3))))]
+Forward reachability: iteration 1.
+Forward controlled-behavior: (p.x = 0 or p.x = 2) and p.l1 or p.x = 1 and p.l1 -> (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.l1))) and (p.x = 1 or p.x = 3 or (p.y != 1 or p.l1)) and ((p.x != 1 or p.y = 1 or (p.y = 3 or p.l1)) and ((p.x != 1 or (p.y != 1 or p.l1)) and p.x != 3)) [forward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 2) and p.l1 or p.x = 1 and p.l1) (assignments: p.y := 3, p := p.y3 / p.y := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.l1))) and ((p.x = 1 or p.x = 3 or (p.y != 1 or p.l1)) and (p.x != 1 or p.y = 1 or (p.y = 3 or p.l1))) and ((p.x != 1 or (p.y != 1 or p.l1)) and (p.x != 3 or (p.y = 1 or p.y = 3)) and ((p.x != 3 or p.y != 1) and (p.x != 3 or (p.y != 3 or p.y3))))]
+Forward reachability: iteration 2.
+Forward controlled-behavior: (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.l1))) and (p.x = 1 or p.x = 3 or (p.y != 1 or p.l1)) and ((p.x != 1 or p.y = 1 or (p.y = 3 or p.l1)) and ((p.x != 1 or (p.y != 1 or p.l1)) and p.x != 3)) [fixed point].
+Controlled behavior: (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.l1))) and ((p.x = 1 or p.x = 3 or (p.y != 1 or p.l1)) and (p.x != 1 or p.y = 1 or (p.y = 3 or p.l1))) and ((p.x != 1 or (p.y != 1 or p.l1)) and (p.x != 3 or (p.y = 1 or p.y = 3)) and ((p.x != 3 or p.y != 1) and (p.x != 3 or (p.y != 3 or p.y3)))) -> (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.l1))) and (p.x = 1 or p.x = 3 or (p.y != 1 or p.l1)) and ((p.x != 1 or p.y = 1 or (p.y = 3 or p.l1)) and ((p.x != 1 or (p.y != 1 or p.l1)) and p.x != 3)).
+
+Round 1: finished, need another round.
+
+Round 2: started.
+
+Round 2: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.y = 3 and p.y3 [marker predicate]
+Backward controlled-behavior: p.y = 3 and p.y3 -> (p.x = 0 or p.x = 2) and (p.y = 3 and p.y3) or p.x = 1 and (p.y = 3 and p.y3) [restricted to current/previous controlled-behavior predicate: (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.l1))) and (p.x = 1 or p.x = 3 or (p.y != 1 or p.l1)) and ((p.x != 1 or p.y = 1 or (p.y = 3 or p.l1)) and ((p.x != 1 or (p.y != 1 or p.l1)) and p.x != 3))]
+Backward reachability: iteration 1.
+Backward controlled-behavior: (p.x = 0 or p.x = 2) and (p.y = 3 and p.y3) or p.x = 1 and (p.y = 3 and p.y3) -> (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.l1))) and (p.x = 1 or p.x = 3 or (p.y != 1 or p.l1)) and ((p.x != 1 or p.y = 1 or (p.y = 3 or p.l1)) and ((p.x != 1 or (p.y != 1 or p.l1)) and p.x != 3)) [backward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 2) and p.l1 or p.x = 1 and p.l1) (assignments: p.y := 3, p := p.y3 / p.y := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.l1))) and (p.x = 1 or p.x = 3 or (p.y != 1 or p.l1)) and ((p.x != 1 or p.y = 1 or (p.y = 3 or p.l1)) and ((p.x != 1 or (p.y != 1 or p.l1)) and p.x != 3))]
+Backward reachability: iteration 2.
+Backward controlled-behavior: (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.l1))) and (p.x = 1 or p.x = 3 or (p.y != 1 or p.l1)) and ((p.x != 1 or p.y = 1 or (p.y = 3 or p.l1)) and ((p.x != 1 or (p.y != 1 or p.l1)) and p.x != 3)) [fixed point].
+
+Round 2: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.x = 0 or p.x = 2) and ((p.y = 0 or p.y = 2) and p.y3) or (p.x = 0 or p.x = 2) and (p.y = 1 and p.y3) or (p.x = 1 and ((p.y = 0 or p.y = 2) and p.y3) or (p.x = 1 and (p.y = 1 and p.y3) or p.x = 3)) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 2: finished, controlled behavior is stable.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.l1))) and (p.x = 1 or p.x = 3 or (p.y != 1 or p.l1)) and ((p.x != 1 or p.y = 1 or (p.y = 3 or p.l1)) and ((p.x != 1 or (p.y != 1 or p.l1)) and p.x != 3)))
+    Edge: (event: e) (guard: (p.x = 0 or p.x = 2) and p.l1 or p.x = 1 and p.l1) (assignments: p.y := 3, p := p.y3 / p.y := 3, p := p.y3)
+
+Controlled system:                     exactly 15 states.
+
+Initial (synthesis result):            (p.x = 1 or p.x = 3 or (p.y = 1 or (p.y = 3 or p.l1))) and (p.x = 1 or p.x = 3 or (p.y != 1 or p.l1)) and ((p.x != 1 or p.y = 1 or (p.y = 3 or p.l1)) and ((p.x != 1 or (p.y != 1 or p.l1)) and p.x != 3))
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           (p.x = 0 or p.x = 2) and p.l1 or p.x = 1 and p.l1
+Initial (removed by supervisor):       p.x = 3 and p.l1
+Initial (added by supervisor):         p.x != 3 or p.y3
+
+Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
+  Initial: (p.x = 0 or p.x = 2) and p.l1 or p.x = 1 and p.l1 -> p.x != 3 [assume p.l1].
+
+Constructing output CIF specification.
+Writing output CIF file "datasynth/edge_granularity_guards_updates5_per_event.ctrlsys.real.cif".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates5_per_event.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates5_per_event.ctrlsys.cif
new file mode 100644
index 0000000000000000000000000000000000000000..fcb4c3b0c4e62b72477676fca40153c866b26965
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates5_per_event.ctrlsys.cif
@@ -0,0 +1,18 @@
+uncontrollable e;
+plant automaton p:
+  disc int[0..3] x in any;
+  disc int[0..3] y in any;
+  location l1:
+    initial;
+    edge e when x = 0 or x = 1 do y := 3 goto y3;
+    edge e when x = 1 or x = 2 do y := 3 goto y3;
+  location y3:
+    marked y = 3;
+end
+supervisor automaton sup:
+  alphabet;
+  initial p.x != 3;
+  location:
+    initial;
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates5_per_event.statespace.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates5_per_event.statespace.cif
new file mode 100644
index 0000000000000000000000000000000000000000..47079b18b46b703fe1c45b6b5e20f6cedbd72a36
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates5_per_event.statespace.cif
@@ -0,0 +1,46 @@
+uncontrollable e;
+automaton statespace:
+  alphabet e;
+  location loc1:
+    initial;
+    edge e goto loc13;
+  location loc2:
+    initial;
+    edge e goto loc13;
+  location loc3:
+    initial;
+    edge e goto loc13;
+  location loc4:
+    initial;
+    edge e goto loc13;
+  location loc5:
+    initial;
+    edge e goto loc14;
+  location loc6:
+    initial;
+    edge e goto loc14;
+  location loc7:
+    initial;
+    edge e goto loc14;
+  location loc8:
+    initial;
+    edge e goto loc14;
+  location loc9:
+    initial;
+    edge e goto loc15;
+  location loc10:
+    initial;
+    edge e goto loc15;
+  location loc11:
+    initial;
+    edge e goto loc15;
+  location loc12:
+    initial;
+    edge e goto loc15;
+  location loc13:
+    marked;
+  location loc14:
+    marked;
+  location loc15:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates6_per_edge.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates6_per_edge.cif
new file mode 100644
index 0000000000000000000000000000000000000000..bc54ce37ad70a9567f18f6c854e7ba577b293a20
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates6_per_edge.cif
@@ -0,0 +1,32 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..3] x in any;
+  disc int[0..3] y in any;
+
+  location l1: // x in {0, 2, 3}, y in any
+    initial;
+
+    // Partially overlapping guards, different updates.
+    edge e when x = 0 or x = 2 do y := 2 goto y2;
+    edge e when x = 2 or x = 3 do y := 3 goto y3;
+
+  location y2: // x in {0, 2}, y = 2
+    marked y = 2;
+
+  location y3: // x in {2, 3}, y = 3
+    marked y = 3;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates6_per_edge.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates6_per_edge.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..760a9285eb9df575991e16ee76f78d83dd337b90
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates6_per_edge.cif.out
@@ -0,0 +1,232 @@
+Reading CIF file "datasynth/edge_granularity_guards_updates6_per_edge.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      2 * 2     3 * 2       4 * 2       75%
+  2      discrete variable  int[0..3]  p.x   1      2 * 2     4 * 2       4 * 2       100%
+  3      discrete variable  int[0..3]  p.y   2      2 * 2     4 * 2       4 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      3      12        22          24          ~92%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 7
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 3
+
+        Total span:   2 (total)   0.29 (avg/edge) / WES:   0.444444 (total)   0.063492 (avg/edge) [before]
+        Total span:   2 (total)   0.29 (avg/edge) / WES:   0.444444 (total)   0.063492 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 3
+
+        Total span:   2 (total)   0.29 (avg/edge) / WES:   0.444444 (total)   0.063492 (avg/edge) [before]
+        Total span:   2 (total)   0.29 (avg/edge) / WES:   0.507937 (total)   0.072562 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 3
+
+          Total span:   2 (total)   0.29 (avg/edge) / WES:   0.444444 (total)   0.063492 (avg/edge) [before]
+          Total span:   2 (total)   0.29 (avg/edge) / WES:   0.444444 (total)   0.063492 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 7
+
+          Total span:   2 (total)   0.29 (avg/edge) / WES:   0.444444 (total)   0.063492 (avg/edge) [before]
+          Total span:   2 (total)   0.29 (avg/edge) / WES:   0.444444 (total)   0.063492 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 3
+
+          Total span:   2 (total)   0.29 (avg/edge) / WES:   0.444444 (total)   0.063492 (avg/edge) [before]
+          Total span:   2 (total)   0.29 (avg/edge) / WES:   0.507937 (total)   0.072562 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 7
+
+          Total span:   2 (total)   0.29 (avg/edge) / WES:   0.507937 (total)   0.072562 (avg/edge) [before]
+          Total span:   2 (total)   0.29 (avg/edge) / WES:   0.507937 (total)   0.072562 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 20
+
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [before]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [iteration 1]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 3
+
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [before]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..3]  p.x   0      2 * 2     4 * 2       4 * 2       100%
+  2      discrete variable  int[0..3]  p.y   1      2 * 2     4 * 2       4 * 2       100%
+  3      location pointer   n/a        p     2      2 * 2     3 * 2       4 * 2       75%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      3      12        22          24          ~92%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variable 1):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.y = 2 and p.y2 or p.y = 3 and p.y3
+Marked    (auts/locs marker predicate):      p.y = 2 and p.y2 or p.y = 3 and p.y3
+Marked    (uncontrolled system):             p.y = 2 and p.y2 or p.y = 3 and p.y3
+Marked    (system, combined mark/plant inv): p.y = 2 and p.y2 or p.y = 3 and p.y3
+Marked    (system, combined mark/state inv): p.y = 2 and p.y2 or p.y = 3 and p.y3
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: (p.x = 0 or p.x = 2) and p.l1) (assignments: p.y := 2, p := p.y2)
+    Edge: (event: e) (guard: (p.x = 2 or p.x = 3) and p.l1) (assignments: p.y := 3, p := p.y3)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Controlled behavior: true -> true [range: true, variable: location pointer for automaton "p" (group: 2, domain: 4+5, BDD variables: 2, CIF/BDD values: 3/4)].
+
+Extended controlled-behavior predicate using variable ranges: true.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.y = 2 and p.y2 or p.y = 3 and p.y3 [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.y = 2 and p.y2 or p.y = 3 and p.y3 -> (p.x = 0 or p.x = 2) and (p.y = 0 and p.l1) or ((p.x = 0 or p.x = 2) and (p.y = 2 and not p.y3) or (p.x = 0 or p.x = 2) and (p.y = 1 and p.l1)) or ((p.x = 0 or p.x = 2) and (p.y = 3 and not p.y2) or ((p.x = 1 or p.x = 3) and (p.y = 2 and p.y2) or (p.x = 1 or p.x = 3) and (p.y = 3 and p.y3))) [backward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 2) and p.l1) (assignments: p.y := 2, p := p.y2), restricted to current/previous controlled-behavior predicate: true]
+Backward controlled-behavior: (p.x = 0 or p.x = 2) and (p.y = 0 and p.l1) or ((p.x = 0 or p.x = 2) and (p.y = 2 and not p.y3) or (p.x = 0 or p.x = 2) and (p.y = 1 and p.l1)) or ((p.x = 0 or p.x = 2) and (p.y = 3 and not p.y2) or ((p.x = 1 or p.x = 3) and (p.y = 2 and p.y2) or (p.x = 1 or p.x = 3) and (p.y = 3 and p.y3))) -> (p.x = 0 or p.x = 2) and (p.y = 0 and p.l1) or (p.x = 0 or p.x = 2) and (p.y = 2 and not p.y3) or ((p.x = 0 or p.x = 2) and (p.y = 1 and p.l1) or ((p.x = 0 or p.x = 2) and (p.y = 3 and not p.y2) or p.x = 1 and (p.y = 2 and p.y2))) or (p.x = 1 and (p.y = 3 and p.y3) or p.x = 3 and (p.y = 0 and p.l1) or (p.x = 3 and (p.y = 2 and not p.y3) or (p.x = 3 and (p.y = 1 and p.l1) or p.x = 3 and (p.y = 3 and not p.y2)))) [backward reach with edge: (event: e) (guard: (p.x = 2 or p.x = 3) and p.l1) (assignments: p.y := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 2.
+Backward controlled-behavior: (p.x = 0 or p.x = 2) and (p.y = 0 and p.l1) or (p.x = 0 or p.x = 2) and (p.y = 2 and not p.y3) or ((p.x = 0 or p.x = 2) and (p.y = 1 and p.l1) or ((p.x = 0 or p.x = 2) and (p.y = 3 and not p.y2) or p.x = 1 and (p.y = 2 and p.y2))) or (p.x = 1 and (p.y = 3 and p.y3) or p.x = 3 and (p.y = 0 and p.l1) or (p.x = 3 and (p.y = 2 and not p.y3) or (p.x = 3 and (p.y = 1 and p.l1) or p.x = 3 and (p.y = 3 and not p.y2)))) [fixed point].
+Controlled behavior: true -> (p.x = 0 or p.x = 2) and (p.y = 0 and p.l1) or (p.x = 0 or p.x = 2) and (p.y = 2 and not p.y3) or ((p.x = 0 or p.x = 2) and (p.y = 1 and p.l1) or ((p.x = 0 or p.x = 2) and (p.y = 3 and not p.y2) or p.x = 1 and (p.y = 2 and p.y2))) or (p.x = 1 and (p.y = 3 and p.y3) or p.x = 3 and (p.y = 0 and p.l1) or (p.x = 3 and (p.y = 2 and not p.y3) or (p.x = 3 and (p.y = 1 and p.l1) or p.x = 3 and (p.y = 3 and not p.y2)))).
+
+Round 1: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.x = 1 or p.x = 3 or (p.y != 0 or not p.l1)) and (p.x = 1 or p.x = 3 or (p.y != 2 or p.y3)) and ((p.x = 1 or p.x = 3 or (p.y != 1 or not p.l1)) and ((p.x = 1 or p.x = 3 or (p.y != 3 or p.y2)) and (p.x != 1 or (p.y != 2 or not p.y2)))) and ((p.x != 1 or (p.y != 3 or not p.y3)) and (p.x != 3 or (p.y != 0 or not p.l1)) and ((p.x != 3 or (p.y != 2 or p.y3)) and ((p.x != 3 or (p.y != 1 or not p.l1)) and (p.x != 3 or (p.y != 3 or p.y2))))) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 1: computing forward controlled-behavior predicate.
+Forward controlled-behavior: p.l1 [initialization predicate]
+Forward controlled-behavior: p.l1 -> (p.x = 0 or p.x = 2) and p.l1 or p.x = 3 and p.l1 [restricted to current/previous controlled-behavior predicate: (p.x = 0 or p.x = 2) and (p.y = 0 and p.l1) or (p.x = 0 or p.x = 2) and (p.y = 2 and not p.y3) or ((p.x = 0 or p.x = 2) and (p.y = 1 and p.l1) or ((p.x = 0 or p.x = 2) and (p.y = 3 and not p.y2) or p.x = 1 and (p.y = 2 and p.y2))) or (p.x = 1 and (p.y = 3 and p.y3) or p.x = 3 and (p.y = 0 and p.l1) or (p.x = 3 and (p.y = 2 and not p.y3) or (p.x = 3 and (p.y = 1 and p.l1) or p.x = 3 and (p.y = 3 and not p.y2))))]
+Forward reachability: iteration 1.
+Forward controlled-behavior: (p.x = 0 or p.x = 2) and p.l1 or p.x = 3 and p.l1 -> (p.x = 0 or p.x = 2) and (p.y = 0 and p.l1) or (p.x = 0 or p.x = 2) and (p.y = 2 and not p.y3) or ((p.x = 0 or p.x = 2) and ((p.y = 1 or p.y = 3) and p.l1) or p.x = 3 and p.l1) [forward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 2) and p.l1) (assignments: p.y := 2, p := p.y2), restricted to current/previous controlled-behavior predicate: (p.x = 0 or p.x = 2) and (p.y = 0 and p.l1) or (p.x = 0 or p.x = 2) and (p.y = 2 and not p.y3) or ((p.x = 0 or p.x = 2) and (p.y = 1 and p.l1) or ((p.x = 0 or p.x = 2) and (p.y = 3 and not p.y2) or p.x = 1 and (p.y = 2 and p.y2))) or (p.x = 1 and (p.y = 3 and p.y3) or p.x = 3 and (p.y = 0 and p.l1) or (p.x = 3 and (p.y = 2 and not p.y3) or (p.x = 3 and (p.y = 1 and p.l1) or p.x = 3 and (p.y = 3 and not p.y2))))]
+Forward controlled-behavior: (p.x = 0 or p.x = 2) and (p.y = 0 and p.l1) or (p.x = 0 or p.x = 2) and (p.y = 2 and not p.y3) or ((p.x = 0 or p.x = 2) and ((p.y = 1 or p.y = 3) and p.l1) or p.x = 3 and p.l1) -> p.x = 0 and (p.y = 0 and p.l1) or p.x = 0 and (p.y = 2 and not p.y3) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or (p.x = 2 and (p.y = 0 and p.l1) or p.x = 2 and (p.y = 2 and not p.y3))) or (p.x = 2 and (p.y = 1 and p.l1) or p.x = 2 and (p.y = 3 and not p.y2) or (p.x = 3 and ((p.y = 0 or p.y = 2) and p.l1) or (p.x = 3 and (p.y = 1 and p.l1) or p.x = 3 and (p.y = 3 and not p.y2)))) [forward reach with edge: (event: e) (guard: (p.x = 2 or p.x = 3) and p.l1) (assignments: p.y := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: (p.x = 0 or p.x = 2) and (p.y = 0 and p.l1) or (p.x = 0 or p.x = 2) and (p.y = 2 and not p.y3) or ((p.x = 0 or p.x = 2) and (p.y = 1 and p.l1) or ((p.x = 0 or p.x = 2) and (p.y = 3 and not p.y2) or p.x = 1 and (p.y = 2 and p.y2))) or (p.x = 1 and (p.y = 3 and p.y3) or p.x = 3 and (p.y = 0 and p.l1) or (p.x = 3 and (p.y = 2 and not p.y3) or (p.x = 3 and (p.y = 1 and p.l1) or p.x = 3 and (p.y = 3 and not p.y2))))]
+Forward reachability: iteration 2.
+Forward controlled-behavior: p.x = 0 and (p.y = 0 and p.l1) or p.x = 0 and (p.y = 2 and not p.y3) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or (p.x = 2 and (p.y = 0 and p.l1) or p.x = 2 and (p.y = 2 and not p.y3))) or (p.x = 2 and (p.y = 1 and p.l1) or p.x = 2 and (p.y = 3 and not p.y2) or (p.x = 3 and ((p.y = 0 or p.y = 2) and p.l1) or (p.x = 3 and (p.y = 1 and p.l1) or p.x = 3 and (p.y = 3 and not p.y2)))) [fixed point].
+Controlled behavior: (p.x = 0 or p.x = 2) and (p.y = 0 and p.l1) or (p.x = 0 or p.x = 2) and (p.y = 2 and not p.y3) or ((p.x = 0 or p.x = 2) and (p.y = 1 and p.l1) or ((p.x = 0 or p.x = 2) and (p.y = 3 and not p.y2) or p.x = 1 and (p.y = 2 and p.y2))) or (p.x = 1 and (p.y = 3 and p.y3) or p.x = 3 and (p.y = 0 and p.l1) or (p.x = 3 and (p.y = 2 and not p.y3) or (p.x = 3 and (p.y = 1 and p.l1) or p.x = 3 and (p.y = 3 and not p.y2)))) -> p.x = 0 and (p.y = 0 and p.l1) or p.x = 0 and (p.y = 2 and not p.y3) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or (p.x = 2 and (p.y = 0 and p.l1) or p.x = 2 and (p.y = 2 and not p.y3))) or (p.x = 2 and (p.y = 1 and p.l1) or p.x = 2 and (p.y = 3 and not p.y2) or (p.x = 3 and ((p.y = 0 or p.y = 2) and p.l1) or (p.x = 3 and (p.y = 1 and p.l1) or p.x = 3 and (p.y = 3 and not p.y2)))).
+
+Round 1: finished, need another round.
+
+Round 2: started.
+
+Round 2: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.y = 2 and p.y2 or p.y = 3 and p.y3 [marker predicate]
+Backward controlled-behavior: p.y = 2 and p.y2 or p.y = 3 and p.y3 -> p.x = 0 and (p.y = 2 and p.y2) or p.x = 2 and (p.y = 2 and p.y2) or (p.x = 2 and (p.y = 3 and p.y3) or p.x = 3 and (p.y = 3 and p.y3)) [restricted to current/previous controlled-behavior predicate: p.x = 0 and (p.y = 0 and p.l1) or p.x = 0 and (p.y = 2 and not p.y3) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or (p.x = 2 and (p.y = 0 and p.l1) or p.x = 2 and (p.y = 2 and not p.y3))) or (p.x = 2 and (p.y = 1 and p.l1) or p.x = 2 and (p.y = 3 and not p.y2) or (p.x = 3 and ((p.y = 0 or p.y = 2) and p.l1) or (p.x = 3 and (p.y = 1 and p.l1) or p.x = 3 and (p.y = 3 and not p.y2))))]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.x = 0 and (p.y = 2 and p.y2) or p.x = 2 and (p.y = 2 and p.y2) or (p.x = 2 and (p.y = 3 and p.y3) or p.x = 3 and (p.y = 3 and p.y3)) -> p.x = 0 and (p.y = 0 and p.l1) or p.x = 0 and (p.y = 2 and not p.y3) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or p.x = 2 and (p.y = 0 and p.l1)) or (p.x = 2 and (p.y = 2 and not p.y3) or p.x = 2 and (p.y = 1 and p.l1) or (p.x = 2 and (p.y = 3 and not p.y2) or p.x = 3 and (p.y = 3 and p.y3))) [backward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 2) and p.l1) (assignments: p.y := 2, p := p.y2), restricted to current/previous controlled-behavior predicate: p.x = 0 and (p.y = 0 and p.l1) or p.x = 0 and (p.y = 2 and not p.y3) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or (p.x = 2 and (p.y = 0 and p.l1) or p.x = 2 and (p.y = 2 and not p.y3))) or (p.x = 2 and (p.y = 1 and p.l1) or p.x = 2 and (p.y = 3 and not p.y2) or (p.x = 3 and ((p.y = 0 or p.y = 2) and p.l1) or (p.x = 3 and (p.y = 1 and p.l1) or p.x = 3 and (p.y = 3 and not p.y2))))]
+Backward controlled-behavior: p.x = 0 and (p.y = 0 and p.l1) or p.x = 0 and (p.y = 2 and not p.y3) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or p.x = 2 and (p.y = 0 and p.l1)) or (p.x = 2 and (p.y = 2 and not p.y3) or p.x = 2 and (p.y = 1 and p.l1) or (p.x = 2 and (p.y = 3 and not p.y2) or p.x = 3 and (p.y = 3 and p.y3))) -> p.x = 0 and (p.y = 0 and p.l1) or p.x = 0 and (p.y = 2 and not p.y3) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or (p.x = 2 and (p.y = 0 and p.l1) or p.x = 2 and (p.y = 2 and not p.y3))) or (p.x = 2 and (p.y = 1 and p.l1) or p.x = 2 and (p.y = 3 and not p.y2) or (p.x = 3 and ((p.y = 0 or p.y = 2) and p.l1) or (p.x = 3 and (p.y = 1 and p.l1) or p.x = 3 and (p.y = 3 and not p.y2)))) [backward reach with edge: (event: e) (guard: (p.x = 2 or p.x = 3) and p.l1) (assignments: p.y := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: p.x = 0 and (p.y = 0 and p.l1) or p.x = 0 and (p.y = 2 and not p.y3) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or (p.x = 2 and (p.y = 0 and p.l1) or p.x = 2 and (p.y = 2 and not p.y3))) or (p.x = 2 and (p.y = 1 and p.l1) or p.x = 2 and (p.y = 3 and not p.y2) or (p.x = 3 and ((p.y = 0 or p.y = 2) and p.l1) or (p.x = 3 and (p.y = 1 and p.l1) or p.x = 3 and (p.y = 3 and not p.y2))))]
+Backward reachability: iteration 2.
+Backward controlled-behavior: p.x = 0 and (p.y = 0 and p.l1) or p.x = 0 and (p.y = 2 and not p.y3) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or (p.x = 2 and (p.y = 0 and p.l1) or p.x = 2 and (p.y = 2 and not p.y3))) or (p.x = 2 and (p.y = 1 and p.l1) or p.x = 2 and (p.y = 3 and not p.y2) or (p.x = 3 and ((p.y = 0 or p.y = 2) and p.l1) or (p.x = 3 and (p.y = 1 and p.l1) or p.x = 3 and (p.y = 3 and not p.y2)))) [fixed point].
+
+Round 2: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.x != 0 or (p.y != 0 or not p.l1)) and (p.x != 0 or (p.y != 2 or p.y3)) and ((p.x != 0 or p.y = 0 or (p.y = 2 or not p.l1)) and ((p.x != 2 or (p.y != 0 or not p.l1)) and (p.x != 2 or (p.y != 2 or p.y3)))) and ((p.x != 2 or (p.y != 1 or not p.l1)) and (p.x != 2 or (p.y != 3 or p.y2)) and ((p.x != 3 or p.y = 1 or (p.y = 3 or not p.l1)) and ((p.x != 3 or (p.y != 1 or not p.l1)) and (p.x != 3 or (p.y != 3 or p.y2))))) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 2: finished, controlled behavior is stable.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: p.x = 0 and (p.y = 0 and p.l1) or p.x = 0 and (p.y = 2 and not p.y3) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or (p.x = 2 and (p.y = 0 and p.l1) or p.x = 2 and (p.y = 2 and not p.y3))) or (p.x = 2 and (p.y = 1 and p.l1) or p.x = 2 and (p.y = 3 and not p.y2) or (p.x = 3 and ((p.y = 0 or p.y = 2) and p.l1) or (p.x = 3 and (p.y = 1 and p.l1) or p.x = 3 and (p.y = 3 and not p.y2)))))
+    Edge: (event: e) (guard: (p.x = 0 or p.x = 2) and p.l1) (assignments: p.y := 2, p := p.y2)
+    Edge: (event: e) (guard: (p.x = 2 or p.x = 3) and p.l1) (assignments: p.y := 3, p := p.y3)
+
+Controlled system:                     exactly 16 states.
+
+Initial (synthesis result):            p.x = 0 and (p.y = 0 and p.l1) or p.x = 0 and (p.y = 2 and not p.y3) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or (p.x = 2 and (p.y = 0 and p.l1) or p.x = 2 and (p.y = 2 and not p.y3))) or (p.x = 2 and (p.y = 1 and p.l1) or p.x = 2 and (p.y = 3 and not p.y2) or (p.x = 3 and ((p.y = 0 or p.y = 2) and p.l1) or (p.x = 3 and (p.y = 1 and p.l1) or p.x = 3 and (p.y = 3 and not p.y2))))
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           (p.x = 0 or p.x = 2) and p.l1 or p.x = 3 and p.l1
+Initial (removed by supervisor):       p.x = 1 and p.l1
+Initial (added by supervisor):         p.x != 1 or not p.l1
+
+Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
+  Initial: (p.x = 0 or p.x = 2) and p.l1 or p.x = 3 and p.l1 -> p.x != 1 [assume p.l1].
+
+Constructing output CIF specification.
+Writing output CIF file "datasynth/edge_granularity_guards_updates6_per_edge.ctrlsys.real.cif".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates6_per_edge.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates6_per_edge.ctrlsys.cif
new file mode 100644
index 0000000000000000000000000000000000000000..2b53618e23e7ff18bab98e575f0fda4f8e2eca93
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates6_per_edge.ctrlsys.cif
@@ -0,0 +1,20 @@
+uncontrollable e;
+plant automaton p:
+  disc int[0..3] x in any;
+  disc int[0..3] y in any;
+  location l1:
+    initial;
+    edge e when x = 0 or x = 2 do y := 2 goto y2;
+    edge e when x = 2 or x = 3 do y := 3 goto y3;
+  location y2:
+    marked y = 2;
+  location y3:
+    marked y = 3;
+end
+supervisor automaton sup:
+  alphabet;
+  initial p.x != 1;
+  location:
+    initial;
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates6_per_edge.statespace.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates6_per_edge.statespace.cif
new file mode 100644
index 0000000000000000000000000000000000000000..6627723264988d59240dfad74c250e33f69ea17d
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates6_per_edge.statespace.cif
@@ -0,0 +1,52 @@
+uncontrollable e;
+automaton statespace:
+  alphabet e;
+  location loc1:
+    initial;
+    edge e goto loc13;
+  location loc2:
+    initial;
+    edge e goto loc13;
+  location loc3:
+    initial;
+    edge e goto loc13;
+  location loc4:
+    initial;
+    edge e goto loc13;
+  location loc5:
+    initial;
+    edge e goto loc14;
+    edge e goto loc15;
+  location loc6:
+    initial;
+    edge e goto loc14;
+    edge e goto loc15;
+  location loc7:
+    initial;
+    edge e goto loc14;
+    edge e goto loc15;
+  location loc8:
+    initial;
+    edge e goto loc14;
+    edge e goto loc15;
+  location loc9:
+    initial;
+    edge e goto loc16;
+  location loc10:
+    initial;
+    edge e goto loc16;
+  location loc11:
+    initial;
+    edge e goto loc16;
+  location loc12:
+    initial;
+    edge e goto loc16;
+  location loc13:
+    marked;
+  location loc14:
+    marked;
+  location loc15:
+    marked;
+  location loc16:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates6_per_event.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates6_per_event.cif
new file mode 100644
index 0000000000000000000000000000000000000000..bc54ce37ad70a9567f18f6c854e7ba577b293a20
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates6_per_event.cif
@@ -0,0 +1,32 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..3] x in any;
+  disc int[0..3] y in any;
+
+  location l1: // x in {0, 2, 3}, y in any
+    initial;
+
+    // Partially overlapping guards, different updates.
+    edge e when x = 0 or x = 2 do y := 2 goto y2;
+    edge e when x = 2 or x = 3 do y := 3 goto y3;
+
+  location y2: // x in {0, 2}, y = 2
+    marked y = 2;
+
+  location y3: // x in {2, 3}, y = 3
+    marked y = 3;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates6_per_event.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates6_per_event.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..d3abe089c57161ef869540fdce193bcc0086d0d2
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates6_per_event.cif.out
@@ -0,0 +1,227 @@
+Reading CIF file "datasynth/edge_granularity_guards_updates6_per_event.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      2 * 2     3 * 2       4 * 2       75%
+  2      discrete variable  int[0..3]  p.x   1      2 * 2     4 * 2       4 * 2       100%
+  3      discrete variable  int[0..3]  p.y   2      2 * 2     4 * 2       4 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      3      12        22          24          ~92%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 7
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 3
+
+        Total span:   2 (total)   0.29 (avg/edge) / WES:   0.444444 (total)   0.063492 (avg/edge) [before]
+        Total span:   2 (total)   0.29 (avg/edge) / WES:   0.444444 (total)   0.063492 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 3
+
+        Total span:   2 (total)   0.29 (avg/edge) / WES:   0.444444 (total)   0.063492 (avg/edge) [before]
+        Total span:   2 (total)   0.29 (avg/edge) / WES:   0.507937 (total)   0.072562 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 3
+
+          Total span:   2 (total)   0.29 (avg/edge) / WES:   0.444444 (total)   0.063492 (avg/edge) [before]
+          Total span:   2 (total)   0.29 (avg/edge) / WES:   0.444444 (total)   0.063492 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 7
+
+          Total span:   2 (total)   0.29 (avg/edge) / WES:   0.444444 (total)   0.063492 (avg/edge) [before]
+          Total span:   2 (total)   0.29 (avg/edge) / WES:   0.444444 (total)   0.063492 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 3
+
+          Total span:   2 (total)   0.29 (avg/edge) / WES:   0.444444 (total)   0.063492 (avg/edge) [before]
+          Total span:   2 (total)   0.29 (avg/edge) / WES:   0.507937 (total)   0.072562 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 7
+
+          Total span:   2 (total)   0.29 (avg/edge) / WES:   0.507937 (total)   0.072562 (avg/edge) [before]
+          Total span:   2 (total)   0.29 (avg/edge) / WES:   0.507937 (total)   0.072562 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Maximum number of iterations: 20
+
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [before]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [iteration 1]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 2
+      Window length: 3
+
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [before]
+      Total span:   4 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.666667 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..3]  p.x   0      2 * 2     4 * 2       4 * 2       100%
+  2      discrete variable  int[0..3]  p.y   1      2 * 2     4 * 2       4 * 2       100%
+  3      location pointer   n/a        p     2      2 * 2     3 * 2       4 * 2       75%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      3      12        22          24          ~92%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variable 1):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.y = 2 and p.y2 or p.y = 3 and p.y3
+Marked    (auts/locs marker predicate):      p.y = 2 and p.y2 or p.y = 3 and p.y3
+Marked    (uncontrolled system):             p.y = 2 and p.y2 or p.y = 3 and p.y3
+Marked    (system, combined mark/plant inv): p.y = 2 and p.y2 or p.y = 3 and p.y3
+Marked    (system, combined mark/state inv): p.y = 2 and p.y2 or p.y = 3 and p.y3
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: (p.x = 0 or p.x = 2) and p.l1 or p.x = 3 and p.l1) (assignments: p.y := 2, p := p.y2 / p.y := 3, p := p.y3)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Controlled behavior: true -> true [range: true, variable: location pointer for automaton "p" (group: 2, domain: 4+5, BDD variables: 2, CIF/BDD values: 3/4)].
+
+Extended controlled-behavior predicate using variable ranges: true.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.y = 2 and p.y2 or p.y = 3 and p.y3 [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.y = 2 and p.y2 or p.y = 3 and p.y3 -> (p.x = 0 or p.x = 2) and (p.y = 0 and p.l1) or (p.x = 0 or p.x = 2) and (p.y = 2 and not p.y3) or ((p.x = 0 or p.x = 2) and (p.y = 1 and p.l1) or ((p.x = 0 or p.x = 2) and (p.y = 3 and not p.y2) or p.x = 1 and (p.y = 2 and p.y2))) or (p.x = 1 and (p.y = 3 and p.y3) or p.x = 3 and (p.y = 0 and p.l1) or (p.x = 3 and (p.y = 2 and not p.y3) or (p.x = 3 and (p.y = 1 and p.l1) or p.x = 3 and (p.y = 3 and not p.y2)))) [backward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 2) and p.l1 or p.x = 3 and p.l1) (assignments: p.y := 2, p := p.y2 / p.y := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 2.
+Backward controlled-behavior: (p.x = 0 or p.x = 2) and (p.y = 0 and p.l1) or (p.x = 0 or p.x = 2) and (p.y = 2 and not p.y3) or ((p.x = 0 or p.x = 2) and (p.y = 1 and p.l1) or ((p.x = 0 or p.x = 2) and (p.y = 3 and not p.y2) or p.x = 1 and (p.y = 2 and p.y2))) or (p.x = 1 and (p.y = 3 and p.y3) or p.x = 3 and (p.y = 0 and p.l1) or (p.x = 3 and (p.y = 2 and not p.y3) or (p.x = 3 and (p.y = 1 and p.l1) or p.x = 3 and (p.y = 3 and not p.y2)))) [fixed point].
+Controlled behavior: true -> (p.x = 0 or p.x = 2) and (p.y = 0 and p.l1) or (p.x = 0 or p.x = 2) and (p.y = 2 and not p.y3) or ((p.x = 0 or p.x = 2) and (p.y = 1 and p.l1) or ((p.x = 0 or p.x = 2) and (p.y = 3 and not p.y2) or p.x = 1 and (p.y = 2 and p.y2))) or (p.x = 1 and (p.y = 3 and p.y3) or p.x = 3 and (p.y = 0 and p.l1) or (p.x = 3 and (p.y = 2 and not p.y3) or (p.x = 3 and (p.y = 1 and p.l1) or p.x = 3 and (p.y = 3 and not p.y2)))).
+
+Round 1: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.x = 1 or p.x = 3 or (p.y != 0 or not p.l1)) and (p.x = 1 or p.x = 3 or (p.y != 2 or p.y3)) and ((p.x = 1 or p.x = 3 or (p.y != 1 or not p.l1)) and ((p.x = 1 or p.x = 3 or (p.y != 3 or p.y2)) and (p.x != 1 or (p.y != 2 or not p.y2)))) and ((p.x != 1 or (p.y != 3 or not p.y3)) and (p.x != 3 or (p.y != 0 or not p.l1)) and ((p.x != 3 or (p.y != 2 or p.y3)) and ((p.x != 3 or (p.y != 1 or not p.l1)) and (p.x != 3 or (p.y != 3 or p.y2))))) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 1: computing forward controlled-behavior predicate.
+Forward controlled-behavior: p.l1 [initialization predicate]
+Forward controlled-behavior: p.l1 -> (p.x = 0 or p.x = 2) and p.l1 or p.x = 3 and p.l1 [restricted to current/previous controlled-behavior predicate: (p.x = 0 or p.x = 2) and (p.y = 0 and p.l1) or (p.x = 0 or p.x = 2) and (p.y = 2 and not p.y3) or ((p.x = 0 or p.x = 2) and (p.y = 1 and p.l1) or ((p.x = 0 or p.x = 2) and (p.y = 3 and not p.y2) or p.x = 1 and (p.y = 2 and p.y2))) or (p.x = 1 and (p.y = 3 and p.y3) or p.x = 3 and (p.y = 0 and p.l1) or (p.x = 3 and (p.y = 2 and not p.y3) or (p.x = 3 and (p.y = 1 and p.l1) or p.x = 3 and (p.y = 3 and not p.y2))))]
+Forward reachability: iteration 1.
+Forward controlled-behavior: (p.x = 0 or p.x = 2) and p.l1 or p.x = 3 and p.l1 -> p.x = 0 and (p.y = 0 and p.l1) or p.x = 0 and (p.y = 2 and not p.y3) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or (p.x = 2 and (p.y = 0 and p.l1) or p.x = 2 and (p.y = 2 and not p.y3))) or (p.x = 2 and (p.y = 1 and p.l1) or p.x = 2 and (p.y = 3 and not p.y2) or (p.x = 3 and ((p.y = 0 or p.y = 2) and p.l1) or (p.x = 3 and (p.y = 1 and p.l1) or p.x = 3 and (p.y = 3 and not p.y2)))) [forward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 2) and p.l1 or p.x = 3 and p.l1) (assignments: p.y := 2, p := p.y2 / p.y := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: (p.x = 0 or p.x = 2) and (p.y = 0 and p.l1) or (p.x = 0 or p.x = 2) and (p.y = 2 and not p.y3) or ((p.x = 0 or p.x = 2) and (p.y = 1 and p.l1) or ((p.x = 0 or p.x = 2) and (p.y = 3 and not p.y2) or p.x = 1 and (p.y = 2 and p.y2))) or (p.x = 1 and (p.y = 3 and p.y3) or p.x = 3 and (p.y = 0 and p.l1) or (p.x = 3 and (p.y = 2 and not p.y3) or (p.x = 3 and (p.y = 1 and p.l1) or p.x = 3 and (p.y = 3 and not p.y2))))]
+Forward reachability: iteration 2.
+Forward controlled-behavior: p.x = 0 and (p.y = 0 and p.l1) or p.x = 0 and (p.y = 2 and not p.y3) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or (p.x = 2 and (p.y = 0 and p.l1) or p.x = 2 and (p.y = 2 and not p.y3))) or (p.x = 2 and (p.y = 1 and p.l1) or p.x = 2 and (p.y = 3 and not p.y2) or (p.x = 3 and ((p.y = 0 or p.y = 2) and p.l1) or (p.x = 3 and (p.y = 1 and p.l1) or p.x = 3 and (p.y = 3 and not p.y2)))) [fixed point].
+Controlled behavior: (p.x = 0 or p.x = 2) and (p.y = 0 and p.l1) or (p.x = 0 or p.x = 2) and (p.y = 2 and not p.y3) or ((p.x = 0 or p.x = 2) and (p.y = 1 and p.l1) or ((p.x = 0 or p.x = 2) and (p.y = 3 and not p.y2) or p.x = 1 and (p.y = 2 and p.y2))) or (p.x = 1 and (p.y = 3 and p.y3) or p.x = 3 and (p.y = 0 and p.l1) or (p.x = 3 and (p.y = 2 and not p.y3) or (p.x = 3 and (p.y = 1 and p.l1) or p.x = 3 and (p.y = 3 and not p.y2)))) -> p.x = 0 and (p.y = 0 and p.l1) or p.x = 0 and (p.y = 2 and not p.y3) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or (p.x = 2 and (p.y = 0 and p.l1) or p.x = 2 and (p.y = 2 and not p.y3))) or (p.x = 2 and (p.y = 1 and p.l1) or p.x = 2 and (p.y = 3 and not p.y2) or (p.x = 3 and ((p.y = 0 or p.y = 2) and p.l1) or (p.x = 3 and (p.y = 1 and p.l1) or p.x = 3 and (p.y = 3 and not p.y2)))).
+
+Round 1: finished, need another round.
+
+Round 2: started.
+
+Round 2: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.y = 2 and p.y2 or p.y = 3 and p.y3 [marker predicate]
+Backward controlled-behavior: p.y = 2 and p.y2 or p.y = 3 and p.y3 -> p.x = 0 and (p.y = 2 and p.y2) or p.x = 2 and (p.y = 2 and p.y2) or (p.x = 2 and (p.y = 3 and p.y3) or p.x = 3 and (p.y = 3 and p.y3)) [restricted to current/previous controlled-behavior predicate: p.x = 0 and (p.y = 0 and p.l1) or p.x = 0 and (p.y = 2 and not p.y3) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or (p.x = 2 and (p.y = 0 and p.l1) or p.x = 2 and (p.y = 2 and not p.y3))) or (p.x = 2 and (p.y = 1 and p.l1) or p.x = 2 and (p.y = 3 and not p.y2) or (p.x = 3 and ((p.y = 0 or p.y = 2) and p.l1) or (p.x = 3 and (p.y = 1 and p.l1) or p.x = 3 and (p.y = 3 and not p.y2))))]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.x = 0 and (p.y = 2 and p.y2) or p.x = 2 and (p.y = 2 and p.y2) or (p.x = 2 and (p.y = 3 and p.y3) or p.x = 3 and (p.y = 3 and p.y3)) -> p.x = 0 and (p.y = 0 and p.l1) or p.x = 0 and (p.y = 2 and not p.y3) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or (p.x = 2 and (p.y = 0 and p.l1) or p.x = 2 and (p.y = 2 and not p.y3))) or (p.x = 2 and (p.y = 1 and p.l1) or p.x = 2 and (p.y = 3 and not p.y2) or (p.x = 3 and ((p.y = 0 or p.y = 2) and p.l1) or (p.x = 3 and (p.y = 1 and p.l1) or p.x = 3 and (p.y = 3 and not p.y2)))) [backward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 2) and p.l1 or p.x = 3 and p.l1) (assignments: p.y := 2, p := p.y2 / p.y := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: p.x = 0 and (p.y = 0 and p.l1) or p.x = 0 and (p.y = 2 and not p.y3) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or (p.x = 2 and (p.y = 0 and p.l1) or p.x = 2 and (p.y = 2 and not p.y3))) or (p.x = 2 and (p.y = 1 and p.l1) or p.x = 2 and (p.y = 3 and not p.y2) or (p.x = 3 and ((p.y = 0 or p.y = 2) and p.l1) or (p.x = 3 and (p.y = 1 and p.l1) or p.x = 3 and (p.y = 3 and not p.y2))))]
+Backward reachability: iteration 2.
+Backward controlled-behavior: p.x = 0 and (p.y = 0 and p.l1) or p.x = 0 and (p.y = 2 and not p.y3) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or (p.x = 2 and (p.y = 0 and p.l1) or p.x = 2 and (p.y = 2 and not p.y3))) or (p.x = 2 and (p.y = 1 and p.l1) or p.x = 2 and (p.y = 3 and not p.y2) or (p.x = 3 and ((p.y = 0 or p.y = 2) and p.l1) or (p.x = 3 and (p.y = 1 and p.l1) or p.x = 3 and (p.y = 3 and not p.y2)))) [fixed point].
+
+Round 2: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p.x != 0 or (p.y != 0 or not p.l1)) and (p.x != 0 or (p.y != 2 or p.y3)) and ((p.x != 0 or p.y = 0 or (p.y = 2 or not p.l1)) and ((p.x != 2 or (p.y != 0 or not p.l1)) and (p.x != 2 or (p.y != 2 or p.y3)))) and ((p.x != 2 or (p.y != 1 or not p.l1)) and (p.x != 2 or (p.y != 3 or p.y2)) and ((p.x != 3 or p.y = 1 or (p.y = 3 or not p.l1)) and ((p.x != 3 or (p.y != 1 or not p.l1)) and (p.x != 3 or (p.y != 3 or p.y2))))) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 2: finished, controlled behavior is stable.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: p.x = 0 and (p.y = 0 and p.l1) or p.x = 0 and (p.y = 2 and not p.y3) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or (p.x = 2 and (p.y = 0 and p.l1) or p.x = 2 and (p.y = 2 and not p.y3))) or (p.x = 2 and (p.y = 1 and p.l1) or p.x = 2 and (p.y = 3 and not p.y2) or (p.x = 3 and ((p.y = 0 or p.y = 2) and p.l1) or (p.x = 3 and (p.y = 1 and p.l1) or p.x = 3 and (p.y = 3 and not p.y2)))))
+    Edge: (event: e) (guard: (p.x = 0 or p.x = 2) and p.l1 or p.x = 3 and p.l1) (assignments: p.y := 2, p := p.y2 / p.y := 3, p := p.y3)
+
+Controlled system:                     exactly 16 states.
+
+Initial (synthesis result):            p.x = 0 and (p.y = 0 and p.l1) or p.x = 0 and (p.y = 2 and not p.y3) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or (p.x = 2 and (p.y = 0 and p.l1) or p.x = 2 and (p.y = 2 and not p.y3))) or (p.x = 2 and (p.y = 1 and p.l1) or p.x = 2 and (p.y = 3 and not p.y2) or (p.x = 3 and ((p.y = 0 or p.y = 2) and p.l1) or (p.x = 3 and (p.y = 1 and p.l1) or p.x = 3 and (p.y = 3 and not p.y2))))
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           (p.x = 0 or p.x = 2) and p.l1 or p.x = 3 and p.l1
+Initial (removed by supervisor):       p.x = 1 and p.l1
+Initial (added by supervisor):         p.x != 1 or not p.l1
+
+Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
+  Initial: (p.x = 0 or p.x = 2) and p.l1 or p.x = 3 and p.l1 -> p.x != 1 [assume p.l1].
+
+Constructing output CIF specification.
+Writing output CIF file "datasynth/edge_granularity_guards_updates6_per_event.ctrlsys.real.cif".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates6_per_event.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates6_per_event.ctrlsys.cif
new file mode 100644
index 0000000000000000000000000000000000000000..2b53618e23e7ff18bab98e575f0fda4f8e2eca93
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates6_per_event.ctrlsys.cif
@@ -0,0 +1,20 @@
+uncontrollable e;
+plant automaton p:
+  disc int[0..3] x in any;
+  disc int[0..3] y in any;
+  location l1:
+    initial;
+    edge e when x = 0 or x = 2 do y := 2 goto y2;
+    edge e when x = 2 or x = 3 do y := 3 goto y3;
+  location y2:
+    marked y = 2;
+  location y3:
+    marked y = 3;
+end
+supervisor automaton sup:
+  alphabet;
+  initial p.x != 1;
+  location:
+    initial;
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates6_per_event.statespace.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates6_per_event.statespace.cif
new file mode 100644
index 0000000000000000000000000000000000000000..6627723264988d59240dfad74c250e33f69ea17d
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates6_per_event.statespace.cif
@@ -0,0 +1,52 @@
+uncontrollable e;
+automaton statespace:
+  alphabet e;
+  location loc1:
+    initial;
+    edge e goto loc13;
+  location loc2:
+    initial;
+    edge e goto loc13;
+  location loc3:
+    initial;
+    edge e goto loc13;
+  location loc4:
+    initial;
+    edge e goto loc13;
+  location loc5:
+    initial;
+    edge e goto loc14;
+    edge e goto loc15;
+  location loc6:
+    initial;
+    edge e goto loc14;
+    edge e goto loc15;
+  location loc7:
+    initial;
+    edge e goto loc14;
+    edge e goto loc15;
+  location loc8:
+    initial;
+    edge e goto loc14;
+    edge e goto loc15;
+  location loc9:
+    initial;
+    edge e goto loc16;
+  location loc10:
+    initial;
+    edge e goto loc16;
+  location loc11:
+    initial;
+    edge e goto loc16;
+  location loc12:
+    initial;
+    edge e goto loc16;
+  location loc13:
+    marked;
+  location loc14:
+    marked;
+  location loc15:
+    marked;
+  location loc16:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates7_per_edge.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates7_per_edge.cif
new file mode 100644
index 0000000000000000000000000000000000000000..44fc8dfd528c3ad6b0d0d3a22238bf44782b6a80
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates7_per_edge.cif
@@ -0,0 +1,42 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..3] x in any;
+  disc int[0..3] y in any;
+
+  location l1: // x in {0, 1, 2}, y in any
+    initial;
+
+    // Partially overlapping guards, different and same updates.
+    edge e when x = 0 or x = 1 do y := 0 goto y0;
+    edge e when x = 1 or x = 2 do y := 1 goto y1;
+    edge e when x = 0          do y := 0 goto y0;
+    edge e when x = 0          do y := 2 goto y2;
+    edge e when x = 1          do y := 1 goto y1;
+    edge e when x = 1          do y := 3 goto y3;
+
+  location y0: // x in {0, 1}, y = 0
+    marked y = 0;
+
+  location y1: // x in {1, 2}, y = 1
+    marked y = 1;
+
+  location y2: // x = 0, y = 2
+    marked y = 2;
+
+  location y3: // x = 1, y = 3
+    marked y = 3;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates7_per_edge.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates7_per_edge.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..f90bf67d6195e62c5187c298d76b6b7e84234d10
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates7_per_edge.cif.out
@@ -0,0 +1,242 @@
+Reading CIF file "datasynth/edge_granularity_guards_updates7_per_edge.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      3 * 2     5 * 2       8 * 2       ~63%
+  2      discrete variable  int[0..3]  p.x   1      2 * 2     4 * 2       4 * 2       100%
+  3      discrete variable  int[0..3]  p.y   2      2 * 2     4 * 2       4 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      3      14        26          32          ~81%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 15
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 3
+
+        Total span:   2 (total)   0.13 (avg/edge) / WES:   0.385185 (total)   0.025679 (avg/edge) [before]
+        Total span:   2 (total)   0.13 (avg/edge) / WES:   0.385185 (total)   0.025679 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 3
+
+        Total span:   2 (total)   0.13 (avg/edge) / WES:   0.385185 (total)   0.025679 (avg/edge) [before]
+        Total span:   2 (total)   0.13 (avg/edge) / WES:   0.414815 (total)   0.027654 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 3
+
+          Total span:   2 (total)   0.13 (avg/edge) / WES:   0.385185 (total)   0.025679 (avg/edge) [before]
+          Total span:   2 (total)   0.13 (avg/edge) / WES:   0.385185 (total)   0.025679 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 15
+
+          Total span:   2 (total)   0.13 (avg/edge) / WES:   0.385185 (total)   0.025679 (avg/edge) [before]
+          Total span:   2 (total)   0.13 (avg/edge) / WES:   0.385185 (total)   0.025679 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 3
+
+          Total span:   2 (total)   0.13 (avg/edge) / WES:   0.385185 (total)   0.025679 (avg/edge) [before]
+          Total span:   2 (total)   0.13 (avg/edge) / WES:   0.414815 (total)   0.027654 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 15
+
+          Total span:   2 (total)   0.13 (avg/edge) / WES:   0.414815 (total)   0.027654 (avg/edge) [before]
+          Total span:   2 (total)   0.13 (avg/edge) / WES:   0.414815 (total)   0.027654 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 6
+      Maximum number of iterations: 20
+
+      Total span:   12 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.222222 (avg/edge) [before]
+      Total span:   12 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.222222 (avg/edge) [iteration 1]
+      Total span:   12 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.222222 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 6
+      Window length: 3
+
+      Total span:   12 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.222222 (avg/edge) [before]
+      Total span:   12 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.222222 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..3]  p.x   0      2 * 2     4 * 2       4 * 2       100%
+  2      discrete variable  int[0..3]  p.y   1      2 * 2     4 * 2       4 * 2       100%
+  3      location pointer   n/a        p     2      3 * 2     5 * 2       8 * 2       ~63%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      3      14        26          32          ~81%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variable 1):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3)
+Marked    (auts/locs marker predicate):      p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3)
+Marked    (uncontrolled system):             p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3)
+Marked    (system, combined mark/plant inv): p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3)
+Marked    (system, combined mark/state inv): p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3)
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: (p.x = 0 or p.x = 1) and p.l1) (assignments: p.y := 0, p := p.y0)
+    Edge: (event: e) (guard: p.x = 2 and p.l1 or p.x = 1 and p.l1) (assignments: p.y := 1, p := p.y1)
+    Edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 0, p := p.y0)
+    Edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2)
+    Edge: (event: e) (guard: p.x = 1 and p.l1) (assignments: p.y := 1, p := p.y1)
+    Edge: (event: e) (guard: p.x = 1 and p.l1) (assignments: p.y := 3, p := p.y3)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Controlled behavior: true -> true [range: true, variable: location pointer for automaton "p" (group: 2, domain: 4+5, BDD variables: 3, CIF/BDD values: 5/8)].
+
+Extended controlled-behavior predicate using variable ranges: true.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3) [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3) -> (p.x = 0 or p.x = 1) and (p.y = 0 and (p.l1 or p.y0)) or (p.x = 0 or p.x = 1) and (p.y = 2 and p.l1) or ((p.x = 0 or p.x = 1) and (p.y = 2 and p.y2) or (p.x = 0 or p.x = 1) and (p.y = 1 and (p.l1 or p.y1))) or ((p.x = 0 or p.x = 1) and (p.y = 3 and (p.l1 or p.y3)) or (p.x = 2 or p.x = 3) and (p.y = 0 and p.y0) or ((p.x = 2 or p.x = 3) and (p.y = 2 and p.y2) or ((p.x = 2 or p.x = 3) and (p.y = 1 and p.y1) or (p.x = 2 or p.x = 3) and (p.y = 3 and p.y3)))) [backward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 1) and p.l1) (assignments: p.y := 0, p := p.y0), restricted to current/previous controlled-behavior predicate: true]
+Backward controlled-behavior: (p.x = 0 or p.x = 1) and (p.y = 0 and (p.l1 or p.y0)) or (p.x = 0 or p.x = 1) and (p.y = 2 and p.l1) or ((p.x = 0 or p.x = 1) and (p.y = 2 and p.y2) or (p.x = 0 or p.x = 1) and (p.y = 1 and (p.l1 or p.y1))) or ((p.x = 0 or p.x = 1) and (p.y = 3 and (p.l1 or p.y3)) or (p.x = 2 or p.x = 3) and (p.y = 0 and p.y0) or ((p.x = 2 or p.x = 3) and (p.y = 2 and p.y2) or ((p.x = 2 or p.x = 3) and (p.y = 1 and p.y1) or (p.x = 2 or p.x = 3) and (p.y = 3 and p.y3)))) -> <bdd 21n 14p> [backward reach with edge: (event: e) (guard: p.x = 2 and p.l1 or p.x = 1 and p.l1) (assignments: p.y := 1, p := p.y1), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 2.
+Backward controlled-behavior: <bdd 21n 14p> [fixed point].
+Controlled behavior: true -> <bdd 21n 14p>.
+
+Round 1: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: <bdd 21n 32p> [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 1: computing forward controlled-behavior predicate.
+Forward controlled-behavior: p.l1 [initialization predicate]
+Forward controlled-behavior: p.l1 -> (p.x = 0 or p.x = 2) and p.l1 or p.x = 1 and p.l1 [restricted to current/previous controlled-behavior predicate: <bdd 21n 14p>]
+Forward reachability: iteration 1.
+Forward controlled-behavior: (p.x = 0 or p.x = 2) and p.l1 or p.x = 1 and p.l1 -> p.x = 0 and (p.y = 0 and (p.l1 or p.y0)) or (p.x = 0 and (p.y = 2 and p.l1) or p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1)) or (p.x = 2 and p.l1 or p.x = 1 and (p.y = 0 and (p.l1 or p.y0)) or (p.x = 1 and (p.y = 2 and p.l1) or p.x = 1 and ((p.y = 1 or p.y = 3) and p.l1))) [forward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 1) and p.l1) (assignments: p.y := 0, p := p.y0), restricted to current/previous controlled-behavior predicate: <bdd 21n 14p>]
+Forward controlled-behavior: p.x = 0 and (p.y = 0 and (p.l1 or p.y0)) or (p.x = 0 and (p.y = 2 and p.l1) or p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1)) or (p.x = 2 and p.l1 or p.x = 1 and (p.y = 0 and (p.l1 or p.y0)) or (p.x = 1 and (p.y = 2 and p.l1) or p.x = 1 and ((p.y = 1 or p.y = 3) and p.l1))) -> p.x = 0 and (p.y = 0 and (p.l1 or p.y0)) or p.x = 0 and (p.y = 2 and p.l1) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or (p.x = 2 and ((p.y = 0 or p.y = 2) and p.l1) or p.x = 2 and (p.y = 1 and (p.l1 or p.y1)))) or (p.x = 2 and (p.y = 3 and p.l1) or p.x = 1 and (p.y = 0 and (p.l1 or p.y0)) or (p.x = 1 and (p.y = 2 and p.l1) or (p.x = 1 and (p.y = 1 and (p.l1 or p.y1)) or p.x = 1 and (p.y = 3 and p.l1)))) [forward reach with edge: (event: e) (guard: p.x = 2 and p.l1 or p.x = 1 and p.l1) (assignments: p.y := 1, p := p.y1), restricted to current/previous controlled-behavior predicate: <bdd 21n 14p>]
+Forward controlled-behavior: p.x = 0 and (p.y = 0 and (p.l1 or p.y0)) or p.x = 0 and (p.y = 2 and p.l1) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or (p.x = 2 and ((p.y = 0 or p.y = 2) and p.l1) or p.x = 2 and (p.y = 1 and (p.l1 or p.y1)))) or (p.x = 2 and (p.y = 3 and p.l1) or p.x = 1 and (p.y = 0 and (p.l1 or p.y0)) or (p.x = 1 and (p.y = 2 and p.l1) or (p.x = 1 and (p.y = 1 and (p.l1 or p.y1)) or p.x = 1 and (p.y = 3 and p.l1)))) -> p.x = 0 and (p.y = 0 and (p.l1 or p.y0)) or p.x = 0 and (p.y = 2 and p.l1) or (p.x = 0 and (p.y = 2 and p.y2) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or p.x = 2 and ((p.y = 0 or p.y = 2) and p.l1))) or (p.x = 2 and (p.y = 1 and (p.l1 or p.y1)) or (p.x = 2 and (p.y = 3 and p.l1) or p.x = 1 and (p.y = 0 and (p.l1 or p.y0))) or (p.x = 1 and (p.y = 2 and p.l1) or (p.x = 1 and (p.y = 1 and (p.l1 or p.y1)) or p.x = 1 and (p.y = 3 and p.l1)))) [forward reach with edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2), restricted to current/previous controlled-behavior predicate: <bdd 21n 14p>]
+Forward controlled-behavior: p.x = 0 and (p.y = 0 and (p.l1 or p.y0)) or p.x = 0 and (p.y = 2 and p.l1) or (p.x = 0 and (p.y = 2 and p.y2) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or p.x = 2 and ((p.y = 0 or p.y = 2) and p.l1))) or (p.x = 2 and (p.y = 1 and (p.l1 or p.y1)) or (p.x = 2 and (p.y = 3 and p.l1) or p.x = 1 and (p.y = 0 and (p.l1 or p.y0))) or (p.x = 1 and (p.y = 2 and p.l1) or (p.x = 1 and (p.y = 1 and (p.l1 or p.y1)) or p.x = 1 and (p.y = 3 and p.l1)))) -> p.x = 0 and (p.y = 0 and (p.l1 or p.y0)) or p.x = 0 and (p.y = 2 and p.l1) or (p.x = 0 and (p.y = 2 and p.y2) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or p.x = 2 and ((p.y = 0 or p.y = 2) and p.l1))) or (p.x = 2 and (p.y = 1 and (p.l1 or p.y1)) or (p.x = 2 and (p.y = 3 and p.l1) or p.x = 1 and (p.y = 0 and (p.l1 or p.y0))) or (p.x = 1 and (p.y = 2 and p.l1) or (p.x = 1 and (p.y = 1 and (p.l1 or p.y1)) or p.x = 1 and (p.y = 3 and (p.l1 or p.y3))))) [forward reach with edge: (event: e) (guard: p.x = 1 and p.l1) (assignments: p.y := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: <bdd 21n 14p>]
+Forward reachability: iteration 2.
+Forward controlled-behavior: p.x = 0 and (p.y = 0 and (p.l1 or p.y0)) or p.x = 0 and (p.y = 2 and p.l1) or (p.x = 0 and (p.y = 2 and p.y2) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or p.x = 2 and ((p.y = 0 or p.y = 2) and p.l1))) or (p.x = 2 and (p.y = 1 and (p.l1 or p.y1)) or (p.x = 2 and (p.y = 3 and p.l1) or p.x = 1 and (p.y = 0 and (p.l1 or p.y0))) or (p.x = 1 and (p.y = 2 and p.l1) or (p.x = 1 and (p.y = 1 and (p.l1 or p.y1)) or p.x = 1 and (p.y = 3 and (p.l1 or p.y3))))) [fixed point].
+Controlled behavior: <bdd 21n 14p> -> p.x = 0 and (p.y = 0 and (p.l1 or p.y0)) or p.x = 0 and (p.y = 2 and p.l1) or (p.x = 0 and (p.y = 2 and p.y2) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or p.x = 2 and ((p.y = 0 or p.y = 2) and p.l1))) or (p.x = 2 and (p.y = 1 and (p.l1 or p.y1)) or (p.x = 2 and (p.y = 3 and p.l1) or p.x = 1 and (p.y = 0 and (p.l1 or p.y0))) or (p.x = 1 and (p.y = 2 and p.l1) or (p.x = 1 and (p.y = 1 and (p.l1 or p.y1)) or p.x = 1 and (p.y = 3 and (p.l1 or p.y3))))).
+
+Round 1: finished, need another round.
+
+Round 2: started.
+
+Round 2: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3) [marker predicate]
+Backward controlled-behavior: p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3) -> p.x = 0 and (p.y = 0 and p.y0) or (p.x = 0 and (p.y = 2 and p.y2) or p.x = 2 and (p.y = 1 and p.y1)) or (p.x = 1 and (p.y = 0 and p.y0) or (p.x = 1 and (p.y = 1 and p.y1) or p.x = 1 and (p.y = 3 and p.y3))) [restricted to current/previous controlled-behavior predicate: p.x = 0 and (p.y = 0 and (p.l1 or p.y0)) or p.x = 0 and (p.y = 2 and p.l1) or (p.x = 0 and (p.y = 2 and p.y2) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or p.x = 2 and ((p.y = 0 or p.y = 2) and p.l1))) or (p.x = 2 and (p.y = 1 and (p.l1 or p.y1)) or (p.x = 2 and (p.y = 3 and p.l1) or p.x = 1 and (p.y = 0 and (p.l1 or p.y0))) or (p.x = 1 and (p.y = 2 and p.l1) or (p.x = 1 and (p.y = 1 and (p.l1 or p.y1)) or p.x = 1 and (p.y = 3 and (p.l1 or p.y3)))))]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.x = 0 and (p.y = 0 and p.y0) or (p.x = 0 and (p.y = 2 and p.y2) or p.x = 2 and (p.y = 1 and p.y1)) or (p.x = 1 and (p.y = 0 and p.y0) or (p.x = 1 and (p.y = 1 and p.y1) or p.x = 1 and (p.y = 3 and p.y3))) -> p.x = 0 and (p.y = 0 and (p.l1 or p.y0)) or p.x = 0 and (p.y = 2 and p.l1) or (p.x = 0 and (p.y = 2 and p.y2) or p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1)) or (p.x = 2 and (p.y = 1 and p.y1) or p.x = 1 and (p.y = 0 and (p.l1 or p.y0)) or (p.x = 1 and (p.y = 2 and p.l1) or (p.x = 1 and (p.y = 1 and (p.l1 or p.y1)) or p.x = 1 and (p.y = 3 and (p.l1 or p.y3))))) [backward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 1) and p.l1) (assignments: p.y := 0, p := p.y0), restricted to current/previous controlled-behavior predicate: p.x = 0 and (p.y = 0 and (p.l1 or p.y0)) or p.x = 0 and (p.y = 2 and p.l1) or (p.x = 0 and (p.y = 2 and p.y2) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or p.x = 2 and ((p.y = 0 or p.y = 2) and p.l1))) or (p.x = 2 and (p.y = 1 and (p.l1 or p.y1)) or (p.x = 2 and (p.y = 3 and p.l1) or p.x = 1 and (p.y = 0 and (p.l1 or p.y0))) or (p.x = 1 and (p.y = 2 and p.l1) or (p.x = 1 and (p.y = 1 and (p.l1 or p.y1)) or p.x = 1 and (p.y = 3 and (p.l1 or p.y3)))))]
+Backward controlled-behavior: p.x = 0 and (p.y = 0 and (p.l1 or p.y0)) or p.x = 0 and (p.y = 2 and p.l1) or (p.x = 0 and (p.y = 2 and p.y2) or p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1)) or (p.x = 2 and (p.y = 1 and p.y1) or p.x = 1 and (p.y = 0 and (p.l1 or p.y0)) or (p.x = 1 and (p.y = 2 and p.l1) or (p.x = 1 and (p.y = 1 and (p.l1 or p.y1)) or p.x = 1 and (p.y = 3 and (p.l1 or p.y3))))) -> p.x = 0 and (p.y = 0 and (p.l1 or p.y0)) or p.x = 0 and (p.y = 2 and p.l1) or (p.x = 0 and (p.y = 2 and p.y2) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or p.x = 2 and ((p.y = 0 or p.y = 2) and p.l1))) or (p.x = 2 and (p.y = 1 and (p.l1 or p.y1)) or (p.x = 2 and (p.y = 3 and p.l1) or p.x = 1 and (p.y = 0 and (p.l1 or p.y0))) or (p.x = 1 and (p.y = 2 and p.l1) or (p.x = 1 and (p.y = 1 and (p.l1 or p.y1)) or p.x = 1 and (p.y = 3 and (p.l1 or p.y3))))) [backward reach with edge: (event: e) (guard: p.x = 2 and p.l1 or p.x = 1 and p.l1) (assignments: p.y := 1, p := p.y1), restricted to current/previous controlled-behavior predicate: p.x = 0 and (p.y = 0 and (p.l1 or p.y0)) or p.x = 0 and (p.y = 2 and p.l1) or (p.x = 0 and (p.y = 2 and p.y2) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or p.x = 2 and ((p.y = 0 or p.y = 2) and p.l1))) or (p.x = 2 and (p.y = 1 and (p.l1 or p.y1)) or (p.x = 2 and (p.y = 3 and p.l1) or p.x = 1 and (p.y = 0 and (p.l1 or p.y0))) or (p.x = 1 and (p.y = 2 and p.l1) or (p.x = 1 and (p.y = 1 and (p.l1 or p.y1)) or p.x = 1 and (p.y = 3 and (p.l1 or p.y3)))))]
+Backward reachability: iteration 2.
+Backward controlled-behavior: p.x = 0 and (p.y = 0 and (p.l1 or p.y0)) or p.x = 0 and (p.y = 2 and p.l1) or (p.x = 0 and (p.y = 2 and p.y2) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or p.x = 2 and ((p.y = 0 or p.y = 2) and p.l1))) or (p.x = 2 and (p.y = 1 and (p.l1 or p.y1)) or (p.x = 2 and (p.y = 3 and p.l1) or p.x = 1 and (p.y = 0 and (p.l1 or p.y0))) or (p.x = 1 and (p.y = 2 and p.l1) or (p.x = 1 and (p.y = 1 and (p.l1 or p.y1)) or p.x = 1 and (p.y = 3 and (p.l1 or p.y3))))) [fixed point].
+
+Round 2: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: <bdd 18n 27p> [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 2: finished, controlled behavior is stable.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: p.x = 0 and (p.y = 0 and (p.l1 or p.y0)) or p.x = 0 and (p.y = 2 and p.l1) or (p.x = 0 and (p.y = 2 and p.y2) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or p.x = 2 and ((p.y = 0 or p.y = 2) and p.l1))) or (p.x = 2 and (p.y = 1 and (p.l1 or p.y1)) or (p.x = 2 and (p.y = 3 and p.l1) or p.x = 1 and (p.y = 0 and (p.l1 or p.y0))) or (p.x = 1 and (p.y = 2 and p.l1) or (p.x = 1 and (p.y = 1 and (p.l1 or p.y1)) or p.x = 1 and (p.y = 3 and (p.l1 or p.y3))))))
+    Edge: (event: e) (guard: (p.x = 0 or p.x = 1) and p.l1) (assignments: p.y := 0, p := p.y0)
+    Edge: (event: e) (guard: p.x = 2 and p.l1 or p.x = 1 and p.l1) (assignments: p.y := 1, p := p.y1)
+    Edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 0, p := p.y0)
+    Edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p := p.y2)
+    Edge: (event: e) (guard: p.x = 1 and p.l1) (assignments: p.y := 1, p := p.y1)
+    Edge: (event: e) (guard: p.x = 1 and p.l1) (assignments: p.y := 3, p := p.y3)
+
+Controlled system:                     exactly 18 states.
+
+Initial (synthesis result):            p.x = 0 and (p.y = 0 and (p.l1 or p.y0)) or p.x = 0 and (p.y = 2 and p.l1) or (p.x = 0 and (p.y = 2 and p.y2) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or p.x = 2 and ((p.y = 0 or p.y = 2) and p.l1))) or (p.x = 2 and (p.y = 1 and (p.l1 or p.y1)) or (p.x = 2 and (p.y = 3 and p.l1) or p.x = 1 and (p.y = 0 and (p.l1 or p.y0))) or (p.x = 1 and (p.y = 2 and p.l1) or (p.x = 1 and (p.y = 1 and (p.l1 or p.y1)) or p.x = 1 and (p.y = 3 and (p.l1 or p.y3)))))
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           (p.x = 0 or p.x = 2) and p.l1 or p.x = 1 and p.l1
+Initial (removed by supervisor):       p.x = 3 and p.l1
+Initial (added by supervisor):         p.x != 3 or not p.l1
+
+Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
+  Initial: (p.x = 0 or p.x = 2) and p.l1 or p.x = 1 and p.l1 -> p.x != 3 [assume p.l1].
+
+Constructing output CIF specification.
+Writing output CIF file "datasynth/edge_granularity_guards_updates7_per_edge.ctrlsys.real.cif".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates7_per_edge.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates7_per_edge.ctrlsys.cif
new file mode 100644
index 0000000000000000000000000000000000000000..11a98b1eb3d74ab29ab18a9813f5fa33b751ccec
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates7_per_edge.ctrlsys.cif
@@ -0,0 +1,28 @@
+uncontrollable e;
+plant automaton p:
+  disc int[0..3] x in any;
+  disc int[0..3] y in any;
+  location l1:
+    initial;
+    edge e when x = 0 or x = 1 do y := 0 goto y0;
+    edge e when x = 1 or x = 2 do y := 1 goto y1;
+    edge e when x = 0 do y := 0 goto y0;
+    edge e when x = 0 do y := 2 goto y2;
+    edge e when x = 1 do y := 1 goto y1;
+    edge e when x = 1 do y := 3 goto y3;
+  location y0:
+    marked y = 0;
+  location y1:
+    marked y = 1;
+  location y2:
+    marked y = 2;
+  location y3:
+    marked y = 3;
+end
+supervisor automaton sup:
+  alphabet;
+  initial p.x != 3;
+  location:
+    initial;
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates7_per_edge.statespace.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates7_per_edge.statespace.cif
new file mode 100644
index 0000000000000000000000000000000000000000..b306ca1a3315ba70370bd9e2afba2562c51c9be3
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates7_per_edge.statespace.cif
@@ -0,0 +1,64 @@
+uncontrollable e;
+automaton statespace:
+  alphabet e;
+  location loc1:
+    initial;
+    edge e goto loc13;
+    edge e goto loc14;
+  location loc2:
+    initial;
+    edge e goto loc13;
+    edge e goto loc14;
+  location loc3:
+    initial;
+    edge e goto loc13;
+    edge e goto loc14;
+  location loc4:
+    initial;
+    edge e goto loc13;
+    edge e goto loc14;
+  location loc5:
+    initial;
+    edge e goto loc15;
+    edge e goto loc16;
+    edge e goto loc17;
+  location loc6:
+    initial;
+    edge e goto loc15;
+    edge e goto loc16;
+    edge e goto loc17;
+  location loc7:
+    initial;
+    edge e goto loc15;
+    edge e goto loc16;
+    edge e goto loc17;
+  location loc8:
+    initial;
+    edge e goto loc15;
+    edge e goto loc16;
+    edge e goto loc17;
+  location loc9:
+    initial;
+    edge e goto loc18;
+  location loc10:
+    initial;
+    edge e goto loc18;
+  location loc11:
+    initial;
+    edge e goto loc18;
+  location loc12:
+    initial;
+    edge e goto loc18;
+  location loc13:
+    marked;
+  location loc14:
+    marked;
+  location loc15:
+    marked;
+  location loc16:
+    marked;
+  location loc17:
+    marked;
+  location loc18:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates7_per_event.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates7_per_event.cif
new file mode 100644
index 0000000000000000000000000000000000000000..44fc8dfd528c3ad6b0d0d3a22238bf44782b6a80
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates7_per_event.cif
@@ -0,0 +1,42 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..3] x in any;
+  disc int[0..3] y in any;
+
+  location l1: // x in {0, 1, 2}, y in any
+    initial;
+
+    // Partially overlapping guards, different and same updates.
+    edge e when x = 0 or x = 1 do y := 0 goto y0;
+    edge e when x = 1 or x = 2 do y := 1 goto y1;
+    edge e when x = 0          do y := 0 goto y0;
+    edge e when x = 0          do y := 2 goto y2;
+    edge e when x = 1          do y := 1 goto y1;
+    edge e when x = 1          do y := 3 goto y3;
+
+  location y0: // x in {0, 1}, y = 0
+    marked y = 0;
+
+  location y1: // x in {1, 2}, y = 1
+    marked y = 1;
+
+  location y2: // x = 0, y = 2
+    marked y = 2;
+
+  location y3: // x = 1, y = 3
+    marked y = 3;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates7_per_event.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates7_per_event.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..22649bd5888f3b3d82c7b81d9ca4545b07dffb09
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates7_per_event.cif.out
@@ -0,0 +1,227 @@
+Reading CIF file "datasynth/edge_granularity_guards_updates7_per_event.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      3 * 2     5 * 2       8 * 2       ~63%
+  2      discrete variable  int[0..3]  p.x   1      2 * 2     4 * 2       4 * 2       100%
+  3      discrete variable  int[0..3]  p.y   2      2 * 2     4 * 2       4 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      3      14        26          32          ~81%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 15
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 3
+
+        Total span:   2 (total)   0.13 (avg/edge) / WES:   0.385185 (total)   0.025679 (avg/edge) [before]
+        Total span:   2 (total)   0.13 (avg/edge) / WES:   0.385185 (total)   0.025679 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 3
+
+        Total span:   2 (total)   0.13 (avg/edge) / WES:   0.385185 (total)   0.025679 (avg/edge) [before]
+        Total span:   2 (total)   0.13 (avg/edge) / WES:   0.414815 (total)   0.027654 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 3
+
+          Total span:   2 (total)   0.13 (avg/edge) / WES:   0.385185 (total)   0.025679 (avg/edge) [before]
+          Total span:   2 (total)   0.13 (avg/edge) / WES:   0.385185 (total)   0.025679 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 15
+
+          Total span:   2 (total)   0.13 (avg/edge) / WES:   0.385185 (total)   0.025679 (avg/edge) [before]
+          Total span:   2 (total)   0.13 (avg/edge) / WES:   0.385185 (total)   0.025679 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 3
+
+          Total span:   2 (total)   0.13 (avg/edge) / WES:   0.385185 (total)   0.025679 (avg/edge) [before]
+          Total span:   2 (total)   0.13 (avg/edge) / WES:   0.414815 (total)   0.027654 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 15
+
+          Total span:   2 (total)   0.13 (avg/edge) / WES:   0.414815 (total)   0.027654 (avg/edge) [before]
+          Total span:   2 (total)   0.13 (avg/edge) / WES:   0.414815 (total)   0.027654 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 6
+      Maximum number of iterations: 20
+
+      Total span:   12 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.222222 (avg/edge) [before]
+      Total span:   12 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.222222 (avg/edge) [iteration 1]
+      Total span:   12 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.222222 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 6
+      Window length: 3
+
+      Total span:   12 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.222222 (avg/edge) [before]
+      Total span:   12 (total)   2.00 (avg/edge) / WES:   1.333333 (total)   0.222222 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..3]  p.x   0      2 * 2     4 * 2       4 * 2       100%
+  2      discrete variable  int[0..3]  p.y   1      2 * 2     4 * 2       4 * 2       100%
+  3      location pointer   n/a        p     2      3 * 2     5 * 2       8 * 2       ~63%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      3      14        26          32          ~81%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variable 1):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.l1
+Initial   (system, combined init/plant inv): p.l1
+Initial   (system, combined init/state inv): p.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3)
+Marked    (auts/locs marker predicate):      p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3)
+Marked    (uncontrolled system):             p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3)
+Marked    (system, combined mark/plant inv): p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3)
+Marked    (system, combined mark/state inv): p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3)
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: (p.x = 0 or p.x = 2) and p.l1 or p.x = 1 and p.l1) (assignments: p.y := 0, p := p.y0 / p.y := 1, p := p.y1 / p.y := 0, p := p.y0 / p.y := 2, p := p.y2 / p.y := 1, p := p.y1 / p.y := 3, p := p.y3)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Controlled behavior: true -> true [range: true, variable: location pointer for automaton "p" (group: 2, domain: 4+5, BDD variables: 3, CIF/BDD values: 5/8)].
+
+Extended controlled-behavior predicate using variable ranges: true.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3) [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3) -> <bdd 21n 14p> [backward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 2) and p.l1 or p.x = 1 and p.l1) (assignments: p.y := 0, p := p.y0 / p.y := 1, p := p.y1 / p.y := 0, p := p.y0 / p.y := 2, p := p.y2 / p.y := 1, p := p.y1 / p.y := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 2.
+Backward controlled-behavior: <bdd 21n 14p> [fixed point].
+Controlled behavior: true -> <bdd 21n 14p>.
+
+Round 1: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: <bdd 21n 32p> [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 1: computing forward controlled-behavior predicate.
+Forward controlled-behavior: p.l1 [initialization predicate]
+Forward controlled-behavior: p.l1 -> (p.x = 0 or p.x = 2) and p.l1 or p.x = 1 and p.l1 [restricted to current/previous controlled-behavior predicate: <bdd 21n 14p>]
+Forward reachability: iteration 1.
+Forward controlled-behavior: (p.x = 0 or p.x = 2) and p.l1 or p.x = 1 and p.l1 -> p.x = 0 and (p.y = 0 and (p.l1 or p.y0)) or p.x = 0 and (p.y = 2 and p.l1) or (p.x = 0 and (p.y = 2 and p.y2) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or p.x = 2 and ((p.y = 0 or p.y = 2) and p.l1))) or (p.x = 2 and (p.y = 1 and (p.l1 or p.y1)) or (p.x = 2 and (p.y = 3 and p.l1) or p.x = 1 and (p.y = 0 and (p.l1 or p.y0))) or (p.x = 1 and (p.y = 2 and p.l1) or (p.x = 1 and (p.y = 1 and (p.l1 or p.y1)) or p.x = 1 and (p.y = 3 and (p.l1 or p.y3))))) [forward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 2) and p.l1 or p.x = 1 and p.l1) (assignments: p.y := 0, p := p.y0 / p.y := 1, p := p.y1 / p.y := 0, p := p.y0 / p.y := 2, p := p.y2 / p.y := 1, p := p.y1 / p.y := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: <bdd 21n 14p>]
+Forward reachability: iteration 2.
+Forward controlled-behavior: p.x = 0 and (p.y = 0 and (p.l1 or p.y0)) or p.x = 0 and (p.y = 2 and p.l1) or (p.x = 0 and (p.y = 2 and p.y2) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or p.x = 2 and ((p.y = 0 or p.y = 2) and p.l1))) or (p.x = 2 and (p.y = 1 and (p.l1 or p.y1)) or (p.x = 2 and (p.y = 3 and p.l1) or p.x = 1 and (p.y = 0 and (p.l1 or p.y0))) or (p.x = 1 and (p.y = 2 and p.l1) or (p.x = 1 and (p.y = 1 and (p.l1 or p.y1)) or p.x = 1 and (p.y = 3 and (p.l1 or p.y3))))) [fixed point].
+Controlled behavior: <bdd 21n 14p> -> p.x = 0 and (p.y = 0 and (p.l1 or p.y0)) or p.x = 0 and (p.y = 2 and p.l1) or (p.x = 0 and (p.y = 2 and p.y2) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or p.x = 2 and ((p.y = 0 or p.y = 2) and p.l1))) or (p.x = 2 and (p.y = 1 and (p.l1 or p.y1)) or (p.x = 2 and (p.y = 3 and p.l1) or p.x = 1 and (p.y = 0 and (p.l1 or p.y0))) or (p.x = 1 and (p.y = 2 and p.l1) or (p.x = 1 and (p.y = 1 and (p.l1 or p.y1)) or p.x = 1 and (p.y = 3 and (p.l1 or p.y3))))).
+
+Round 1: finished, need another round.
+
+Round 2: started.
+
+Round 2: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3) [marker predicate]
+Backward controlled-behavior: p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3) -> p.x = 0 and (p.y = 0 and p.y0) or (p.x = 0 and (p.y = 2 and p.y2) or p.x = 2 and (p.y = 1 and p.y1)) or (p.x = 1 and (p.y = 0 and p.y0) or (p.x = 1 and (p.y = 1 and p.y1) or p.x = 1 and (p.y = 3 and p.y3))) [restricted to current/previous controlled-behavior predicate: p.x = 0 and (p.y = 0 and (p.l1 or p.y0)) or p.x = 0 and (p.y = 2 and p.l1) or (p.x = 0 and (p.y = 2 and p.y2) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or p.x = 2 and ((p.y = 0 or p.y = 2) and p.l1))) or (p.x = 2 and (p.y = 1 and (p.l1 or p.y1)) or (p.x = 2 and (p.y = 3 and p.l1) or p.x = 1 and (p.y = 0 and (p.l1 or p.y0))) or (p.x = 1 and (p.y = 2 and p.l1) or (p.x = 1 and (p.y = 1 and (p.l1 or p.y1)) or p.x = 1 and (p.y = 3 and (p.l1 or p.y3)))))]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.x = 0 and (p.y = 0 and p.y0) or (p.x = 0 and (p.y = 2 and p.y2) or p.x = 2 and (p.y = 1 and p.y1)) or (p.x = 1 and (p.y = 0 and p.y0) or (p.x = 1 and (p.y = 1 and p.y1) or p.x = 1 and (p.y = 3 and p.y3))) -> p.x = 0 and (p.y = 0 and (p.l1 or p.y0)) or p.x = 0 and (p.y = 2 and p.l1) or (p.x = 0 and (p.y = 2 and p.y2) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or p.x = 2 and ((p.y = 0 or p.y = 2) and p.l1))) or (p.x = 2 and (p.y = 1 and (p.l1 or p.y1)) or (p.x = 2 and (p.y = 3 and p.l1) or p.x = 1 and (p.y = 0 and (p.l1 or p.y0))) or (p.x = 1 and (p.y = 2 and p.l1) or (p.x = 1 and (p.y = 1 and (p.l1 or p.y1)) or p.x = 1 and (p.y = 3 and (p.l1 or p.y3))))) [backward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 2) and p.l1 or p.x = 1 and p.l1) (assignments: p.y := 0, p := p.y0 / p.y := 1, p := p.y1 / p.y := 0, p := p.y0 / p.y := 2, p := p.y2 / p.y := 1, p := p.y1 / p.y := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: p.x = 0 and (p.y = 0 and (p.l1 or p.y0)) or p.x = 0 and (p.y = 2 and p.l1) or (p.x = 0 and (p.y = 2 and p.y2) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or p.x = 2 and ((p.y = 0 or p.y = 2) and p.l1))) or (p.x = 2 and (p.y = 1 and (p.l1 or p.y1)) or (p.x = 2 and (p.y = 3 and p.l1) or p.x = 1 and (p.y = 0 and (p.l1 or p.y0))) or (p.x = 1 and (p.y = 2 and p.l1) or (p.x = 1 and (p.y = 1 and (p.l1 or p.y1)) or p.x = 1 and (p.y = 3 and (p.l1 or p.y3)))))]
+Backward reachability: iteration 2.
+Backward controlled-behavior: p.x = 0 and (p.y = 0 and (p.l1 or p.y0)) or p.x = 0 and (p.y = 2 and p.l1) or (p.x = 0 and (p.y = 2 and p.y2) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or p.x = 2 and ((p.y = 0 or p.y = 2) and p.l1))) or (p.x = 2 and (p.y = 1 and (p.l1 or p.y1)) or (p.x = 2 and (p.y = 3 and p.l1) or p.x = 1 and (p.y = 0 and (p.l1 or p.y0))) or (p.x = 1 and (p.y = 2 and p.l1) or (p.x = 1 and (p.y = 1 and (p.l1 or p.y1)) or p.x = 1 and (p.y = 3 and (p.l1 or p.y3))))) [fixed point].
+
+Round 2: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: <bdd 18n 27p> [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 2: finished, controlled behavior is stable.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: p.x = 0 and (p.y = 0 and (p.l1 or p.y0)) or p.x = 0 and (p.y = 2 and p.l1) or (p.x = 0 and (p.y = 2 and p.y2) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or p.x = 2 and ((p.y = 0 or p.y = 2) and p.l1))) or (p.x = 2 and (p.y = 1 and (p.l1 or p.y1)) or (p.x = 2 and (p.y = 3 and p.l1) or p.x = 1 and (p.y = 0 and (p.l1 or p.y0))) or (p.x = 1 and (p.y = 2 and p.l1) or (p.x = 1 and (p.y = 1 and (p.l1 or p.y1)) or p.x = 1 and (p.y = 3 and (p.l1 or p.y3))))))
+    Edge: (event: e) (guard: (p.x = 0 or p.x = 2) and p.l1 or p.x = 1 and p.l1) (assignments: p.y := 0, p := p.y0 / p.y := 1, p := p.y1 / p.y := 0, p := p.y0 / p.y := 2, p := p.y2 / p.y := 1, p := p.y1 / p.y := 3, p := p.y3)
+
+Controlled system:                     exactly 18 states.
+
+Initial (synthesis result):            p.x = 0 and (p.y = 0 and (p.l1 or p.y0)) or p.x = 0 and (p.y = 2 and p.l1) or (p.x = 0 and (p.y = 2 and p.y2) or (p.x = 0 and ((p.y = 1 or p.y = 3) and p.l1) or p.x = 2 and ((p.y = 0 or p.y = 2) and p.l1))) or (p.x = 2 and (p.y = 1 and (p.l1 or p.y1)) or (p.x = 2 and (p.y = 3 and p.l1) or p.x = 1 and (p.y = 0 and (p.l1 or p.y0))) or (p.x = 1 and (p.y = 2 and p.l1) or (p.x = 1 and (p.y = 1 and (p.l1 or p.y1)) or p.x = 1 and (p.y = 3 and (p.l1 or p.y3)))))
+Initial (uncontrolled system):         p.l1
+Initial (controlled system):           (p.x = 0 or p.x = 2) and p.l1 or p.x = 1 and p.l1
+Initial (removed by supervisor):       p.x = 3 and p.l1
+Initial (added by supervisor):         p.x != 3 or not p.l1
+
+Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
+  Initial: (p.x = 0 or p.x = 2) and p.l1 or p.x = 1 and p.l1 -> p.x != 3 [assume p.l1].
+
+Constructing output CIF specification.
+Writing output CIF file "datasynth/edge_granularity_guards_updates7_per_event.ctrlsys.real.cif".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates7_per_event.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates7_per_event.ctrlsys.cif
new file mode 100644
index 0000000000000000000000000000000000000000..11a98b1eb3d74ab29ab18a9813f5fa33b751ccec
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates7_per_event.ctrlsys.cif
@@ -0,0 +1,28 @@
+uncontrollable e;
+plant automaton p:
+  disc int[0..3] x in any;
+  disc int[0..3] y in any;
+  location l1:
+    initial;
+    edge e when x = 0 or x = 1 do y := 0 goto y0;
+    edge e when x = 1 or x = 2 do y := 1 goto y1;
+    edge e when x = 0 do y := 0 goto y0;
+    edge e when x = 0 do y := 2 goto y2;
+    edge e when x = 1 do y := 1 goto y1;
+    edge e when x = 1 do y := 3 goto y3;
+  location y0:
+    marked y = 0;
+  location y1:
+    marked y = 1;
+  location y2:
+    marked y = 2;
+  location y3:
+    marked y = 3;
+end
+supervisor automaton sup:
+  alphabet;
+  initial p.x != 3;
+  location:
+    initial;
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates7_per_event.statespace.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates7_per_event.statespace.cif
new file mode 100644
index 0000000000000000000000000000000000000000..b306ca1a3315ba70370bd9e2afba2562c51c9be3
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates7_per_event.statespace.cif
@@ -0,0 +1,64 @@
+uncontrollable e;
+automaton statespace:
+  alphabet e;
+  location loc1:
+    initial;
+    edge e goto loc13;
+    edge e goto loc14;
+  location loc2:
+    initial;
+    edge e goto loc13;
+    edge e goto loc14;
+  location loc3:
+    initial;
+    edge e goto loc13;
+    edge e goto loc14;
+  location loc4:
+    initial;
+    edge e goto loc13;
+    edge e goto loc14;
+  location loc5:
+    initial;
+    edge e goto loc15;
+    edge e goto loc16;
+    edge e goto loc17;
+  location loc6:
+    initial;
+    edge e goto loc15;
+    edge e goto loc16;
+    edge e goto loc17;
+  location loc7:
+    initial;
+    edge e goto loc15;
+    edge e goto loc16;
+    edge e goto loc17;
+  location loc8:
+    initial;
+    edge e goto loc15;
+    edge e goto loc16;
+    edge e goto loc17;
+  location loc9:
+    initial;
+    edge e goto loc18;
+  location loc10:
+    initial;
+    edge e goto loc18;
+  location loc11:
+    initial;
+    edge e goto loc18;
+  location loc12:
+    initial;
+    edge e goto loc18;
+  location loc13:
+    marked;
+  location loc14:
+    marked;
+  location loc15:
+    marked;
+  location loc16:
+    marked;
+  location loc17:
+    marked;
+  location loc18:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates8_per_edge.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates8_per_edge.cif
new file mode 100644
index 0000000000000000000000000000000000000000..6d1ea58259c6762b3b86791ead2a92af653875d9
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates8_per_edge.cif
@@ -0,0 +1,43 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..3] x in any;
+  disc int[0..3] y;
+  disc int[0..3] z;
+
+  location l1: // x in {0, 1, 2}, y = 0, z = 0
+    initial;
+
+    // Partially overlapping guards, different and same updates, and a second variable as well.
+    edge e when x = 0 or x = 1 do y := 0, z := 1 goto y0;
+    edge e when x = 1 or x = 2 do y := 1, z := 1 goto y1;
+    edge e when x = 0          do y := 0, z := 1 goto y0;
+    edge e when x = 0          do y := 2, z := 2 goto y2;
+    edge e when x = 1          do y := 1, z := 2 goto y1;
+    edge e when x = 1          do y := 3, z := 3 goto y3;
+
+  location y0: // x in {0, 1}, y = 0, z = 1
+    marked y = 0;
+
+  location y1: // x in {1, 2}, y = 1, z in {1, 2}, but not (x = 2 and z = 2)
+    marked y = 1;
+
+  location y2: // x = 0, y = 2, z = 2
+    marked y = 2;
+
+  location y3: // x = 1, y = 3, z = 3
+    marked y = 3;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates8_per_edge.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates8_per_edge.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..710e415b0ecaa7dc8093c8ab0cae237357676bae
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates8_per_edge.cif.out
@@ -0,0 +1,246 @@
+Reading CIF file "datasynth/edge_granularity_guards_updates8_per_edge.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      3 * 2     5 * 2       8 * 2       ~63%
+  2      discrete variable  int[0..3]  p.x   1      2 * 2     4 * 2       4 * 2       100%
+  3      discrete variable  int[0..3]  p.y   2      2 * 2     4 * 2       4 * 2       100%
+  4      discrete variable  int[0..3]  p.z   3      2 * 2     4 * 2       4 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      4      18        34          40          85%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 21
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 6
+
+        Total span:   3 (total)   0.14 (avg/edge) / WES:   0.297619 (total)   0.014172 (avg/edge) [before]
+        Total span:   3 (total)   0.14 (avg/edge) / WES:   0.297619 (total)   0.014172 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 6
+
+        Total span:   3 (total)   0.14 (avg/edge) / WES:   0.297619 (total)   0.014172 (avg/edge) [before]
+        Total span:   3 (total)   0.14 (avg/edge) / WES:   0.321429 (total)   0.015306 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 6
+
+          Total span:   3 (total)   0.14 (avg/edge) / WES:   0.297619 (total)   0.014172 (avg/edge) [before]
+          Total span:   3 (total)   0.14 (avg/edge) / WES:   0.297619 (total)   0.014172 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 21
+
+          Total span:   3 (total)   0.14 (avg/edge) / WES:   0.297619 (total)   0.014172 (avg/edge) [before]
+          Total span:   3 (total)   0.14 (avg/edge) / WES:   0.297619 (total)   0.014172 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 6
+
+          Total span:   3 (total)   0.14 (avg/edge) / WES:   0.297619 (total)   0.014172 (avg/edge) [before]
+          Total span:   3 (total)   0.14 (avg/edge) / WES:   0.321429 (total)   0.015306 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 21
+
+          Total span:   3 (total)   0.14 (avg/edge) / WES:   0.321429 (total)   0.015306 (avg/edge) [before]
+          Total span:   3 (total)   0.14 (avg/edge) / WES:   0.321429 (total)   0.015306 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 6
+      Maximum number of iterations: 20
+
+      Total span:   18 (total)   3.00 (avg/edge) / WES:   1.500000 (total)   0.250000 (avg/edge) [before]
+      Total span:   18 (total)   3.00 (avg/edge) / WES:   1.500000 (total)   0.250000 (avg/edge) [iteration 1]
+      Total span:   18 (total)   3.00 (avg/edge) / WES:   1.500000 (total)   0.250000 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 6
+      Window length: 4
+
+      Total span:   18 (total)   3.00 (avg/edge) / WES:   1.500000 (total)   0.250000 (avg/edge) [before]
+      Total span:   18 (total)   3.00 (avg/edge) / WES:   1.500000 (total)   0.250000 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..3]  p.x   0      2 * 2     4 * 2       4 * 2       100%
+  2      discrete variable  int[0..3]  p.z   1      2 * 2     4 * 2       4 * 2       100%
+  3      discrete variable  int[0..3]  p.y   2      2 * 2     4 * 2       4 * 2       100%
+  4      location pointer   n/a        p     3      3 * 2     5 * 2       8 * 2       ~63%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      4      18        34          40          85%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variable 1):             p.z = 0
+Initial   (discrete variable 2):             p.y = 0
+Initial   (discrete variables):              p.z = 0 and p.y = 0
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.z = 0 and (p.y = 0 and p.l1)
+Initial   (system, combined init/plant inv): p.z = 0 and (p.y = 0 and p.l1)
+Initial   (system, combined init/state inv): p.z = 0 and (p.y = 0 and p.l1)
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3)
+Marked    (auts/locs marker predicate):      p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3)
+Marked    (uncontrolled system):             p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3)
+Marked    (system, combined mark/plant inv): p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3)
+Marked    (system, combined mark/state inv): p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3)
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: (p.x = 0 or p.x = 1) and p.l1) (assignments: p.y := 0, p.z := 1, p := p.y0)
+    Edge: (event: e) (guard: p.x = 2 and p.l1 or p.x = 1 and p.l1) (assignments: p.y := 1, p.z := 1, p := p.y1)
+    Edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 0, p.z := 1, p := p.y0)
+    Edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p.z := 2, p := p.y2)
+    Edge: (event: e) (guard: p.x = 1 and p.l1) (assignments: p.y := 1, p.z := 2, p := p.y1)
+    Edge: (event: e) (guard: p.x = 1 and p.l1) (assignments: p.y := 3, p.z := 3, p := p.y3)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.z = 0 and (p.y = 0 and p.l1).
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Controlled behavior: true -> true [range: true, variable: location pointer for automaton "p" (group: 3, domain: 6+7, BDD variables: 3, CIF/BDD values: 5/8)].
+
+Extended controlled-behavior predicate using variable ranges: true.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3) [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3) -> (p.x = 0 or p.x = 1) and (p.y = 0 and (p.l1 or p.y0)) or (p.x = 0 or p.x = 1) and (p.y = 2 and p.l1) or ((p.x = 0 or p.x = 1) and (p.y = 2 and p.y2) or (p.x = 0 or p.x = 1) and (p.y = 1 and (p.l1 or p.y1))) or ((p.x = 0 or p.x = 1) and (p.y = 3 and (p.l1 or p.y3)) or (p.x = 2 or p.x = 3) and (p.y = 0 and p.y0) or ((p.x = 2 or p.x = 3) and (p.y = 2 and p.y2) or ((p.x = 2 or p.x = 3) and (p.y = 1 and p.y1) or (p.x = 2 or p.x = 3) and (p.y = 3 and p.y3)))) [backward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 1) and p.l1) (assignments: p.y := 0, p.z := 1, p := p.y0), restricted to current/previous controlled-behavior predicate: true]
+Backward controlled-behavior: (p.x = 0 or p.x = 1) and (p.y = 0 and (p.l1 or p.y0)) or (p.x = 0 or p.x = 1) and (p.y = 2 and p.l1) or ((p.x = 0 or p.x = 1) and (p.y = 2 and p.y2) or (p.x = 0 or p.x = 1) and (p.y = 1 and (p.l1 or p.y1))) or ((p.x = 0 or p.x = 1) and (p.y = 3 and (p.l1 or p.y3)) or (p.x = 2 or p.x = 3) and (p.y = 0 and p.y0) or ((p.x = 2 or p.x = 3) and (p.y = 2 and p.y2) or ((p.x = 2 or p.x = 3) and (p.y = 1 and p.y1) or (p.x = 2 or p.x = 3) and (p.y = 3 and p.y3)))) -> <bdd 21n 14p> [backward reach with edge: (event: e) (guard: p.x = 2 and p.l1 or p.x = 1 and p.l1) (assignments: p.y := 1, p.z := 1, p := p.y1), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 2.
+Backward controlled-behavior: <bdd 21n 14p> [fixed point].
+Controlled behavior: true -> <bdd 21n 14p>.
+
+Round 1: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: <bdd 21n 32p> [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 1: computing forward controlled-behavior predicate.
+Forward controlled-behavior: p.z = 0 and (p.y = 0 and p.l1) [initialization predicate]
+Forward controlled-behavior: p.z = 0 and (p.y = 0 and p.l1) -> (p.x = 0 or p.x = 2) and p.z = 0 and (p.y = 0 and p.l1) or p.x = 1 and p.z = 0 and (p.y = 0 and p.l1) [restricted to current/previous controlled-behavior predicate: <bdd 21n 14p>]
+Forward reachability: iteration 1.
+Forward controlled-behavior: (p.x = 0 or p.x = 2) and p.z = 0 and (p.y = 0 and p.l1) or p.x = 1 and p.z = 0 and (p.y = 0 and p.l1) -> p.x = 0 and p.z = 0 and (p.y = 0 and p.l1) or p.x = 0 and p.z = 1 and (p.y = 0 and p.y0) or (p.x = 2 and p.z = 0 and (p.y = 0 and p.l1) or (p.x = 1 and p.z = 0 and (p.y = 0 and p.l1) or p.x = 1 and p.z = 1 and (p.y = 0 and p.y0))) [forward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 1) and p.l1) (assignments: p.y := 0, p.z := 1, p := p.y0), restricted to current/previous controlled-behavior predicate: <bdd 21n 14p>]
+Forward controlled-behavior: p.x = 0 and p.z = 0 and (p.y = 0 and p.l1) or p.x = 0 and p.z = 1 and (p.y = 0 and p.y0) or (p.x = 2 and p.z = 0 and (p.y = 0 and p.l1) or (p.x = 1 and p.z = 0 and (p.y = 0 and p.l1) or p.x = 1 and p.z = 1 and (p.y = 0 and p.y0))) -> <bdd 23n 7p> [forward reach with edge: (event: e) (guard: p.x = 2 and p.l1 or p.x = 1 and p.l1) (assignments: p.y := 1, p.z := 1, p := p.y1), restricted to current/previous controlled-behavior predicate: <bdd 21n 14p>]
+Forward controlled-behavior: <bdd 23n 7p> -> <bdd 27n 8p> [forward reach with edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p.z := 2, p := p.y2), restricted to current/previous controlled-behavior predicate: <bdd 21n 14p>]
+Forward controlled-behavior: <bdd 27n 8p> -> <bdd 28n 9p> [forward reach with edge: (event: e) (guard: p.x = 1 and p.l1) (assignments: p.y := 1, p.z := 2, p := p.y1), restricted to current/previous controlled-behavior predicate: <bdd 21n 14p>]
+Forward controlled-behavior: <bdd 28n 9p> -> <bdd 33n 10p> [forward reach with edge: (event: e) (guard: p.x = 1 and p.l1) (assignments: p.y := 3, p.z := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: <bdd 21n 14p>]
+Forward reachability: iteration 2.
+Forward controlled-behavior: <bdd 33n 10p> [fixed point].
+Controlled behavior: <bdd 21n 14p> -> <bdd 33n 10p>.
+
+Round 1: finished, need another round.
+
+Round 2: started.
+
+Round 2: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3) [marker predicate]
+Backward controlled-behavior: p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3) -> <bdd 29n 7p> [restricted to current/previous controlled-behavior predicate: <bdd 33n 10p>]
+Backward reachability: iteration 1.
+Backward controlled-behavior: <bdd 29n 7p> -> <bdd 32n 9p> [backward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 1) and p.l1) (assignments: p.y := 0, p.z := 1, p := p.y0), restricted to current/previous controlled-behavior predicate: <bdd 33n 10p>]
+Backward controlled-behavior: <bdd 32n 9p> -> <bdd 33n 10p> [backward reach with edge: (event: e) (guard: p.x = 2 and p.l1 or p.x = 1 and p.l1) (assignments: p.y := 1, p.z := 1, p := p.y1), restricted to current/previous controlled-behavior predicate: <bdd 33n 10p>]
+Backward reachability: iteration 2.
+Backward controlled-behavior: <bdd 33n 10p> [fixed point].
+
+Round 2: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: <bdd 33n 52p> [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 2: finished, controlled behavior is stable.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: <bdd 33n 10p>)
+    Edge: (event: e) (guard: (p.x = 0 or p.x = 1) and p.l1) (assignments: p.y := 0, p.z := 1, p := p.y0)
+    Edge: (event: e) (guard: p.x = 2 and p.l1 or p.x = 1 and p.l1) (assignments: p.y := 1, p.z := 1, p := p.y1)
+    Edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 0, p.z := 1, p := p.y0)
+    Edge: (event: e) (guard: p.x = 0 and p.l1) (assignments: p.y := 2, p.z := 2, p := p.y2)
+    Edge: (event: e) (guard: p.x = 1 and p.l1) (assignments: p.y := 1, p.z := 2, p := p.y1)
+    Edge: (event: e) (guard: p.x = 1 and p.l1) (assignments: p.y := 3, p.z := 3, p := p.y3)
+
+Controlled system:                     exactly 10 states.
+
+Initial (synthesis result):            <bdd 33n 10p>
+Initial (uncontrolled system):         p.z = 0 and (p.y = 0 and p.l1)
+Initial (controlled system):           (p.x = 0 or p.x = 2) and p.z = 0 and (p.y = 0 and p.l1) or p.x = 1 and p.z = 0 and (p.y = 0 and p.l1)
+Initial (removed by supervisor):       p.x = 3 and p.z = 0 and (p.y = 0 and p.l1)
+Initial (added by supervisor):         p.x != 3 or p.z != 0 or (p.y != 0 or not p.l1)
+
+Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
+  Initial: (p.x = 0 or p.x = 2) and p.z = 0 and (p.y = 0 and p.l1) or p.x = 1 and p.z = 0 and (p.y = 0 and p.l1) -> p.x != 3 [assume p.z = 0 and (p.y = 0 and p.l1)].
+
+Constructing output CIF specification.
+Writing output CIF file "datasynth/edge_granularity_guards_updates8_per_edge.ctrlsys.real.cif".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates8_per_edge.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates8_per_edge.ctrlsys.cif
new file mode 100644
index 0000000000000000000000000000000000000000..26768ce6710ea18475a395434bc4954e3c97f91d
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates8_per_edge.ctrlsys.cif
@@ -0,0 +1,29 @@
+uncontrollable e;
+plant automaton p:
+  disc int[0..3] x in any;
+  disc int[0..3] y;
+  disc int[0..3] z;
+  location l1:
+    initial;
+    edge e when x = 0 or x = 1 do y := 0, z := 1 goto y0;
+    edge e when x = 1 or x = 2 do y := 1, z := 1 goto y1;
+    edge e when x = 0 do y := 0, z := 1 goto y0;
+    edge e when x = 0 do y := 2, z := 2 goto y2;
+    edge e when x = 1 do y := 1, z := 2 goto y1;
+    edge e when x = 1 do y := 3, z := 3 goto y3;
+  location y0:
+    marked y = 0;
+  location y1:
+    marked y = 1;
+  location y2:
+    marked y = 2;
+  location y3:
+    marked y = 3;
+end
+supervisor automaton sup:
+  alphabet;
+  initial p.x != 3;
+  location:
+    initial;
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates8_per_edge.statespace.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates8_per_edge.statespace.cif
new file mode 100644
index 0000000000000000000000000000000000000000..09b5124469eb70b8250efe1c8ef9f7ddc69cf0ba
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates8_per_edge.statespace.cif
@@ -0,0 +1,31 @@
+uncontrollable e;
+automaton statespace:
+  alphabet e;
+  location loc1:
+    initial;
+    edge e goto loc4;
+    edge e goto loc5;
+  location loc2:
+    initial;
+    edge e goto loc6;
+    edge e goto loc7;
+    edge e goto loc8;
+    edge e goto loc9;
+  location loc3:
+    initial;
+    edge e goto loc10;
+  location loc4:
+    marked;
+  location loc5:
+    marked;
+  location loc6:
+    marked;
+  location loc7:
+    marked;
+  location loc8:
+    marked;
+  location loc9:
+    marked;
+  location loc10:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates8_per_event.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates8_per_event.cif
new file mode 100644
index 0000000000000000000000000000000000000000..6d1ea58259c6762b3b86791ead2a92af653875d9
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates8_per_event.cif
@@ -0,0 +1,43 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+
+plant p:
+  disc int[0..3] x in any;
+  disc int[0..3] y;
+  disc int[0..3] z;
+
+  location l1: // x in {0, 1, 2}, y = 0, z = 0
+    initial;
+
+    // Partially overlapping guards, different and same updates, and a second variable as well.
+    edge e when x = 0 or x = 1 do y := 0, z := 1 goto y0;
+    edge e when x = 1 or x = 2 do y := 1, z := 1 goto y1;
+    edge e when x = 0          do y := 0, z := 1 goto y0;
+    edge e when x = 0          do y := 2, z := 2 goto y2;
+    edge e when x = 1          do y := 1, z := 2 goto y1;
+    edge e when x = 1          do y := 3, z := 3 goto y3;
+
+  location y0: // x in {0, 1}, y = 0, z = 1
+    marked y = 0;
+
+  location y1: // x in {1, 2}, y = 1, z in {1, 2}, but not (x = 2 and z = 2)
+    marked y = 1;
+
+  location y2: // x = 0, y = 2, z = 2
+    marked y = 2;
+
+  location y3: // x = 1, y = 3, z = 3
+    marked y = 3;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates8_per_event.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates8_per_event.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..27d3a351e22f1b844062e54fc8e1234f00db5a8b
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates8_per_event.cif.out
@@ -0,0 +1,230 @@
+Reading CIF file "datasynth/edge_granularity_guards_updates8_per_event.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p     0      3 * 2     5 * 2       8 * 2       ~63%
+  2      discrete variable  int[0..3]  p.x   1      2 * 2     4 * 2       4 * 2       100%
+  3      discrete variable  int[0..3]  p.y   2      2 * 2     4 * 2       4 * 2       100%
+  4      discrete variable  int[0..3]  p.z   3      2 * 2     4 * 2       4 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      4      18        34          40          85%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 21
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 6
+
+        Total span:   3 (total)   0.14 (avg/edge) / WES:   0.297619 (total)   0.014172 (avg/edge) [before]
+        Total span:   3 (total)   0.14 (avg/edge) / WES:   0.297619 (total)   0.014172 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 6
+
+        Total span:   3 (total)   0.14 (avg/edge) / WES:   0.297619 (total)   0.014172 (avg/edge) [before]
+        Total span:   3 (total)   0.14 (avg/edge) / WES:   0.321429 (total)   0.015306 (avg/edge) [after]
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 6
+
+          Total span:   3 (total)   0.14 (avg/edge) / WES:   0.297619 (total)   0.014172 (avg/edge) [before]
+          Total span:   3 (total)   0.14 (avg/edge) / WES:   0.297619 (total)   0.014172 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 21
+
+          Total span:   3 (total)   0.14 (avg/edge) / WES:   0.297619 (total)   0.014172 (avg/edge) [before]
+          Total span:   3 (total)   0.14 (avg/edge) / WES:   0.297619 (total)   0.014172 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 6
+
+          Total span:   3 (total)   0.14 (avg/edge) / WES:   0.297619 (total)   0.014172 (avg/edge) [before]
+          Total span:   3 (total)   0.14 (avg/edge) / WES:   0.321429 (total)   0.015306 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 21
+
+          Total span:   3 (total)   0.14 (avg/edge) / WES:   0.321429 (total)   0.015306 (avg/edge) [before]
+          Total span:   3 (total)   0.14 (avg/edge) / WES:   0.321429 (total)   0.015306 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 6
+      Maximum number of iterations: 20
+
+      Total span:   18 (total)   3.00 (avg/edge) / WES:   1.500000 (total)   0.250000 (avg/edge) [before]
+      Total span:   18 (total)   3.00 (avg/edge) / WES:   1.500000 (total)   0.250000 (avg/edge) [iteration 1]
+      Total span:   18 (total)   3.00 (avg/edge) / WES:   1.500000 (total)   0.250000 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 6
+      Window length: 4
+
+      Total span:   18 (total)   3.00 (avg/edge) / WES:   1.500000 (total)   0.250000 (avg/edge) [before]
+      Total span:   18 (total)   3.00 (avg/edge) / WES:   1.500000 (total)   0.250000 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..3]  p.x   0      2 * 2     4 * 2       4 * 2       100%
+  2      discrete variable  int[0..3]  p.z   1      2 * 2     4 * 2       4 * 2       100%
+  3      discrete variable  int[0..3]  p.y   2      2 * 2     4 * 2       4 * 2       100%
+  4      location pointer   n/a        p     3      3 * 2     5 * 2       8 * 2       ~63%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      4      18        34          40          85%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variable 1):             p.z = 0
+Initial   (discrete variable 2):             p.y = 0
+Initial   (discrete variables):              p.z = 0 and p.y = 0
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p.l1
+Initial   (auts/locs init predicate):        p.l1
+Initial   (uncontrolled system):             p.z = 0 and (p.y = 0 and p.l1)
+Initial   (system, combined init/plant inv): p.z = 0 and (p.y = 0 and p.l1)
+Initial   (system, combined init/state inv): p.z = 0 and (p.y = 0 and p.l1)
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3)
+Marked    (auts/locs marker predicate):      p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3)
+Marked    (uncontrolled system):             p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3)
+Marked    (system, combined mark/plant inv): p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3)
+Marked    (system, combined mark/state inv): p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3)
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  None
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: (p.x = 0 or p.x = 2) and p.l1 or p.x = 1 and p.l1) (assignments: p.y := 0, p.z := 1, p := p.y0 / p.y := 1, p.z := 1, p := p.y1 / p.y := 0, p.z := 1, p := p.y0 / p.y := 2, p.z := 2, p := p.y2 / p.y := 1, p.z := 2, p := p.y1 / p.y := 3, p.z := 3, p := p.y3)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p.z = 0 and (p.y = 0 and p.l1).
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Controlled behavior: true -> true [range: true, variable: location pointer for automaton "p" (group: 3, domain: 6+7, BDD variables: 3, CIF/BDD values: 5/8)].
+
+Extended controlled-behavior predicate using variable ranges: true.
+
+Restricting behavior using state/event exclusion requirements.
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3) [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3) -> <bdd 21n 14p> [backward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 2) and p.l1 or p.x = 1 and p.l1) (assignments: p.y := 0, p.z := 1, p := p.y0 / p.y := 1, p.z := 1, p := p.y1 / p.y := 0, p.z := 1, p := p.y0 / p.y := 2, p.z := 2, p := p.y2 / p.y := 1, p.z := 2, p := p.y1 / p.y := 3, p.z := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 2.
+Backward controlled-behavior: <bdd 21n 14p> [fixed point].
+Controlled behavior: true -> <bdd 21n 14p>.
+
+Round 1: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: <bdd 21n 32p> [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 1: computing forward controlled-behavior predicate.
+Forward controlled-behavior: p.z = 0 and (p.y = 0 and p.l1) [initialization predicate]
+Forward controlled-behavior: p.z = 0 and (p.y = 0 and p.l1) -> (p.x = 0 or p.x = 2) and p.z = 0 and (p.y = 0 and p.l1) or p.x = 1 and p.z = 0 and (p.y = 0 and p.l1) [restricted to current/previous controlled-behavior predicate: <bdd 21n 14p>]
+Forward reachability: iteration 1.
+Forward controlled-behavior: (p.x = 0 or p.x = 2) and p.z = 0 and (p.y = 0 and p.l1) or p.x = 1 and p.z = 0 and (p.y = 0 and p.l1) -> <bdd 33n 10p> [forward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 2) and p.l1 or p.x = 1 and p.l1) (assignments: p.y := 0, p.z := 1, p := p.y0 / p.y := 1, p.z := 1, p := p.y1 / p.y := 0, p.z := 1, p := p.y0 / p.y := 2, p.z := 2, p := p.y2 / p.y := 1, p.z := 2, p := p.y1 / p.y := 3, p.z := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: <bdd 21n 14p>]
+Forward reachability: iteration 2.
+Forward controlled-behavior: <bdd 33n 10p> [fixed point].
+Controlled behavior: <bdd 21n 14p> -> <bdd 33n 10p>.
+
+Round 1: finished, need another round.
+
+Round 2: started.
+
+Round 2: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3) [marker predicate]
+Backward controlled-behavior: p.y = 0 and p.y0 or p.y = 2 and p.y2 or (p.y = 1 and p.y1 or p.y = 3 and p.y3) -> <bdd 29n 7p> [restricted to current/previous controlled-behavior predicate: <bdd 33n 10p>]
+Backward reachability: iteration 1.
+Backward controlled-behavior: <bdd 29n 7p> -> <bdd 33n 10p> [backward reach with edge: (event: e) (guard: (p.x = 0 or p.x = 2) and p.l1 or p.x = 1 and p.l1) (assignments: p.y := 0, p.z := 1, p := p.y0 / p.y := 1, p.z := 1, p := p.y1 / p.y := 0, p.z := 1, p := p.y0 / p.y := 2, p.z := 2, p := p.y2 / p.y := 1, p.z := 2, p := p.y1 / p.y := 3, p.z := 3, p := p.y3), restricted to current/previous controlled-behavior predicate: <bdd 33n 10p>]
+Backward reachability: iteration 2.
+Backward controlled-behavior: <bdd 33n 10p> [fixed point].
+
+Round 2: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: <bdd 33n 52p> [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 2: finished, controlled behavior is stable.
+
+Computing controlled system guards.
+
+Final synthesis result:
+  State: (controlled-behavior: <bdd 33n 10p>)
+    Edge: (event: e) (guard: (p.x = 0 or p.x = 2) and p.l1 or p.x = 1 and p.l1) (assignments: p.y := 0, p.z := 1, p := p.y0 / p.y := 1, p.z := 1, p := p.y1 / p.y := 0, p.z := 1, p := p.y0 / p.y := 2, p.z := 2, p := p.y2 / p.y := 1, p.z := 2, p := p.y1 / p.y := 3, p.z := 3, p := p.y3)
+
+Controlled system:                     exactly 10 states.
+
+Initial (synthesis result):            <bdd 33n 10p>
+Initial (uncontrolled system):         p.z = 0 and (p.y = 0 and p.l1)
+Initial (controlled system):           (p.x = 0 or p.x = 2) and p.z = 0 and (p.y = 0 and p.l1) or p.x = 1 and p.z = 0 and (p.y = 0 and p.l1)
+Initial (removed by supervisor):       p.x = 3 and p.z = 0 and (p.y = 0 and p.l1)
+Initial (added by supervisor):         p.x != 3 or p.z != 0 or (p.y != 0 or not p.l1)
+
+Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
+  Initial: (p.x = 0 or p.x = 2) and p.z = 0 and (p.y = 0 and p.l1) or p.x = 1 and p.z = 0 and (p.y = 0 and p.l1) -> p.x != 3 [assume p.z = 0 and (p.y = 0 and p.l1)].
+
+Constructing output CIF specification.
+Writing output CIF file "datasynth/edge_granularity_guards_updates8_per_event.ctrlsys.real.cif".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates8_per_event.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates8_per_event.ctrlsys.cif
new file mode 100644
index 0000000000000000000000000000000000000000..26768ce6710ea18475a395434bc4954e3c97f91d
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates8_per_event.ctrlsys.cif
@@ -0,0 +1,29 @@
+uncontrollable e;
+plant automaton p:
+  disc int[0..3] x in any;
+  disc int[0..3] y;
+  disc int[0..3] z;
+  location l1:
+    initial;
+    edge e when x = 0 or x = 1 do y := 0, z := 1 goto y0;
+    edge e when x = 1 or x = 2 do y := 1, z := 1 goto y1;
+    edge e when x = 0 do y := 0, z := 1 goto y0;
+    edge e when x = 0 do y := 2, z := 2 goto y2;
+    edge e when x = 1 do y := 1, z := 2 goto y1;
+    edge e when x = 1 do y := 3, z := 3 goto y3;
+  location y0:
+    marked y = 0;
+  location y1:
+    marked y = 1;
+  location y2:
+    marked y = 2;
+  location y3:
+    marked y = 3;
+end
+supervisor automaton sup:
+  alphabet;
+  initial p.x != 3;
+  location:
+    initial;
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates8_per_event.statespace.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates8_per_event.statespace.cif
new file mode 100644
index 0000000000000000000000000000000000000000..09b5124469eb70b8250efe1c8ef9f7ddc69cf0ba
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_guards_updates8_per_event.statespace.cif
@@ -0,0 +1,31 @@
+uncontrollable e;
+automaton statespace:
+  alphabet e;
+  location loc1:
+    initial;
+    edge e goto loc4;
+    edge e goto loc5;
+  location loc2:
+    initial;
+    edge e goto loc6;
+    edge e goto loc7;
+    edge e goto loc8;
+    edge e goto loc9;
+  location loc3:
+    initial;
+    edge e goto loc10;
+  location loc4:
+    marked;
+  location loc5:
+    marked;
+  location loc6:
+    marked;
+  location loc7:
+    marked;
+  location loc8:
+    marked;
+  location loc9:
+    marked;
+  location loc10:
+    marked;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_simple_per_edge.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_simple_per_edge.cif
new file mode 100644
index 0000000000000000000000000000000000000000..9ed00e7074ae3cabfd8ab7294c4ec72ed9d40201
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_simple_per_edge.cif
@@ -0,0 +1,44 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+controllable a, b;
+
+plant p1:
+  location l1:
+    initial;
+    marked;
+    edge e goto l2;
+
+  location l2:
+    edge e goto l1;
+end
+
+plant p2:
+  disc int[0..3] x in any;
+
+  location l1:
+    initial;
+    marked;
+    edge e when x = 1 goto l1;
+    edge e when x = 2 goto l2;
+    edge e when x = 3 goto l3;
+
+  location l2:
+    edge a goto l1;
+
+  location l3:
+    edge b goto l1;
+end
+
+requirement true disables b;
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_simple_per_edge.cif.err b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_simple_per_edge.cif.err
new file mode 100644
index 0000000000000000000000000000000000000000..e8c691af6aa6688bb81db47d27e318222666d949
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_simple_per_edge.cif.err
@@ -0,0 +1 @@
+WARNING: Event "b" is never enabled in the input specification, taking into account only state/event exclusion requirements.
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_simple_per_edge.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_simple_per_edge.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..176547ea312403d987e3bb9c86bff2d8bc852f20
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_simple_per_edge.cif.out
@@ -0,0 +1,277 @@
+Reading CIF file "datasynth/edge_granularity_simple_per_edge.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p1    0      1 * 2     2 * 2       2 * 2       100%
+  2      location pointer   n/a        p2    1      2 * 2     3 * 2       4 * 2       75%
+  3      discrete variable  int[0..3]  p2.x  2      2 * 2     4 * 2       4 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      3      10        18          20          90%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 6
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 3
+
+        Total span:   2 (total)   0.33 (avg/edge) / WES:   0.518519 (total)   0.086420 (avg/edge) [before]
+        Total span:   2 (total)   0.33 (avg/edge) / WES:   0.518519 (total)   0.086420 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 3
+
+        Total span:   2 (total)   0.33 (avg/edge) / WES:   0.518519 (total)   0.086420 (avg/edge) [before]
+        Total span:   2 (total)   0.33 (avg/edge) / WES:   0.481481 (total)   0.080247 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 3
+
+          Total span:   2 (total)   0.33 (avg/edge) / WES:   0.518519 (total)   0.086420 (avg/edge) [before]
+          Total span:   2 (total)   0.33 (avg/edge) / WES:   0.518519 (total)   0.086420 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 6
+
+          Total span:   2 (total)   0.33 (avg/edge) / WES:   0.518519 (total)   0.086420 (avg/edge) [before]
+          Total span:   2 (total)   0.33 (avg/edge) / WES:   0.518519 (total)   0.086420 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 3
+
+          Total span:   2 (total)   0.33 (avg/edge) / WES:   0.518519 (total)   0.086420 (avg/edge) [before]
+          Total span:   2 (total)   0.33 (avg/edge) / WES:   0.481481 (total)   0.080247 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 6
+
+          Total span:   2 (total)   0.33 (avg/edge) / WES:   0.481481 (total)   0.080247 (avg/edge) [before]
+          Total span:   2 (total)   0.33 (avg/edge) / WES:   0.481481 (total)   0.080247 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 8
+      Maximum number of iterations: 20
+
+      Total span:   12 (total)   1.50 (avg/edge) / WES:   1.055556 (total)   0.131944 (avg/edge) [before]
+      Total span:   12 (total)   1.50 (avg/edge) / WES:   1.055556 (total)   0.131944 (avg/edge) [iteration 1]
+      Total span:   12 (total)   1.50 (avg/edge) / WES:   1.055556 (total)   0.131944 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 8
+      Window length: 3
+
+      Total span:   12 (total)   1.50 (avg/edge) / WES:   1.055556 (total)   0.131944 (avg/edge) [before]
+      Total span:   12 (total)   1.50 (avg/edge) / WES:   1.055556 (total)   0.131944 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..3]  p2.x  0      2 * 2     4 * 2       4 * 2       100%
+  2      location pointer   n/a        p2    1      2 * 2     3 * 2       4 * 2       75%
+  3      location pointer   n/a        p1    2      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      3      10        18          20          90%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p1.l1
+Initial   (aut/locs init predicate):         p2.l1
+Initial   (auts/locs init predicate):        p2.l1 and p1.l1
+Initial   (uncontrolled system):             p2.l1 and p1.l1
+Initial   (system, combined init/plant inv): p2.l1 and p1.l1
+Initial   (system, combined init/state inv): p2.l1 and p1.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p1.l1
+Marked    (aut/locs marker predicate):       p2.l1
+Marked    (auts/locs marker predicate):      p2.l1 and p1.l1
+Marked    (uncontrolled system):             p2.l1 and p1.l1
+Marked    (system, combined mark/plant inv): p2.l1 and p1.l1
+Marked    (system, combined mark/state inv): p2.l1 and p1.l1
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  Event "b" needs:
+    false
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: p2.x = 1 and (p2.l1 and p1.l1)) (assignments: p1 := p1.l2)
+    Edge: (event: e) (guard: p2.x = 2 and (p2.l1 and p1.l1)) (assignments: p1 := p1.l2, p2 := p2.l2)
+    Edge: (event: e) (guard: p2.x = 3 and (p2.l1 and p1.l1)) (assignments: p1 := p1.l2, p2 := p2.l3)
+    Edge: (event: e) (guard: p2.x = 1 and (p2.l1 and p1.l2)) (assignments: p1 := p1.l1)
+    Edge: (event: e) (guard: p2.x = 2 and (p2.l1 and p1.l2)) (assignments: p1 := p1.l1, p2 := p2.l2)
+    Edge: (event: e) (guard: p2.x = 3 and (p2.l1 and p1.l2)) (assignments: p1 := p1.l1, p2 := p2.l3)
+    Edge: (event: a) (guard: p2.l2) (assignments: p2 := p2.l1)
+    Edge: (event: b) (guard: p2.l3) (assignments: p2 := p2.l1)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p2.l1 and p1.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Controlled behavior: true -> true [range: true, variable: location pointer for automaton "p2" (group: 1, domain: 2+3, BDD variables: 2, CIF/BDD values: 3/4)].
+
+Extended controlled-behavior predicate using variable ranges: true.
+
+Restricting behavior using state/event exclusion requirements.
+
+Edge (event: b) (guard: p2.l3) (assignments: p2 := p2.l1): guard: p2.l3 -> false [state/event exclusion requirement: false].
+
+Restricted behavior using state/event exclusion requirements:
+  State: (controlled-behavior: true)
+    Edge: (event: e) (guard: p2.x = 1 and (p2.l1 and p1.l1)) (assignments: p1 := p1.l2)
+    Edge: (event: e) (guard: p2.x = 2 and (p2.l1 and p1.l1)) (assignments: p1 := p1.l2, p2 := p2.l2)
+    Edge: (event: e) (guard: p2.x = 3 and (p2.l1 and p1.l1)) (assignments: p1 := p1.l2, p2 := p2.l3)
+    Edge: (event: e) (guard: p2.x = 1 and (p2.l1 and p1.l2)) (assignments: p1 := p1.l1)
+    Edge: (event: e) (guard: p2.x = 2 and (p2.l1 and p1.l2)) (assignments: p1 := p1.l1, p2 := p2.l2)
+    Edge: (event: e) (guard: p2.x = 3 and (p2.l1 and p1.l2)) (assignments: p1 := p1.l1, p2 := p2.l3)
+    Edge: (event: a) (guard: p2.l2) (assignments: p2 := p2.l1)
+    Edge: (event: b) (guard: p2.l3 -> false) (assignments: p2 := p2.l1)
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p2.l1 and p1.l1 [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p2.l1 and p1.l1 -> (p2.x = 0 or p2.x = 2) and (p2.l1 and p1.l1) or (p2.x = 1 and p2.l1 or p2.x = 3 and (p2.l1 and p1.l1)) [backward reach with edge: (event: e) (guard: p2.x = 1 and (p2.l1 and p1.l2)) (assignments: p1 := p1.l1), restricted to current/previous controlled-behavior predicate: true]
+Backward controlled-behavior: (p2.x = 0 or p2.x = 2) and (p2.l1 and p1.l1) or (p2.x = 1 and p2.l1 or p2.x = 3 and (p2.l1 and p1.l1)) -> (p2.x = 0 or p2.x = 2) and (not p2.l3 and p1.l1) or (p2.x = 1 and not p2.l3 or p2.x = 3 and (not p2.l3 and p1.l1)) [backward reach with edge: (event: a) (guard: p2.l2) (assignments: p2 := p2.l1), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 2.
+Backward controlled-behavior: (p2.x = 0 or p2.x = 2) and (not p2.l3 and p1.l1) or (p2.x = 1 and not p2.l3 or p2.x = 3 and (not p2.l3 and p1.l1)) -> p2.x = 0 and (not p2.l3 and p1.l1) or p2.x = 2 and p2.l1 or (p2.x = 2 and (p2.l2 and p1.l1) or (p2.x = 1 and not p2.l3 or p2.x = 3 and (not p2.l3 and p1.l1))) [backward reach with edge: (event: e) (guard: p2.x = 2 and (p2.l1 and p1.l2)) (assignments: p1 := p1.l1, p2 := p2.l2), restricted to current/previous controlled-behavior predicate: true]
+Backward controlled-behavior: p2.x = 0 and (not p2.l3 and p1.l1) or p2.x = 2 and p2.l1 or (p2.x = 2 and (p2.l2 and p1.l1) or (p2.x = 1 and not p2.l3 or p2.x = 3 and (not p2.l3 and p1.l1))) -> p2.x = 0 and (not p2.l3 and p1.l1) or p2.x = 2 and not p2.l3 or (p2.x = 1 and not p2.l3 or p2.x = 3 and (not p2.l3 and p1.l1)) [backward reach with edge: (event: a) (guard: p2.l2) (assignments: p2 := p2.l1), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 3.
+Backward controlled-behavior: p2.x = 0 and (not p2.l3 and p1.l1) or p2.x = 2 and not p2.l3 or (p2.x = 1 and not p2.l3 or p2.x = 3 and (not p2.l3 and p1.l1)) [fixed point].
+Controlled behavior: true -> p2.x = 0 and (not p2.l3 and p1.l1) or p2.x = 2 and not p2.l3 or (p2.x = 1 and not p2.l3 or p2.x = 3 and (not p2.l3 and p1.l1)).
+
+Round 1: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p2.x != 0 or (p2.l3 or p1.l2)) and (p2.x != 2 or p2.l3) and ((p2.x != 1 or p2.l3) and (p2.x != 3 or (p2.l3 or p1.l2))) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+Backward uncontrolled bad-state: (p2.x != 0 or (p2.l3 or p1.l2)) and (p2.x != 2 or p2.l3) and ((p2.x != 1 or p2.l3) and (p2.x != 3 or (p2.l3 or p1.l2))) -> (p2.x != 0 or (p2.l3 or p1.l2)) and (p2.x != 2 or p2.l3) and ((p2.x != 1 or p2.l3) and (p2.x != 3 or (not p2.l2 or p1.l2))) [backward reach with edge: (event: e) (guard: p2.x = 3 and (p2.l1 and p1.l1)) (assignments: p1 := p1.l2, p2 := p2.l3)]
+Backward reachability: iteration 2.
+Backward uncontrolled bad-state: (p2.x != 0 or (p2.l3 or p1.l2)) and (p2.x != 2 or p2.l3) and ((p2.x != 1 or p2.l3) and (p2.x != 3 or (not p2.l2 or p1.l2))) [fixed point].
+Controlled behavior: p2.x = 0 and (not p2.l3 and p1.l1) or p2.x = 2 and not p2.l3 or (p2.x = 1 and not p2.l3 or p2.x = 3 and (not p2.l3 and p1.l1)) -> p2.x = 0 and (not p2.l3 and p1.l1) or p2.x = 2 and not p2.l3 or (p2.x = 1 and not p2.l3 or p2.x = 3 and (p2.l2 and p1.l1)).
+
+Round 1: computing forward controlled-behavior predicate.
+Forward controlled-behavior: p2.l1 and p1.l1 [initialization predicate]
+Forward controlled-behavior: p2.l1 and p1.l1 -> (p2.x = 0 or p2.x = 2) and (p2.l1 and p1.l1) or p2.x = 1 and (p2.l1 and p1.l1) [restricted to current/previous controlled-behavior predicate: p2.x = 0 and (not p2.l3 and p1.l1) or p2.x = 2 and not p2.l3 or (p2.x = 1 and not p2.l3 or p2.x = 3 and (p2.l2 and p1.l1))]
+Forward reachability: iteration 1.
+Forward controlled-behavior: (p2.x = 0 or p2.x = 2) and (p2.l1 and p1.l1) or p2.x = 1 and (p2.l1 and p1.l1) -> (p2.x = 0 or p2.x = 2) and (p2.l1 and p1.l1) or p2.x = 1 and p2.l1 [forward reach with edge: (event: e) (guard: p2.x = 1 and (p2.l1 and p1.l1)) (assignments: p1 := p1.l2), restricted to current/previous controlled-behavior predicate: p2.x = 0 and (not p2.l3 and p1.l1) or p2.x = 2 and not p2.l3 or (p2.x = 1 and not p2.l3 or p2.x = 3 and (p2.l2 and p1.l1))]
+Forward controlled-behavior: (p2.x = 0 or p2.x = 2) and (p2.l1 and p1.l1) or p2.x = 1 and p2.l1 -> p2.x = 0 and (p2.l1 and p1.l1) or p2.x = 2 and (p2.l1 and p1.l1) or (p2.x = 2 and (p2.l2 and p1.l2) or p2.x = 1 and p2.l1) [forward reach with edge: (event: e) (guard: p2.x = 2 and (p2.l1 and p1.l1)) (assignments: p1 := p1.l2, p2 := p2.l2), restricted to current/previous controlled-behavior predicate: p2.x = 0 and (not p2.l3 and p1.l1) or p2.x = 2 and not p2.l3 or (p2.x = 1 and not p2.l3 or p2.x = 3 and (p2.l2 and p1.l1))]
+Forward controlled-behavior: p2.x = 0 and (p2.l1 and p1.l1) or p2.x = 2 and (p2.l1 and p1.l1) or (p2.x = 2 and (p2.l2 and p1.l2) or p2.x = 1 and p2.l1) -> p2.x = 0 and (p2.l1 and p1.l1) or p2.x = 2 and p2.l1 or (p2.x = 2 and (p2.l2 and p1.l2) or p2.x = 1 and p2.l1) [forward reach with edge: (event: a) (guard: p2.l2) (assignments: p2 := p2.l1), restricted to current/previous controlled-behavior predicate: p2.x = 0 and (not p2.l3 and p1.l1) or p2.x = 2 and not p2.l3 or (p2.x = 1 and not p2.l3 or p2.x = 3 and (p2.l2 and p1.l1))]
+Forward reachability: iteration 2.
+Forward controlled-behavior: p2.x = 0 and (p2.l1 and p1.l1) or p2.x = 2 and p2.l1 or (p2.x = 2 and (p2.l2 and p1.l2) or p2.x = 1 and p2.l1) -> p2.x = 0 and (p2.l1 and p1.l1) or (p2.x = 2 and not p2.l3 or p2.x = 1 and p2.l1) [forward reach with edge: (event: e) (guard: p2.x = 2 and (p2.l1 and p1.l2)) (assignments: p1 := p1.l1, p2 := p2.l2), restricted to current/previous controlled-behavior predicate: p2.x = 0 and (not p2.l3 and p1.l1) or p2.x = 2 and not p2.l3 or (p2.x = 1 and not p2.l3 or p2.x = 3 and (p2.l2 and p1.l1))]
+Forward reachability: iteration 3.
+Forward controlled-behavior: p2.x = 0 and (p2.l1 and p1.l1) or (p2.x = 2 and not p2.l3 or p2.x = 1 and p2.l1) [fixed point].
+Controlled behavior: p2.x = 0 and (not p2.l3 and p1.l1) or p2.x = 2 and not p2.l3 or (p2.x = 1 and not p2.l3 or p2.x = 3 and (p2.l2 and p1.l1)) -> p2.x = 0 and (p2.l1 and p1.l1) or (p2.x = 2 and not p2.l3 or p2.x = 1 and p2.l1).
+
+Round 1: finished, need another round.
+
+Round 2: started.
+
+Round 2: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p2.l1 and p1.l1 [marker predicate]
+Backward controlled-behavior: p2.l1 and p1.l1 -> (p2.x = 0 or p2.x = 2) and (p2.l1 and p1.l1) or p2.x = 1 and (p2.l1 and p1.l1) [restricted to current/previous controlled-behavior predicate: p2.x = 0 and (p2.l1 and p1.l1) or (p2.x = 2 and not p2.l3 or p2.x = 1 and p2.l1)]
+Backward reachability: iteration 1.
+Backward controlled-behavior: (p2.x = 0 or p2.x = 2) and (p2.l1 and p1.l1) or p2.x = 1 and (p2.l1 and p1.l1) -> (p2.x = 0 or p2.x = 2) and (p2.l1 and p1.l1) or p2.x = 1 and p2.l1 [backward reach with edge: (event: e) (guard: p2.x = 1 and (p2.l1 and p1.l2)) (assignments: p1 := p1.l1), restricted to current/previous controlled-behavior predicate: p2.x = 0 and (p2.l1 and p1.l1) or (p2.x = 2 and not p2.l3 or p2.x = 1 and p2.l1)]
+Backward controlled-behavior: (p2.x = 0 or p2.x = 2) and (p2.l1 and p1.l1) or p2.x = 1 and p2.l1 -> p2.x = 0 and (p2.l1 and p1.l1) or (p2.x = 2 and (not p2.l3 and p1.l1) or p2.x = 1 and p2.l1) [backward reach with edge: (event: a) (guard: p2.l2) (assignments: p2 := p2.l1), restricted to current/previous controlled-behavior predicate: p2.x = 0 and (p2.l1 and p1.l1) or (p2.x = 2 and not p2.l3 or p2.x = 1 and p2.l1)]
+Backward reachability: iteration 2.
+Backward controlled-behavior: p2.x = 0 and (p2.l1 and p1.l1) or (p2.x = 2 and (not p2.l3 and p1.l1) or p2.x = 1 and p2.l1) -> p2.x = 0 and (p2.l1 and p1.l1) or p2.x = 2 and p2.l1 or (p2.x = 2 and (p2.l2 and p1.l1) or p2.x = 1 and p2.l1) [backward reach with edge: (event: e) (guard: p2.x = 2 and (p2.l1 and p1.l2)) (assignments: p1 := p1.l1, p2 := p2.l2), restricted to current/previous controlled-behavior predicate: p2.x = 0 and (p2.l1 and p1.l1) or (p2.x = 2 and not p2.l3 or p2.x = 1 and p2.l1)]
+Backward controlled-behavior: p2.x = 0 and (p2.l1 and p1.l1) or p2.x = 2 and p2.l1 or (p2.x = 2 and (p2.l2 and p1.l1) or p2.x = 1 and p2.l1) -> p2.x = 0 and (p2.l1 and p1.l1) or (p2.x = 2 and not p2.l3 or p2.x = 1 and p2.l1) [backward reach with edge: (event: a) (guard: p2.l2) (assignments: p2 := p2.l1), restricted to current/previous controlled-behavior predicate: p2.x = 0 and (p2.l1 and p1.l1) or (p2.x = 2 and not p2.l3 or p2.x = 1 and p2.l1)]
+Backward reachability: iteration 3.
+Backward controlled-behavior: p2.x = 0 and (p2.l1 and p1.l1) or (p2.x = 2 and not p2.l3 or p2.x = 1 and p2.l1) [fixed point].
+
+Round 2: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p2.x != 0 or (not p2.l1 or p1.l2)) and ((p2.x != 2 or p2.l3) and (p2.x != 1 or not p2.l1)) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 2: finished, controlled behavior is stable.
+
+Computing controlled system guards.
+
+Edge (event: a) (guard: p2.l2) (assignments: p2 := p2.l1): guard: p2.l2 -> p2.x = 0 and (p2.l2 and p1.l1) or (p2.x = 2 and p2.l2 or p2.x = 1 and p2.l2).
+
+Final synthesis result:
+  State: (controlled-behavior: p2.x = 0 and (p2.l1 and p1.l1) or (p2.x = 2 and not p2.l3 or p2.x = 1 and p2.l1))
+    Edge: (event: e) (guard: p2.x = 1 and (p2.l1 and p1.l1)) (assignments: p1 := p1.l2)
+    Edge: (event: e) (guard: p2.x = 2 and (p2.l1 and p1.l1)) (assignments: p1 := p1.l2, p2 := p2.l2)
+    Edge: (event: e) (guard: p2.x = 3 and (p2.l1 and p1.l1)) (assignments: p1 := p1.l2, p2 := p2.l3)
+    Edge: (event: e) (guard: p2.x = 1 and (p2.l1 and p1.l2)) (assignments: p1 := p1.l1)
+    Edge: (event: e) (guard: p2.x = 2 and (p2.l1 and p1.l2)) (assignments: p1 := p1.l1, p2 := p2.l2)
+    Edge: (event: e) (guard: p2.x = 3 and (p2.l1 and p1.l2)) (assignments: p1 := p1.l1, p2 := p2.l3)
+    Edge: (event: a) (guard: p2.l2 -> p2.x = 0 and (p2.l2 and p1.l1) or (p2.x = 2 and p2.l2 or p2.x = 1 and p2.l2)) (assignments: p2 := p2.l1)
+    Edge: (event: b) (guard: p2.l3 -> false) (assignments: p2 := p2.l1)
+
+Controlled system:                     exactly 7 states.
+
+Initial (synthesis result):            p2.x = 0 and (p2.l1 and p1.l1) or (p2.x = 2 and not p2.l3 or p2.x = 1 and p2.l1)
+Initial (uncontrolled system):         p2.l1 and p1.l1
+Initial (controlled system):           (p2.x = 0 or p2.x = 2) and (p2.l1 and p1.l1) or p2.x = 1 and (p2.l1 and p1.l1)
+Initial (removed by supervisor):       p2.x = 3 and (p2.l1 and p1.l1)
+Initial (added by supervisor):         p2.x != 3 or (not p2.l1 or p1.l2)
+
+Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
+  Initial: (p2.x = 0 or p2.x = 2) and (p2.l1 and p1.l1) or p2.x = 1 and (p2.l1 and p1.l1) -> p2.x != 3 [assume p2.l1 and p1.l1].
+
+Simplification of controlled system under the assumption of the plants:
+  Event a: guard: p2.x = 0 and (p2.l2 and p1.l1) or (p2.x = 2 and p2.l2 or p2.x = 1 and p2.l2) -> (p2.x != 0 or p1.l1) and p2.x != 3 [assume p2.l2].
+
+Constructing output CIF specification.
+Writing output CIF file "datasynth/edge_granularity_simple_per_edge.ctrlsys.real.cif".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_simple_per_edge.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_simple_per_edge.ctrlsys.cif
new file mode 100644
index 0000000000000000000000000000000000000000..dcc18c1862550f0a261d14c11cbe438efceac07b
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_simple_per_edge.ctrlsys.cif
@@ -0,0 +1,33 @@
+uncontrollable e;
+controllable a;
+controllable b;
+plant automaton p1:
+  location l1:
+    initial;
+    marked;
+    edge e goto l2;
+  location l2:
+    edge e goto l1;
+end
+plant automaton p2:
+  disc int[0..3] x in any;
+  location l1:
+    initial;
+    marked;
+    edge e when x = 1 goto l1;
+    edge e when x = 2 goto l2;
+    edge e when x = 3 goto l3;
+  location l2:
+    edge a goto l1;
+  location l3:
+    edge b goto l1;
+end
+supervisor automaton sup:
+  alphabet a, b;
+  initial p2.x != 3;
+  location:
+    initial;
+    marked;
+    edge a when (p2.x != 0 or p1.l1) and p2.x != 3;
+    edge b when false;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_simple_per_edge.statespace.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_simple_per_edge.statespace.cif
new file mode 100644
index 0000000000000000000000000000000000000000..9e3e5976f38da4a5edf47d245afaaa74f39971b7
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_simple_per_edge.statespace.cif
@@ -0,0 +1,25 @@
+uncontrollable e;
+controllable a;
+controllable b;
+automaton statespace:
+  alphabet e, a, b;
+  location loc1:
+    initial;
+    marked;
+  location loc2:
+    initial;
+    marked;
+    edge e goto loc4;
+  location loc3:
+    initial;
+    marked;
+    edge e goto loc5;
+  location loc4:
+    edge e goto loc2;
+  location loc5:
+    edge a goto loc6;
+  location loc6:
+    edge e goto loc7;
+  location loc7:
+    edge a goto loc3;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_simple_per_event.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_simple_per_event.cif
new file mode 100644
index 0000000000000000000000000000000000000000..9ed00e7074ae3cabfd8ab7294c4ec72ed9d40201
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_simple_per_event.cif
@@ -0,0 +1,44 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+uncontrollable e;
+controllable a, b;
+
+plant p1:
+  location l1:
+    initial;
+    marked;
+    edge e goto l2;
+
+  location l2:
+    edge e goto l1;
+end
+
+plant p2:
+  disc int[0..3] x in any;
+
+  location l1:
+    initial;
+    marked;
+    edge e when x = 1 goto l1;
+    edge e when x = 2 goto l2;
+    edge e when x = 3 goto l3;
+
+  location l2:
+    edge a goto l1;
+
+  location l3:
+    edge b goto l1;
+end
+
+requirement true disables b;
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_simple_per_event.cif.err b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_simple_per_event.cif.err
new file mode 100644
index 0000000000000000000000000000000000000000..e8c691af6aa6688bb81db47d27e318222666d949
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_simple_per_event.cif.err
@@ -0,0 +1 @@
+WARNING: Event "b" is never enabled in the input specification, taking into account only state/event exclusion requirements.
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_simple_per_event.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_simple_per_event.cif.out
new file mode 100644
index 0000000000000000000000000000000000000000..87bb4da6bcbb77b45b7a662c9e8aa2be34dd4873
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_simple_per_event.cif.out
@@ -0,0 +1,261 @@
+Reading CIF file "datasynth/edge_granularity_simple_per_event.cif".
+Preprocessing CIF specification.
+Converting CIF specification to internal format.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      location pointer   n/a        p1    0      1 * 2     2 * 2       2 * 2       100%
+  2      location pointer   n/a        p2    1      2 * 2     3 * 2       4 * 2       75%
+  3      discrete variable  int[0..3]  p2.x  2      2 * 2     4 * 2       4 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      3      10        18          20          90%
+
+Applying variable ordering:
+  Applying 4 orderers, sequentially:
+    Applying model variable order:
+      Effect: both
+
+    Applying DCSH algorithm:
+      Metric: wes
+      Relations: legacy
+      Effect: var-order
+      Number of hyper-edges: 6
+
+      Applying Weighted Cuthill-McKee algorithm:
+        Node finder: george-liu
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 3
+
+        Total span:   2 (total)   0.33 (avg/edge) / WES:   0.518519 (total)   0.086420 (avg/edge) [before]
+        Total span:   2 (total)   0.33 (avg/edge) / WES:   0.518519 (total)   0.086420 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying Sloan algorithm:
+        Relations: legacy
+        Effect: var-order
+        Number of graph edges: 3
+
+        Total span:   2 (total)   0.33 (avg/edge) / WES:   0.518519 (total)   0.086420 (avg/edge) [before]
+        Total span:   2 (total)   0.33 (avg/edge) / WES:   0.481481 (total)   0.080247 (avg/edge) [after]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Weighted Cuthill-McKee algorithm:
+          Node finder: george-liu
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 3
+
+          Total span:   2 (total)   0.33 (avg/edge) / WES:   0.518519 (total)   0.086420 (avg/edge) [before]
+          Total span:   2 (total)   0.33 (avg/edge) / WES:   0.518519 (total)   0.086420 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 6
+
+          Total span:   2 (total)   0.33 (avg/edge) / WES:   0.518519 (total)   0.086420 (avg/edge) [before]
+          Total span:   2 (total)   0.33 (avg/edge) / WES:   0.518519 (total)   0.086420 (avg/edge) [reversed]
+
+      Found new best variable order.
+
+      Applying 2 orderers, sequentially:
+        Applying Sloan algorithm:
+          Relations: legacy
+          Effect: var-order
+          Number of graph edges: 3
+
+          Total span:   2 (total)   0.33 (avg/edge) / WES:   0.518519 (total)   0.086420 (avg/edge) [before]
+          Total span:   2 (total)   0.33 (avg/edge) / WES:   0.481481 (total)   0.080247 (avg/edge) [after]
+
+        Reversing the variable order:
+          Relations: legacy
+          Effect: var-order
+          Number of hyper-edges: 6
+
+          Total span:   2 (total)   0.33 (avg/edge) / WES:   0.481481 (total)   0.080247 (avg/edge) [before]
+          Total span:   2 (total)   0.33 (avg/edge) / WES:   0.481481 (total)   0.080247 (avg/edge) [reversed]
+
+    Applying FORCE algorithm:
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 8
+      Maximum number of iterations: 20
+
+      Total span:   12 (total)   1.50 (avg/edge) / WES:   1.055556 (total)   0.131944 (avg/edge) [before]
+      Total span:   12 (total)   1.50 (avg/edge) / WES:   1.055556 (total)   0.131944 (avg/edge) [iteration 1]
+      Total span:   12 (total)   1.50 (avg/edge) / WES:   1.055556 (total)   0.131944 (avg/edge) [after]
+
+    Applying sliding window algorithm:
+      Size: 4
+      Metric: total-span
+      Relations: linearized
+      Effect: var-order
+      Number of hyper-edges: 8
+      Window length: 3
+
+      Total span:   12 (total)   1.50 (avg/edge) / WES:   1.055556 (total)   0.131944 (avg/edge) [before]
+      Total span:   12 (total)   1.50 (avg/edge) / WES:   1.055556 (total)   0.131944 (avg/edge) [after]
+
+Variable order changed.
+
+CIF variables and location pointers:
+  Nr     Kind               Type       Name  Group  BDD vars  CIF values  BDD values  Values used
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  1      discrete variable  int[0..3]  p2.x  0      2 * 2     4 * 2       4 * 2       100%
+  2      location pointer   n/a        p2    1      2 * 2     3 * 2       4 * 2       75%
+  3      location pointer   n/a        p1    2      1 * 2     2 * 2       2 * 2       100%
+  -----  -----------------  ---------  ----  -----  --------  ----------  ----------  -----------
+  Total                                      3      10        18          20          90%
+
+Starting data-based synthesis.
+
+Invariant (components state plant inv):      true
+Invariant (locations state plant invariant): true
+Invariant (system state plant invariant):    true
+
+Invariant (components state req invariant):  true
+Invariant (locations state req invariant):   true
+Invariant (system state req invariant):      true
+
+Initial   (discrete variable 0):             true
+Initial   (discrete variables):              true
+Initial   (components init predicate):       true
+Initial   (aut/locs init predicate):         p1.l1
+Initial   (aut/locs init predicate):         p2.l1
+Initial   (auts/locs init predicate):        p2.l1 and p1.l1
+Initial   (uncontrolled system):             p2.l1 and p1.l1
+Initial   (system, combined init/plant inv): p2.l1 and p1.l1
+Initial   (system, combined init/state inv): p2.l1 and p1.l1
+
+Marked    (components marker predicate):     true
+Marked    (aut/locs marker predicate):       p1.l1
+Marked    (aut/locs marker predicate):       p2.l1
+Marked    (auts/locs marker predicate):      p2.l1 and p1.l1
+Marked    (uncontrolled system):             p2.l1 and p1.l1
+Marked    (system, combined mark/plant inv): p2.l1 and p1.l1
+Marked    (system, combined mark/state inv): p2.l1 and p1.l1
+
+State/event exclusion plants:
+  None
+
+State/event exclusion requirements:
+  Event "b" needs:
+    false
+
+Uncontrolled system:
+  State: (controlled-behavior: ?)
+    Edge: (event: e) (guard: p2.x = 2 and p2.l1 or (p2.x = 1 or p2.x = 3) and p2.l1) (assignments: p1 := p1.l2 / p1 := p1.l2, p2 := p2.l2 / p1 := p1.l2, p2 := p2.l3 / p1 := p1.l1 / p1 := p1.l1, p2 := p2.l2 / p1 := p1.l1, p2 := p2.l3)
+    Edge: (event: a) (guard: p2.l2) (assignments: p2 := p2.l1)
+    Edge: (event: b) (guard: p2.l3) (assignments: p2 := p2.l1)
+
+Restricting behavior using state/event exclusion plants.
+
+Initialized controlled-behavior predicate: true.
+Initialized controlled-initialization predicate: p2.l1 and p1.l1.
+
+Restricting behavior using state requirements.
+
+Extending controlled-behavior predicate using variable ranges.
+
+Controlled behavior: true -> true [range: true, variable: location pointer for automaton "p2" (group: 1, domain: 2+3, BDD variables: 2, CIF/BDD values: 3/4)].
+
+Extended controlled-behavior predicate using variable ranges: true.
+
+Restricting behavior using state/event exclusion requirements.
+
+Edge (event: b) (guard: p2.l3) (assignments: p2 := p2.l1): guard: p2.l3 -> false [state/event exclusion requirement: false].
+
+Restricted behavior using state/event exclusion requirements:
+  State: (controlled-behavior: true)
+    Edge: (event: e) (guard: p2.x = 2 and p2.l1 or (p2.x = 1 or p2.x = 3) and p2.l1) (assignments: p1 := p1.l2 / p1 := p1.l2, p2 := p2.l2 / p1 := p1.l2, p2 := p2.l3 / p1 := p1.l1 / p1 := p1.l1, p2 := p2.l2 / p1 := p1.l1, p2 := p2.l3)
+    Edge: (event: a) (guard: p2.l2) (assignments: p2 := p2.l1)
+    Edge: (event: b) (guard: p2.l3 -> false) (assignments: p2 := p2.l1)
+
+Round 1: started.
+
+Round 1: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p2.l1 and p1.l1 [marker predicate]
+Backward reachability: iteration 1.
+Backward controlled-behavior: p2.l1 and p1.l1 -> (p2.x = 0 or p2.x = 2) and (p2.l1 and p1.l1) or (p2.x = 1 and p2.l1 or p2.x = 3 and (p2.l1 and p1.l1)) [backward reach with edge: (event: e) (guard: p2.x = 2 and p2.l1 or (p2.x = 1 or p2.x = 3) and p2.l1) (assignments: p1 := p1.l2 / p1 := p1.l2, p2 := p2.l2 / p1 := p1.l2, p2 := p2.l3 / p1 := p1.l1 / p1 := p1.l1, p2 := p2.l2 / p1 := p1.l1, p2 := p2.l3), restricted to current/previous controlled-behavior predicate: true]
+Backward controlled-behavior: (p2.x = 0 or p2.x = 2) and (p2.l1 and p1.l1) or (p2.x = 1 and p2.l1 or p2.x = 3 and (p2.l1 and p1.l1)) -> (p2.x = 0 or p2.x = 2) and (not p2.l3 and p1.l1) or (p2.x = 1 and not p2.l3 or p2.x = 3 and (not p2.l3 and p1.l1)) [backward reach with edge: (event: a) (guard: p2.l2) (assignments: p2 := p2.l1), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 2.
+Backward controlled-behavior: (p2.x = 0 or p2.x = 2) and (not p2.l3 and p1.l1) or (p2.x = 1 and not p2.l3 or p2.x = 3 and (not p2.l3 and p1.l1)) -> p2.x = 0 and (not p2.l3 and p1.l1) or p2.x = 2 and p2.l1 or (p2.x = 2 and (p2.l2 and p1.l1) or (p2.x = 1 and not p2.l3 or p2.x = 3 and (not p2.l3 and p1.l1))) [backward reach with edge: (event: e) (guard: p2.x = 2 and p2.l1 or (p2.x = 1 or p2.x = 3) and p2.l1) (assignments: p1 := p1.l2 / p1 := p1.l2, p2 := p2.l2 / p1 := p1.l2, p2 := p2.l3 / p1 := p1.l1 / p1 := p1.l1, p2 := p2.l2 / p1 := p1.l1, p2 := p2.l3), restricted to current/previous controlled-behavior predicate: true]
+Backward controlled-behavior: p2.x = 0 and (not p2.l3 and p1.l1) or p2.x = 2 and p2.l1 or (p2.x = 2 and (p2.l2 and p1.l1) or (p2.x = 1 and not p2.l3 or p2.x = 3 and (not p2.l3 and p1.l1))) -> p2.x = 0 and (not p2.l3 and p1.l1) or p2.x = 2 and not p2.l3 or (p2.x = 1 and not p2.l3 or p2.x = 3 and (not p2.l3 and p1.l1)) [backward reach with edge: (event: a) (guard: p2.l2) (assignments: p2 := p2.l1), restricted to current/previous controlled-behavior predicate: true]
+Backward reachability: iteration 3.
+Backward controlled-behavior: p2.x = 0 and (not p2.l3 and p1.l1) or p2.x = 2 and not p2.l3 or (p2.x = 1 and not p2.l3 or p2.x = 3 and (not p2.l3 and p1.l1)) [fixed point].
+Controlled behavior: true -> p2.x = 0 and (not p2.l3 and p1.l1) or p2.x = 2 and not p2.l3 or (p2.x = 1 and not p2.l3 or p2.x = 3 and (not p2.l3 and p1.l1)).
+
+Round 1: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p2.x != 0 or (p2.l3 or p1.l2)) and (p2.x != 2 or p2.l3) and ((p2.x != 1 or p2.l3) and (p2.x != 3 or (p2.l3 or p1.l2))) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+Backward uncontrolled bad-state: (p2.x != 0 or (p2.l3 or p1.l2)) and (p2.x != 2 or p2.l3) and ((p2.x != 1 or p2.l3) and (p2.x != 3 or (p2.l3 or p1.l2))) -> (p2.x != 0 or (p2.l3 or p1.l2)) and (p2.x != 2 or p2.l3) and ((p2.x != 1 or p2.l3) and (p2.x != 3 or (not p2.l2 or p1.l2))) [backward reach with edge: (event: e) (guard: p2.x = 2 and p2.l1 or (p2.x = 1 or p2.x = 3) and p2.l1) (assignments: p1 := p1.l2 / p1 := p1.l2, p2 := p2.l2 / p1 := p1.l2, p2 := p2.l3 / p1 := p1.l1 / p1 := p1.l1, p2 := p2.l2 / p1 := p1.l1, p2 := p2.l3)]
+Backward reachability: iteration 2.
+Backward uncontrolled bad-state: (p2.x != 0 or (p2.l3 or p1.l2)) and (p2.x != 2 or p2.l3) and ((p2.x != 1 or p2.l3) and (p2.x != 3 or (not p2.l2 or p1.l2))) [fixed point].
+Controlled behavior: p2.x = 0 and (not p2.l3 and p1.l1) or p2.x = 2 and not p2.l3 or (p2.x = 1 and not p2.l3 or p2.x = 3 and (not p2.l3 and p1.l1)) -> p2.x = 0 and (not p2.l3 and p1.l1) or p2.x = 2 and not p2.l3 or (p2.x = 1 and not p2.l3 or p2.x = 3 and (p2.l2 and p1.l1)).
+
+Round 1: computing forward controlled-behavior predicate.
+Forward controlled-behavior: p2.l1 and p1.l1 [initialization predicate]
+Forward controlled-behavior: p2.l1 and p1.l1 -> (p2.x = 0 or p2.x = 2) and (p2.l1 and p1.l1) or p2.x = 1 and (p2.l1 and p1.l1) [restricted to current/previous controlled-behavior predicate: p2.x = 0 and (not p2.l3 and p1.l1) or p2.x = 2 and not p2.l3 or (p2.x = 1 and not p2.l3 or p2.x = 3 and (p2.l2 and p1.l1))]
+Forward reachability: iteration 1.
+Forward controlled-behavior: (p2.x = 0 or p2.x = 2) and (p2.l1 and p1.l1) or p2.x = 1 and (p2.l1 and p1.l1) -> p2.x = 0 and (p2.l1 and p1.l1) or p2.x = 2 and (p2.l1 and p1.l1) or (p2.x = 2 and (p2.l2 and p1.l2) or p2.x = 1 and p2.l1) [forward reach with edge: (event: e) (guard: p2.x = 2 and p2.l1 or (p2.x = 1 or p2.x = 3) and p2.l1) (assignments: p1 := p1.l2 / p1 := p1.l2, p2 := p2.l2 / p1 := p1.l2, p2 := p2.l3 / p1 := p1.l1 / p1 := p1.l1, p2 := p2.l2 / p1 := p1.l1, p2 := p2.l3), restricted to current/previous controlled-behavior predicate: p2.x = 0 and (not p2.l3 and p1.l1) or p2.x = 2 and not p2.l3 or (p2.x = 1 and not p2.l3 or p2.x = 3 and (p2.l2 and p1.l1))]
+Forward controlled-behavior: p2.x = 0 and (p2.l1 and p1.l1) or p2.x = 2 and (p2.l1 and p1.l1) or (p2.x = 2 and (p2.l2 and p1.l2) or p2.x = 1 and p2.l1) -> p2.x = 0 and (p2.l1 and p1.l1) or p2.x = 2 and p2.l1 or (p2.x = 2 and (p2.l2 and p1.l2) or p2.x = 1 and p2.l1) [forward reach with edge: (event: a) (guard: p2.l2) (assignments: p2 := p2.l1), restricted to current/previous controlled-behavior predicate: p2.x = 0 and (not p2.l3 and p1.l1) or p2.x = 2 and not p2.l3 or (p2.x = 1 and not p2.l3 or p2.x = 3 and (p2.l2 and p1.l1))]
+Forward reachability: iteration 2.
+Forward controlled-behavior: p2.x = 0 and (p2.l1 and p1.l1) or p2.x = 2 and p2.l1 or (p2.x = 2 and (p2.l2 and p1.l2) or p2.x = 1 and p2.l1) -> p2.x = 0 and (p2.l1 and p1.l1) or (p2.x = 2 and not p2.l3 or p2.x = 1 and p2.l1) [forward reach with edge: (event: e) (guard: p2.x = 2 and p2.l1 or (p2.x = 1 or p2.x = 3) and p2.l1) (assignments: p1 := p1.l2 / p1 := p1.l2, p2 := p2.l2 / p1 := p1.l2, p2 := p2.l3 / p1 := p1.l1 / p1 := p1.l1, p2 := p2.l2 / p1 := p1.l1, p2 := p2.l3), restricted to current/previous controlled-behavior predicate: p2.x = 0 and (not p2.l3 and p1.l1) or p2.x = 2 and not p2.l3 or (p2.x = 1 and not p2.l3 or p2.x = 3 and (p2.l2 and p1.l1))]
+Forward reachability: iteration 3.
+Forward controlled-behavior: p2.x = 0 and (p2.l1 and p1.l1) or (p2.x = 2 and not p2.l3 or p2.x = 1 and p2.l1) [fixed point].
+Controlled behavior: p2.x = 0 and (not p2.l3 and p1.l1) or p2.x = 2 and not p2.l3 or (p2.x = 1 and not p2.l3 or p2.x = 3 and (p2.l2 and p1.l1)) -> p2.x = 0 and (p2.l1 and p1.l1) or (p2.x = 2 and not p2.l3 or p2.x = 1 and p2.l1).
+
+Round 1: finished, need another round.
+
+Round 2: started.
+
+Round 2: computing backward controlled-behavior predicate.
+Backward controlled-behavior: p2.l1 and p1.l1 [marker predicate]
+Backward controlled-behavior: p2.l1 and p1.l1 -> (p2.x = 0 or p2.x = 2) and (p2.l1 and p1.l1) or p2.x = 1 and (p2.l1 and p1.l1) [restricted to current/previous controlled-behavior predicate: p2.x = 0 and (p2.l1 and p1.l1) or (p2.x = 2 and not p2.l3 or p2.x = 1 and p2.l1)]
+Backward reachability: iteration 1.
+Backward controlled-behavior: (p2.x = 0 or p2.x = 2) and (p2.l1 and p1.l1) or p2.x = 1 and (p2.l1 and p1.l1) -> (p2.x = 0 or p2.x = 2) and (p2.l1 and p1.l1) or p2.x = 1 and p2.l1 [backward reach with edge: (event: e) (guard: p2.x = 2 and p2.l1 or (p2.x = 1 or p2.x = 3) and p2.l1) (assignments: p1 := p1.l2 / p1 := p1.l2, p2 := p2.l2 / p1 := p1.l2, p2 := p2.l3 / p1 := p1.l1 / p1 := p1.l1, p2 := p2.l2 / p1 := p1.l1, p2 := p2.l3), restricted to current/previous controlled-behavior predicate: p2.x = 0 and (p2.l1 and p1.l1) or (p2.x = 2 and not p2.l3 or p2.x = 1 and p2.l1)]
+Backward controlled-behavior: (p2.x = 0 or p2.x = 2) and (p2.l1 and p1.l1) or p2.x = 1 and p2.l1 -> p2.x = 0 and (p2.l1 and p1.l1) or (p2.x = 2 and (not p2.l3 and p1.l1) or p2.x = 1 and p2.l1) [backward reach with edge: (event: a) (guard: p2.l2) (assignments: p2 := p2.l1), restricted to current/previous controlled-behavior predicate: p2.x = 0 and (p2.l1 and p1.l1) or (p2.x = 2 and not p2.l3 or p2.x = 1 and p2.l1)]
+Backward reachability: iteration 2.
+Backward controlled-behavior: p2.x = 0 and (p2.l1 and p1.l1) or (p2.x = 2 and (not p2.l3 and p1.l1) or p2.x = 1 and p2.l1) -> p2.x = 0 and (p2.l1 and p1.l1) or p2.x = 2 and p2.l1 or (p2.x = 2 and (p2.l2 and p1.l1) or p2.x = 1 and p2.l1) [backward reach with edge: (event: e) (guard: p2.x = 2 and p2.l1 or (p2.x = 1 or p2.x = 3) and p2.l1) (assignments: p1 := p1.l2 / p1 := p1.l2, p2 := p2.l2 / p1 := p1.l2, p2 := p2.l3 / p1 := p1.l1 / p1 := p1.l1, p2 := p2.l2 / p1 := p1.l1, p2 := p2.l3), restricted to current/previous controlled-behavior predicate: p2.x = 0 and (p2.l1 and p1.l1) or (p2.x = 2 and not p2.l3 or p2.x = 1 and p2.l1)]
+Backward controlled-behavior: p2.x = 0 and (p2.l1 and p1.l1) or p2.x = 2 and p2.l1 or (p2.x = 2 and (p2.l2 and p1.l1) or p2.x = 1 and p2.l1) -> p2.x = 0 and (p2.l1 and p1.l1) or (p2.x = 2 and not p2.l3 or p2.x = 1 and p2.l1) [backward reach with edge: (event: a) (guard: p2.l2) (assignments: p2 := p2.l1), restricted to current/previous controlled-behavior predicate: p2.x = 0 and (p2.l1 and p1.l1) or (p2.x = 2 and not p2.l3 or p2.x = 1 and p2.l1)]
+Backward reachability: iteration 3.
+Backward controlled-behavior: p2.x = 0 and (p2.l1 and p1.l1) or (p2.x = 2 and not p2.l3 or p2.x = 1 and p2.l1) [fixed point].
+
+Round 2: computing backward uncontrolled bad-state predicate.
+Backward uncontrolled bad-state: (p2.x != 0 or (not p2.l1 or p1.l2)) and ((p2.x != 2 or p2.l3) and (p2.x != 1 or not p2.l1)) [current/previous controlled behavior predicate]
+Backward reachability: iteration 1.
+
+Round 2: finished, controlled behavior is stable.
+
+Computing controlled system guards.
+
+Edge (event: a) (guard: p2.l2) (assignments: p2 := p2.l1): guard: p2.l2 -> p2.x = 0 and (p2.l2 and p1.l1) or (p2.x = 2 and p2.l2 or p2.x = 1 and p2.l2).
+
+Final synthesis result:
+  State: (controlled-behavior: p2.x = 0 and (p2.l1 and p1.l1) or (p2.x = 2 and not p2.l3 or p2.x = 1 and p2.l1))
+    Edge: (event: e) (guard: p2.x = 2 and p2.l1 or (p2.x = 1 or p2.x = 3) and p2.l1) (assignments: p1 := p1.l2 / p1 := p1.l2, p2 := p2.l2 / p1 := p1.l2, p2 := p2.l3 / p1 := p1.l1 / p1 := p1.l1, p2 := p2.l2 / p1 := p1.l1, p2 := p2.l3)
+    Edge: (event: a) (guard: p2.l2 -> p2.x = 0 and (p2.l2 and p1.l1) or (p2.x = 2 and p2.l2 or p2.x = 1 and p2.l2)) (assignments: p2 := p2.l1)
+    Edge: (event: b) (guard: p2.l3 -> false) (assignments: p2 := p2.l1)
+
+Controlled system:                     exactly 7 states.
+
+Initial (synthesis result):            p2.x = 0 and (p2.l1 and p1.l1) or (p2.x = 2 and not p2.l3 or p2.x = 1 and p2.l1)
+Initial (uncontrolled system):         p2.l1 and p1.l1
+Initial (controlled system):           (p2.x = 0 or p2.x = 2) and (p2.l1 and p1.l1) or p2.x = 1 and (p2.l1 and p1.l1)
+Initial (removed by supervisor):       p2.x = 3 and (p2.l1 and p1.l1)
+Initial (added by supervisor):         p2.x != 3 or (not p2.l1 or p1.l2)
+
+Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
+  Initial: (p2.x = 0 or p2.x = 2) and (p2.l1 and p1.l1) or p2.x = 1 and (p2.l1 and p1.l1) -> p2.x != 3 [assume p2.l1 and p1.l1].
+
+Simplification of controlled system under the assumption of the plants:
+  Event a: guard: p2.x = 0 and (p2.l2 and p1.l1) or (p2.x = 2 and p2.l2 or p2.x = 1 and p2.l2) -> (p2.x != 0 or p1.l1) and p2.x != 3 [assume p2.l2].
+
+Constructing output CIF specification.
+Writing output CIF file "datasynth/edge_granularity_simple_per_event.ctrlsys.real.cif".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_simple_per_event.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_simple_per_event.ctrlsys.cif
new file mode 100644
index 0000000000000000000000000000000000000000..dcc18c1862550f0a261d14c11cbe438efceac07b
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_simple_per_event.ctrlsys.cif
@@ -0,0 +1,33 @@
+uncontrollable e;
+controllable a;
+controllable b;
+plant automaton p1:
+  location l1:
+    initial;
+    marked;
+    edge e goto l2;
+  location l2:
+    edge e goto l1;
+end
+plant automaton p2:
+  disc int[0..3] x in any;
+  location l1:
+    initial;
+    marked;
+    edge e when x = 1 goto l1;
+    edge e when x = 2 goto l2;
+    edge e when x = 3 goto l3;
+  location l2:
+    edge a goto l1;
+  location l3:
+    edge b goto l1;
+end
+supervisor automaton sup:
+  alphabet a, b;
+  initial p2.x != 3;
+  location:
+    initial;
+    marked;
+    edge a when (p2.x != 0 or p1.l1) and p2.x != 3;
+    edge b when false;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_simple_per_event.statespace.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_simple_per_event.statespace.cif
new file mode 100644
index 0000000000000000000000000000000000000000..9e3e5976f38da4a5edf47d245afaaa74f39971b7
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/edge_granularity_simple_per_event.statespace.cif
@@ -0,0 +1,25 @@
+uncontrollable e;
+controllable a;
+controllable b;
+automaton statespace:
+  alphabet e, a, b;
+  location loc1:
+    initial;
+    marked;
+  location loc2:
+    initial;
+    marked;
+    edge e goto loc4;
+  location loc3:
+    initial;
+    marked;
+    edge e goto loc5;
+  location loc4:
+    edge e goto loc2;
+  location loc5:
+    edge a goto loc6;
+  location loc6:
+    edge e goto loc7;
+  location loc7:
+    edge a goto loc3;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/inv_state_evt_exclusion_plant_loc.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/inv_state_evt_exclusion_plant_loc.cif.out
index 2c3d04c0f09ec7e9934d26f9de942da0fa6bbe50..241c77d70125edf07d16f1e07920f96f80663f13 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/datasynth/inv_state_evt_exclusion_plant_loc.cif.out
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/inv_state_evt_exclusion_plant_loc.cif.out
@@ -19,7 +19,7 @@ Applying variable ordering:
       Metric: wes
       Relations: legacy
       Effect: var-order
-      Number of hyper-edges: 50
+      Number of hyper-edges: 32
 
       Applying Weighted Cuthill-McKee algorithm:
         Node finder: george-liu
@@ -27,8 +27,8 @@ Applying variable ordering:
         Effect: var-order
         Number of graph edges: 1
 
-        Total span:   4 (total)   0.08 (avg/edge) / WES:   0.480000 (total)   0.009600 (avg/edge) [before]
-        Total span:   4 (total)   0.08 (avg/edge) / WES:   0.480000 (total)   0.009600 (avg/edge) [after]
+        Total span:   4 (total)   0.13 (avg/edge) / WES:   0.468750 (total)   0.014648 (avg/edge) [before]
+        Total span:   4 (total)   0.13 (avg/edge) / WES:   0.468750 (total)   0.014648 (avg/edge) [after]
 
       Found new best variable order.
 
@@ -37,8 +37,8 @@ Applying variable ordering:
         Effect: var-order
         Number of graph edges: 1
 
-        Total span:   4 (total)   0.08 (avg/edge) / WES:   0.480000 (total)   0.009600 (avg/edge) [before]
-        Total span:   4 (total)   0.08 (avg/edge) / WES:   0.480000 (total)   0.009600 (avg/edge) [after]
+        Total span:   4 (total)   0.13 (avg/edge) / WES:   0.468750 (total)   0.014648 (avg/edge) [before]
+        Total span:   4 (total)   0.13 (avg/edge) / WES:   0.468750 (total)   0.014648 (avg/edge) [after]
 
       Applying 2 orderers, sequentially:
         Applying Weighted Cuthill-McKee algorithm:
@@ -47,16 +47,16 @@ Applying variable ordering:
           Effect: var-order
           Number of graph edges: 1
 
-          Total span:   4 (total)   0.08 (avg/edge) / WES:   0.480000 (total)   0.009600 (avg/edge) [before]
-          Total span:   4 (total)   0.08 (avg/edge) / WES:   0.480000 (total)   0.009600 (avg/edge) [after]
+          Total span:   4 (total)   0.13 (avg/edge) / WES:   0.468750 (total)   0.014648 (avg/edge) [before]
+          Total span:   4 (total)   0.13 (avg/edge) / WES:   0.468750 (total)   0.014648 (avg/edge) [after]
 
         Reversing the variable order:
           Relations: legacy
           Effect: var-order
-          Number of hyper-edges: 50
+          Number of hyper-edges: 32
 
-          Total span:   4 (total)   0.08 (avg/edge) / WES:   0.480000 (total)   0.009600 (avg/edge) [before]
-          Total span:   4 (total)   0.08 (avg/edge) / WES:   0.480000 (total)   0.009600 (avg/edge) [reversed]
+          Total span:   4 (total)   0.13 (avg/edge) / WES:   0.468750 (total)   0.014648 (avg/edge) [before]
+          Total span:   4 (total)   0.13 (avg/edge) / WES:   0.468750 (total)   0.014648 (avg/edge) [reversed]
 
       Found new best variable order.
 
@@ -66,16 +66,16 @@ Applying variable ordering:
           Effect: var-order
           Number of graph edges: 1
 
-          Total span:   4 (total)   0.08 (avg/edge) / WES:   0.480000 (total)   0.009600 (avg/edge) [before]
-          Total span:   4 (total)   0.08 (avg/edge) / WES:   0.480000 (total)   0.009600 (avg/edge) [after]
+          Total span:   4 (total)   0.13 (avg/edge) / WES:   0.468750 (total)   0.014648 (avg/edge) [before]
+          Total span:   4 (total)   0.13 (avg/edge) / WES:   0.468750 (total)   0.014648 (avg/edge) [after]
 
         Reversing the variable order:
           Relations: legacy
           Effect: var-order
-          Number of hyper-edges: 50
+          Number of hyper-edges: 32
 
-          Total span:   4 (total)   0.08 (avg/edge) / WES:   0.480000 (total)   0.009600 (avg/edge) [before]
-          Total span:   4 (total)   0.08 (avg/edge) / WES:   0.480000 (total)   0.009600 (avg/edge) [reversed]
+          Total span:   4 (total)   0.13 (avg/edge) / WES:   0.468750 (total)   0.014648 (avg/edge) [before]
+          Total span:   4 (total)   0.13 (avg/edge) / WES:   0.468750 (total)   0.014648 (avg/edge) [reversed]
 
     Applying FORCE algorithm:
       Metric: total-span
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/inv_state_evt_exclusion_req_loc.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/inv_state_evt_exclusion_req_loc.cif.out
index 28603edfce28dd512b81db220cd61637d83cb493..502faf32d64be42c9b15250144a2d585250407f4 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/datasynth/inv_state_evt_exclusion_req_loc.cif.out
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/inv_state_evt_exclusion_req_loc.cif.out
@@ -19,7 +19,7 @@ Applying variable ordering:
       Metric: wes
       Relations: legacy
       Effect: var-order
-      Number of hyper-edges: 25
+      Number of hyper-edges: 16
 
       Applying Weighted Cuthill-McKee algorithm:
         Node finder: george-liu
@@ -27,8 +27,8 @@ Applying variable ordering:
         Effect: var-order
         Number of graph edges: 1
 
-        Total span:   2 (total)   0.08 (avg/edge) / WES:   0.480000 (total)   0.019200 (avg/edge) [before]
-        Total span:   2 (total)   0.08 (avg/edge) / WES:   0.480000 (total)   0.019200 (avg/edge) [after]
+        Total span:   2 (total)   0.13 (avg/edge) / WES:   0.468750 (total)   0.029297 (avg/edge) [before]
+        Total span:   2 (total)   0.13 (avg/edge) / WES:   0.468750 (total)   0.029297 (avg/edge) [after]
 
       Found new best variable order.
 
@@ -37,8 +37,8 @@ Applying variable ordering:
         Effect: var-order
         Number of graph edges: 1
 
-        Total span:   2 (total)   0.08 (avg/edge) / WES:   0.480000 (total)   0.019200 (avg/edge) [before]
-        Total span:   2 (total)   0.08 (avg/edge) / WES:   0.480000 (total)   0.019200 (avg/edge) [after]
+        Total span:   2 (total)   0.13 (avg/edge) / WES:   0.468750 (total)   0.029297 (avg/edge) [before]
+        Total span:   2 (total)   0.13 (avg/edge) / WES:   0.468750 (total)   0.029297 (avg/edge) [after]
 
       Applying 2 orderers, sequentially:
         Applying Weighted Cuthill-McKee algorithm:
@@ -47,16 +47,16 @@ Applying variable ordering:
           Effect: var-order
           Number of graph edges: 1
 
-          Total span:   2 (total)   0.08 (avg/edge) / WES:   0.480000 (total)   0.019200 (avg/edge) [before]
-          Total span:   2 (total)   0.08 (avg/edge) / WES:   0.480000 (total)   0.019200 (avg/edge) [after]
+          Total span:   2 (total)   0.13 (avg/edge) / WES:   0.468750 (total)   0.029297 (avg/edge) [before]
+          Total span:   2 (total)   0.13 (avg/edge) / WES:   0.468750 (total)   0.029297 (avg/edge) [after]
 
         Reversing the variable order:
           Relations: legacy
           Effect: var-order
-          Number of hyper-edges: 25
+          Number of hyper-edges: 16
 
-          Total span:   2 (total)   0.08 (avg/edge) / WES:   0.480000 (total)   0.019200 (avg/edge) [before]
-          Total span:   2 (total)   0.08 (avg/edge) / WES:   0.480000 (total)   0.019200 (avg/edge) [reversed]
+          Total span:   2 (total)   0.13 (avg/edge) / WES:   0.468750 (total)   0.029297 (avg/edge) [before]
+          Total span:   2 (total)   0.13 (avg/edge) / WES:   0.468750 (total)   0.029297 (avg/edge) [reversed]
 
       Found new best variable order.
 
@@ -66,16 +66,16 @@ Applying variable ordering:
           Effect: var-order
           Number of graph edges: 1
 
-          Total span:   2 (total)   0.08 (avg/edge) / WES:   0.480000 (total)   0.019200 (avg/edge) [before]
-          Total span:   2 (total)   0.08 (avg/edge) / WES:   0.480000 (total)   0.019200 (avg/edge) [after]
+          Total span:   2 (total)   0.13 (avg/edge) / WES:   0.468750 (total)   0.029297 (avg/edge) [before]
+          Total span:   2 (total)   0.13 (avg/edge) / WES:   0.468750 (total)   0.029297 (avg/edge) [after]
 
         Reversing the variable order:
           Relations: legacy
           Effect: var-order
-          Number of hyper-edges: 25
+          Number of hyper-edges: 16
 
-          Total span:   2 (total)   0.08 (avg/edge) / WES:   0.480000 (total)   0.019200 (avg/edge) [before]
-          Total span:   2 (total)   0.08 (avg/edge) / WES:   0.480000 (total)   0.019200 (avg/edge) [reversed]
+          Total span:   2 (total)   0.13 (avg/edge) / WES:   0.468750 (total)   0.029297 (avg/edge) [before]
+          Total span:   2 (total)   0.13 (avg/edge) / WES:   0.468750 (total)   0.029297 (avg/edge) [reversed]
 
     Applying FORCE algorithm:
       Metric: total-span
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/invalid4.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/invalid4.cif.out
index 54e647b020ed56d225df4ffb79bd3676bf0c7972..26d035403292cb30c633143aeda304b48b61687a 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/datasynth/invalid4.cif.out
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/invalid4.cif.out
@@ -19,7 +19,7 @@ Applying variable ordering:
       Metric: wes
       Relations: legacy
       Effect: var-order
-      Number of hyper-edges: 2
+      Number of hyper-edges: 1
 
       Applying Weighted Cuthill-McKee algorithm:
         Node finder: george-liu
@@ -50,10 +50,10 @@ Applying variable ordering:
         Reversing the variable order:
           Relations: legacy
           Effect: var-order
-          Number of hyper-edges: 2
+          Number of hyper-edges: 1
 
-          Total span:   0 (total)   0.00 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [before]
-          Total span:   0 (total)   0.00 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [reversed]
+          Total span:   0 (total)   0.00 (avg/edge) / WES:   0.500000 (total)   0.500000 (avg/edge) [before]
+          Total span:   0 (total)   0.00 (avg/edge) / WES:   0.500000 (total)   0.500000 (avg/edge) [reversed]
 
       Found new best variable order.
 
@@ -68,10 +68,10 @@ Applying variable ordering:
         Reversing the variable order:
           Relations: legacy
           Effect: var-order
-          Number of hyper-edges: 2
+          Number of hyper-edges: 1
 
-          Total span:   0 (total)   0.00 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [before]
-          Total span:   0 (total)   0.00 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [reversed]
+          Total span:   0 (total)   0.00 (avg/edge) / WES:   0.500000 (total)   0.500000 (avg/edge) [before]
+          Total span:   0 (total)   0.00 (avg/edge) / WES:   0.500000 (total)   0.500000 (avg/edge) [reversed]
 
     Applying FORCE algorithm:
       Metric: total-span
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/multi_req_invs1.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/multi_req_invs1.cif.out
index 176b664c0323540e6e3e916cffa8e094423db4a5..59918b1b7e2d35b76893afc309a808bb20ed7db3 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/datasynth/multi_req_invs1.cif.out
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/multi_req_invs1.cif.out
@@ -19,7 +19,7 @@ Applying variable ordering:
       Metric: wes
       Relations: legacy
       Effect: var-order
-      Number of hyper-edges: 11
+      Number of hyper-edges: 10
 
       Applying Weighted Cuthill-McKee algorithm:
         Node finder: george-liu
@@ -27,8 +27,8 @@ Applying variable ordering:
         Effect: var-order
         Number of graph edges: 1
 
-        Total span:   1 (total)   0.09 (avg/edge) / WES:   0.272727 (total)   0.024793 (avg/edge) [before]
-        Total span:   1 (total)   0.09 (avg/edge) / WES:   0.272727 (total)   0.024793 (avg/edge) [after]
+        Total span:   1 (total)   0.10 (avg/edge) / WES:   0.300000 (total)   0.030000 (avg/edge) [before]
+        Total span:   1 (total)   0.10 (avg/edge) / WES:   0.300000 (total)   0.030000 (avg/edge) [after]
 
       Found new best variable order.
 
@@ -37,8 +37,8 @@ Applying variable ordering:
         Effect: var-order
         Number of graph edges: 1
 
-        Total span:   1 (total)   0.09 (avg/edge) / WES:   0.272727 (total)   0.024793 (avg/edge) [before]
-        Total span:   1 (total)   0.09 (avg/edge) / WES:   0.272727 (total)   0.024793 (avg/edge) [after]
+        Total span:   1 (total)   0.10 (avg/edge) / WES:   0.300000 (total)   0.030000 (avg/edge) [before]
+        Total span:   1 (total)   0.10 (avg/edge) / WES:   0.300000 (total)   0.030000 (avg/edge) [after]
 
       Applying 2 orderers, sequentially:
         Applying Weighted Cuthill-McKee algorithm:
@@ -47,16 +47,16 @@ Applying variable ordering:
           Effect: var-order
           Number of graph edges: 1
 
-          Total span:   1 (total)   0.09 (avg/edge) / WES:   0.272727 (total)   0.024793 (avg/edge) [before]
-          Total span:   1 (total)   0.09 (avg/edge) / WES:   0.272727 (total)   0.024793 (avg/edge) [after]
+          Total span:   1 (total)   0.10 (avg/edge) / WES:   0.300000 (total)   0.030000 (avg/edge) [before]
+          Total span:   1 (total)   0.10 (avg/edge) / WES:   0.300000 (total)   0.030000 (avg/edge) [after]
 
         Reversing the variable order:
           Relations: legacy
           Effect: var-order
-          Number of hyper-edges: 11
+          Number of hyper-edges: 10
 
-          Total span:   1 (total)   0.09 (avg/edge) / WES:   0.272727 (total)   0.024793 (avg/edge) [before]
-          Total span:   1 (total)   0.09 (avg/edge) / WES:   0.272727 (total)   0.024793 (avg/edge) [reversed]
+          Total span:   1 (total)   0.10 (avg/edge) / WES:   0.300000 (total)   0.030000 (avg/edge) [before]
+          Total span:   1 (total)   0.10 (avg/edge) / WES:   0.300000 (total)   0.030000 (avg/edge) [reversed]
 
       Applying 2 orderers, sequentially:
         Applying Sloan algorithm:
@@ -64,16 +64,16 @@ Applying variable ordering:
           Effect: var-order
           Number of graph edges: 1
 
-          Total span:   1 (total)   0.09 (avg/edge) / WES:   0.272727 (total)   0.024793 (avg/edge) [before]
-          Total span:   1 (total)   0.09 (avg/edge) / WES:   0.272727 (total)   0.024793 (avg/edge) [after]
+          Total span:   1 (total)   0.10 (avg/edge) / WES:   0.300000 (total)   0.030000 (avg/edge) [before]
+          Total span:   1 (total)   0.10 (avg/edge) / WES:   0.300000 (total)   0.030000 (avg/edge) [after]
 
         Reversing the variable order:
           Relations: legacy
           Effect: var-order
-          Number of hyper-edges: 11
+          Number of hyper-edges: 10
 
-          Total span:   1 (total)   0.09 (avg/edge) / WES:   0.272727 (total)   0.024793 (avg/edge) [before]
-          Total span:   1 (total)   0.09 (avg/edge) / WES:   0.272727 (total)   0.024793 (avg/edge) [reversed]
+          Total span:   1 (total)   0.10 (avg/edge) / WES:   0.300000 (total)   0.030000 (avg/edge) [before]
+          Total span:   1 (total)   0.10 (avg/edge) / WES:   0.300000 (total)   0.030000 (avg/edge) [reversed]
 
     Applying FORCE algorithm:
       Metric: total-span
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/req_counter.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/req_counter.cif.out
index dea35d5195e888d78a35adc83527bbe357ee7fb6..fbb91eece3f4faec978fcd78231ccca068c73ae1 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/datasynth/req_counter.cif.out
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/req_counter.cif.out
@@ -19,7 +19,7 @@ Applying variable ordering:
       Metric: wes
       Relations: legacy
       Effect: var-order
-      Number of hyper-edges: 6
+      Number of hyper-edges: 5
 
       Applying Weighted Cuthill-McKee algorithm:
         Node finder: george-liu
@@ -27,8 +27,8 @@ Applying variable ordering:
         Effect: var-order
         Number of graph edges: 1
 
-        Total span:   2 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.111111 (avg/edge) [before]
-        Total span:   2 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.111111 (avg/edge) [after]
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.700000 (total)   0.140000 (avg/edge) [before]
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.700000 (total)   0.140000 (avg/edge) [after]
 
       Found new best variable order.
 
@@ -37,8 +37,8 @@ Applying variable ordering:
         Effect: var-order
         Number of graph edges: 1
 
-        Total span:   2 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.111111 (avg/edge) [before]
-        Total span:   2 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.111111 (avg/edge) [after]
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.700000 (total)   0.140000 (avg/edge) [before]
+        Total span:   2 (total)   0.40 (avg/edge) / WES:   0.700000 (total)   0.140000 (avg/edge) [after]
 
       Applying 2 orderers, sequentially:
         Applying Weighted Cuthill-McKee algorithm:
@@ -47,16 +47,16 @@ Applying variable ordering:
           Effect: var-order
           Number of graph edges: 1
 
-          Total span:   2 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.111111 (avg/edge) [before]
-          Total span:   2 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.111111 (avg/edge) [after]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.700000 (total)   0.140000 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.700000 (total)   0.140000 (avg/edge) [after]
 
         Reversing the variable order:
           Relations: legacy
           Effect: var-order
-          Number of hyper-edges: 6
+          Number of hyper-edges: 5
 
-          Total span:   2 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.111111 (avg/edge) [before]
-          Total span:   2 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.111111 (avg/edge) [reversed]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.700000 (total)   0.140000 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.700000 (total)   0.140000 (avg/edge) [reversed]
 
       Found new best variable order.
 
@@ -66,16 +66,16 @@ Applying variable ordering:
           Effect: var-order
           Number of graph edges: 1
 
-          Total span:   2 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.111111 (avg/edge) [before]
-          Total span:   2 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.111111 (avg/edge) [after]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.700000 (total)   0.140000 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.700000 (total)   0.140000 (avg/edge) [after]
 
         Reversing the variable order:
           Relations: legacy
           Effect: var-order
-          Number of hyper-edges: 6
+          Number of hyper-edges: 5
 
-          Total span:   2 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.111111 (avg/edge) [before]
-          Total span:   2 (total)   0.33 (avg/edge) / WES:   0.666667 (total)   0.111111 (avg/edge) [reversed]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.700000 (total)   0.140000 (avg/edge) [before]
+          Total span:   2 (total)   0.40 (avg/edge) / WES:   0.700000 (total)   0.140000 (avg/edge) [reversed]
 
     Applying FORCE algorithm:
       Metric: total-span
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/simplify_state_plant_invs_off.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/simplify_state_plant_invs_off.cif.out
index ffed33534663bc282d107f3bf1849026eb185411..0ad41f23ccc4f992802fe983c6f9afd44aaaa3f9 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/datasynth/simplify_state_plant_invs_off.cif.out
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/simplify_state_plant_invs_off.cif.out
@@ -19,7 +19,7 @@ Applying variable ordering:
       Metric: wes
       Relations: legacy
       Effect: var-order
-      Number of hyper-edges: 2
+      Number of hyper-edges: 3
 
       Applying Weighted Cuthill-McKee algorithm:
         Node finder: george-liu
@@ -27,8 +27,8 @@ Applying variable ordering:
         Effect: var-order
         Number of graph edges: 1
 
-        Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [before]
-        Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [after]
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [before]
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [after]
 
       Found new best variable order.
 
@@ -37,8 +37,8 @@ Applying variable ordering:
         Effect: var-order
         Number of graph edges: 1
 
-        Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [before]
-        Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [after]
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [before]
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [after]
 
       Applying 2 orderers, sequentially:
         Applying Weighted Cuthill-McKee algorithm:
@@ -47,16 +47,16 @@ Applying variable ordering:
           Effect: var-order
           Number of graph edges: 1
 
-          Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [before]
-          Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [after]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [after]
 
         Reversing the variable order:
           Relations: legacy
           Effect: var-order
-          Number of hyper-edges: 2
+          Number of hyper-edges: 3
 
-          Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [before]
-          Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [reversed]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [reversed]
 
       Applying 2 orderers, sequentially:
         Applying Sloan algorithm:
@@ -64,16 +64,16 @@ Applying variable ordering:
           Effect: var-order
           Number of graph edges: 1
 
-          Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [before]
-          Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [after]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [after]
 
         Reversing the variable order:
           Relations: legacy
           Effect: var-order
-          Number of hyper-edges: 2
+          Number of hyper-edges: 3
 
-          Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [before]
-          Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [reversed]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [reversed]
 
     Applying FORCE algorithm:
       Metric: total-span
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/simplify_state_plant_invs_on.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/simplify_state_plant_invs_on.cif.out
index 65f2d6086727b25a24e4d2090a5bab190e76e2e2..058512fd1f3d11b967db18a2eaf1b22859846d12 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/datasynth/simplify_state_plant_invs_on.cif.out
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/simplify_state_plant_invs_on.cif.out
@@ -19,7 +19,7 @@ Applying variable ordering:
       Metric: wes
       Relations: legacy
       Effect: var-order
-      Number of hyper-edges: 2
+      Number of hyper-edges: 3
 
       Applying Weighted Cuthill-McKee algorithm:
         Node finder: george-liu
@@ -27,8 +27,8 @@ Applying variable ordering:
         Effect: var-order
         Number of graph edges: 1
 
-        Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [before]
-        Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [after]
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [before]
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [after]
 
       Found new best variable order.
 
@@ -37,8 +37,8 @@ Applying variable ordering:
         Effect: var-order
         Number of graph edges: 1
 
-        Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [before]
-        Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [after]
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [before]
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [after]
 
       Applying 2 orderers, sequentially:
         Applying Weighted Cuthill-McKee algorithm:
@@ -47,16 +47,16 @@ Applying variable ordering:
           Effect: var-order
           Number of graph edges: 1
 
-          Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [before]
-          Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [after]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [after]
 
         Reversing the variable order:
           Relations: legacy
           Effect: var-order
-          Number of hyper-edges: 2
+          Number of hyper-edges: 3
 
-          Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [before]
-          Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [reversed]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [reversed]
 
       Applying 2 orderers, sequentially:
         Applying Sloan algorithm:
@@ -64,16 +64,16 @@ Applying variable ordering:
           Effect: var-order
           Number of graph edges: 1
 
-          Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [before]
-          Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [after]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [after]
 
         Reversing the variable order:
           Relations: legacy
           Effect: var-order
-          Number of hyper-edges: 2
+          Number of hyper-edges: 3
 
-          Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [before]
-          Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [reversed]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [reversed]
 
     Applying FORCE algorithm:
       Metric: total-span
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/simplify_state_req_invs_off.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/simplify_state_req_invs_off.cif.out
index bca9547920c6ae10512797a3d4f26cea5a036e5a..4476a5134532d60708ba9a98efa989d0e8da1ae5 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/datasynth/simplify_state_req_invs_off.cif.out
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/simplify_state_req_invs_off.cif.out
@@ -19,7 +19,7 @@ Applying variable ordering:
       Metric: wes
       Relations: legacy
       Effect: var-order
-      Number of hyper-edges: 2
+      Number of hyper-edges: 3
 
       Applying Weighted Cuthill-McKee algorithm:
         Node finder: george-liu
@@ -27,8 +27,8 @@ Applying variable ordering:
         Effect: var-order
         Number of graph edges: 1
 
-        Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [before]
-        Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [after]
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [before]
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [after]
 
       Found new best variable order.
 
@@ -37,8 +37,8 @@ Applying variable ordering:
         Effect: var-order
         Number of graph edges: 1
 
-        Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [before]
-        Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [after]
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [before]
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [after]
 
       Applying 2 orderers, sequentially:
         Applying Weighted Cuthill-McKee algorithm:
@@ -47,16 +47,16 @@ Applying variable ordering:
           Effect: var-order
           Number of graph edges: 1
 
-          Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [before]
-          Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [after]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [after]
 
         Reversing the variable order:
           Relations: legacy
           Effect: var-order
-          Number of hyper-edges: 2
+          Number of hyper-edges: 3
 
-          Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [before]
-          Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [reversed]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [reversed]
 
       Applying 2 orderers, sequentially:
         Applying Sloan algorithm:
@@ -64,16 +64,16 @@ Applying variable ordering:
           Effect: var-order
           Number of graph edges: 1
 
-          Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [before]
-          Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [after]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [after]
 
         Reversing the variable order:
           Relations: legacy
           Effect: var-order
-          Number of hyper-edges: 2
+          Number of hyper-edges: 3
 
-          Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [before]
-          Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [reversed]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [reversed]
 
     Applying FORCE algorithm:
       Metric: total-span
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/simplify_state_req_invs_on.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/simplify_state_req_invs_on.cif.out
index f39bdc747e2bf6e3f2d31465c3f7bfba7f2e92fd..eb85f83ebd0e4d045cf2a96ea3d210f005fe0b6d 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/datasynth/simplify_state_req_invs_on.cif.out
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/simplify_state_req_invs_on.cif.out
@@ -19,7 +19,7 @@ Applying variable ordering:
       Metric: wes
       Relations: legacy
       Effect: var-order
-      Number of hyper-edges: 2
+      Number of hyper-edges: 3
 
       Applying Weighted Cuthill-McKee algorithm:
         Node finder: george-liu
@@ -27,8 +27,8 @@ Applying variable ordering:
         Effect: var-order
         Number of graph edges: 1
 
-        Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [before]
-        Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [after]
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [before]
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [after]
 
       Found new best variable order.
 
@@ -37,8 +37,8 @@ Applying variable ordering:
         Effect: var-order
         Number of graph edges: 1
 
-        Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [before]
-        Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [after]
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [before]
+        Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [after]
 
       Applying 2 orderers, sequentially:
         Applying Weighted Cuthill-McKee algorithm:
@@ -47,16 +47,16 @@ Applying variable ordering:
           Effect: var-order
           Number of graph edges: 1
 
-          Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [before]
-          Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [after]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [after]
 
         Reversing the variable order:
           Relations: legacy
           Effect: var-order
-          Number of hyper-edges: 2
+          Number of hyper-edges: 3
 
-          Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [before]
-          Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [reversed]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [reversed]
 
       Applying 2 orderers, sequentially:
         Applying Sloan algorithm:
@@ -64,16 +64,16 @@ Applying variable ordering:
           Effect: var-order
           Number of graph edges: 1
 
-          Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [before]
-          Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [after]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [after]
 
         Reversing the variable order:
           Relations: legacy
           Effect: var-order
-          Number of hyper-edges: 2
+          Number of hyper-edges: 3
 
-          Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [before]
-          Total span:   1 (total)   0.50 (avg/edge) / WES:   0.500000 (total)   0.250000 (avg/edge) [reversed]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [before]
+          Total span:   1 (total)   0.33 (avg/edge) / WES:   0.500000 (total)   0.166667 (avg/edge) [reversed]
 
     Applying FORCE algorithm:
       Metric: total-span
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/state_req_inv_all_ctrl_beh.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/state_req_inv_all_ctrl_beh.cif.out
index 4925eec8e96bf2515e93e2779c992fede468f776..2bb759b525aa97a91c24f21c4e75d3af026101fb 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/datasynth/state_req_inv_all_ctrl_beh.cif.out
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/state_req_inv_all_ctrl_beh.cif.out
@@ -21,7 +21,7 @@ Applying variable ordering:
       Metric: wes
       Relations: legacy
       Effect: var-order
-      Number of hyper-edges: 11
+      Number of hyper-edges: 8
 
       Applying Weighted Cuthill-McKee algorithm:
         Node finder: george-liu
@@ -29,8 +29,8 @@ Applying variable ordering:
         Effect: var-order
         Number of graph edges: 1
 
-        Total span:   1 (total)   0.09 (avg/edge) / WES:   0.215909 (total)   0.019628 (avg/edge) [before]
-        Total span:   1 (total)   0.09 (avg/edge) / WES:   0.215909 (total)   0.019628 (avg/edge) [after]
+        Total span:   1 (total)   0.13 (avg/edge) / WES:   0.203125 (total)   0.025391 (avg/edge) [before]
+        Total span:   1 (total)   0.13 (avg/edge) / WES:   0.203125 (total)   0.025391 (avg/edge) [after]
 
       Found new best variable order.
 
@@ -39,8 +39,8 @@ Applying variable ordering:
         Effect: var-order
         Number of graph edges: 1
 
-        Total span:   1 (total)   0.09 (avg/edge) / WES:   0.215909 (total)   0.019628 (avg/edge) [before]
-        Total span:   1 (total)   0.09 (avg/edge) / WES:   0.215909 (total)   0.019628 (avg/edge) [after]
+        Total span:   1 (total)   0.13 (avg/edge) / WES:   0.203125 (total)   0.025391 (avg/edge) [before]
+        Total span:   1 (total)   0.13 (avg/edge) / WES:   0.203125 (total)   0.025391 (avg/edge) [after]
 
       Applying 2 orderers, sequentially:
         Applying Weighted Cuthill-McKee algorithm:
@@ -49,18 +49,16 @@ Applying variable ordering:
           Effect: var-order
           Number of graph edges: 1
 
-          Total span:   1 (total)   0.09 (avg/edge) / WES:   0.215909 (total)   0.019628 (avg/edge) [before]
-          Total span:   1 (total)   0.09 (avg/edge) / WES:   0.215909 (total)   0.019628 (avg/edge) [after]
+          Total span:   1 (total)   0.13 (avg/edge) / WES:   0.203125 (total)   0.025391 (avg/edge) [before]
+          Total span:   1 (total)   0.13 (avg/edge) / WES:   0.203125 (total)   0.025391 (avg/edge) [after]
 
         Reversing the variable order:
           Relations: legacy
           Effect: var-order
-          Number of hyper-edges: 11
+          Number of hyper-edges: 8
 
-          Total span:   1 (total)   0.09 (avg/edge) / WES:   0.215909 (total)   0.019628 (avg/edge) [before]
-          Total span:   1 (total)   0.09 (avg/edge) / WES:   0.215909 (total)   0.019628 (avg/edge) [reversed]
-
-      Found new best variable order.
+          Total span:   1 (total)   0.13 (avg/edge) / WES:   0.203125 (total)   0.025391 (avg/edge) [before]
+          Total span:   1 (total)   0.13 (avg/edge) / WES:   0.203125 (total)   0.025391 (avg/edge) [reversed]
 
       Applying 2 orderers, sequentially:
         Applying Sloan algorithm:
@@ -68,16 +66,16 @@ Applying variable ordering:
           Effect: var-order
           Number of graph edges: 1
 
-          Total span:   1 (total)   0.09 (avg/edge) / WES:   0.215909 (total)   0.019628 (avg/edge) [before]
-          Total span:   1 (total)   0.09 (avg/edge) / WES:   0.215909 (total)   0.019628 (avg/edge) [after]
+          Total span:   1 (total)   0.13 (avg/edge) / WES:   0.203125 (total)   0.025391 (avg/edge) [before]
+          Total span:   1 (total)   0.13 (avg/edge) / WES:   0.203125 (total)   0.025391 (avg/edge) [after]
 
         Reversing the variable order:
           Relations: legacy
           Effect: var-order
-          Number of hyper-edges: 11
+          Number of hyper-edges: 8
 
-          Total span:   1 (total)   0.09 (avg/edge) / WES:   0.215909 (total)   0.019628 (avg/edge) [before]
-          Total span:   1 (total)   0.09 (avg/edge) / WES:   0.215909 (total)   0.019628 (avg/edge) [reversed]
+          Total span:   1 (total)   0.13 (avg/edge) / WES:   0.203125 (total)   0.025391 (avg/edge) [before]
+          Total span:   1 (total)   0.13 (avg/edge) / WES:   0.203125 (total)   0.025391 (avg/edge) [reversed]
 
     Applying FORCE algorithm:
       Metric: total-span
@@ -86,9 +84,9 @@ Applying variable ordering:
       Number of hyper-edges: 2
       Maximum number of iterations: 20
 
-      Total span:   1 (total)   0.50 (avg/edge) / WES:   0.437500 (total)   0.218750 (avg/edge) [before]
+      Total span:   1 (total)   0.50 (avg/edge) / WES:   0.250000 (total)   0.125000 (avg/edge) [before]
       Total span:   1 (total)   0.50 (avg/edge) / WES:   0.250000 (total)   0.125000 (avg/edge) [iteration 1]
-      Total span:   1 (total)   0.50 (avg/edge) / WES:   0.437500 (total)   0.218750 (avg/edge) [after]
+      Total span:   1 (total)   0.50 (avg/edge) / WES:   0.250000 (total)   0.125000 (avg/edge) [after]
 
     Applying sliding window algorithm:
       Size: 4
@@ -98,20 +96,10 @@ Applying variable ordering:
       Number of hyper-edges: 2
       Window length: 4
 
-      Total span:   1 (total)   0.50 (avg/edge) / WES:   0.437500 (total)   0.218750 (avg/edge) [before]
-      Total span:   1 (total)   0.50 (avg/edge) / WES:   0.437500 (total)   0.218750 (avg/edge) [after]
+      Total span:   1 (total)   0.50 (avg/edge) / WES:   0.250000 (total)   0.125000 (avg/edge) [before]
+      Total span:   1 (total)   0.50 (avg/edge) / WES:   0.250000 (total)   0.125000 (avg/edge) [after]
 
-Variable order changed.
-
-CIF variables and location pointers:
-  Nr     Kind               Type        Name  Group  BDD vars  CIF values  BDD values  Values used
-  -----  -----------------  ----------  ----  -----  --------  ----------  ----------  -----------
-  1      discrete variable  int[0..10]  p.z   0      4 * 2     11 * 2      16 * 2      ~69%
-  2      discrete variable  int[0..10]  p.y   1      4 * 2     11 * 2      16 * 2      ~69%
-  3      discrete variable  int[0..10]  p.x   2      4 * 2     11 * 2      16 * 2      ~69%
-  4      discrete variable  bool        p.b   3      1 * 2     2 * 2       2 * 2       100%
-  -----  -----------------  ----------  ----  -----  --------  ----------  ----------  -----------
-  Total                                       4      26        70          100         70%
+Variable order unchanged.
 
 Starting data-based synthesis.
 
@@ -126,10 +114,10 @@ Invariant (components state req invariant):  <bdd 12n 27p>
 Invariant (locations state req invariant):   true
 Invariant (system state req invariant):      <bdd 12n 27p>
 
-Initial   (discrete variable 0):             true
+Initial   (discrete variable 0):             not p.b
 Initial   (discrete variable 1):             true
 Initial   (discrete variable 2):             true
-Initial   (discrete variable 3):             not p.b
+Initial   (discrete variable 3):             true
 Initial   (discrete variables):              <bdd 13n 125p>
 Initial   (components init predicate):       true
 Initial   (aut/locs init predicate):         true
@@ -179,19 +167,19 @@ Backward controlled-behavior: <bdd 12n 27p> [fixed point].
 Round 1: computing backward uncontrolled bad-state predicate.
 Backward uncontrolled bad-state: <bdd 12n 52p> [current/previous controlled behavior predicate]
 Backward reachability: iteration 1.
-Backward uncontrolled bad-state: <bdd 12n 52p> -> <bdd 16n 97p> [backward reach with edge: (event: u_e) (guard: not p.b) (assignments: p.x := p.x + 2, p.b := true)]
+Backward uncontrolled bad-state: <bdd 12n 52p> -> <bdd 14n 105p> [backward reach with edge: (event: u_e) (guard: not p.b) (assignments: p.x := p.x + 2, p.b := true)]
 Backward reachability: iteration 2.
-Backward uncontrolled bad-state: <bdd 16n 97p> [fixed point].
-Controlled behavior: <bdd 12n 27p> -> <bdd 16n 54p>.
+Backward uncontrolled bad-state: <bdd 14n 105p> [fixed point].
+Controlled behavior: <bdd 12n 27p> -> <bdd 14n 54p>.
 
 Round 1: computing forward controlled-behavior predicate.
 Forward controlled-behavior: <bdd 13n 125p> [initialization predicate]
-Forward controlled-behavior: <bdd 13n 125p> -> <bdd 13n 27p> [restricted to current/previous controlled-behavior predicate: <bdd 16n 54p>]
+Forward controlled-behavior: <bdd 13n 125p> -> <bdd 13n 27p> [restricted to current/previous controlled-behavior predicate: <bdd 14n 54p>]
 Forward reachability: iteration 1.
-Forward controlled-behavior: <bdd 13n 27p> -> <bdd 20n 63p> [forward reach with edge: (event: u_e) (guard: not p.b) (assignments: p.x := p.x + 2, p.b := true), restricted to current/previous controlled-behavior predicate: <bdd 16n 54p>]
+Forward controlled-behavior: <bdd 13n 27p> -> <bdd 17n 63p> [forward reach with edge: (event: u_e) (guard: not p.b) (assignments: p.x := p.x + 2, p.b := true), restricted to current/previous controlled-behavior predicate: <bdd 14n 54p>]
 Forward reachability: iteration 2.
-Forward controlled-behavior: <bdd 20n 63p> [fixed point].
-Controlled behavior: <bdd 16n 54p> -> <bdd 20n 63p>.
+Forward controlled-behavior: <bdd 17n 63p> [fixed point].
+Controlled behavior: <bdd 14n 54p> -> <bdd 17n 63p>.
 
 Round 1: finished, need another round.
 
@@ -199,32 +187,32 @@ Round 2: started.
 
 Round 2: computing backward controlled-behavior predicate.
 Backward controlled-behavior: true [marker predicate]
-Backward controlled-behavior: true -> <bdd 20n 63p> [restricted to current/previous controlled-behavior predicate: <bdd 20n 63p>]
+Backward controlled-behavior: true -> <bdd 17n 63p> [restricted to current/previous controlled-behavior predicate: <bdd 17n 63p>]
 Backward reachability: iteration 1.
-Backward controlled-behavior: <bdd 20n 63p> [fixed point].
+Backward controlled-behavior: <bdd 17n 63p> [fixed point].
 
 Round 2: computing backward uncontrolled bad-state predicate.
-Backward uncontrolled bad-state: <bdd 20n 124p> [current/previous controlled behavior predicate]
+Backward uncontrolled bad-state: <bdd 17n 124p> [current/previous controlled behavior predicate]
 Backward reachability: iteration 1.
 
 Round 2: finished, controlled behavior is stable.
 
 Computing controlled system guards.
 
-Edge (event: c_e) (guard: true) (assignments: p.y := p.y + 2): guard: true -> <bdd 20n 63p>.
+Edge (event: c_e) (guard: true) (assignments: p.y := p.y + 2): guard: true -> <bdd 17n 63p>.
 
 Final synthesis result:
-  State: (controlled-behavior: <bdd 20n 63p>)
+  State: (controlled-behavior: <bdd 17n 63p>)
     Edge: (event: u_e) (guard: not p.b) (assignments: p.x := p.x + 2, p.b := true)
-    Edge: (event: c_e) (guard: true -> <bdd 20n 63p>) (assignments: p.y := p.y + 2)
+    Edge: (event: c_e) (guard: true -> <bdd 17n 63p>) (assignments: p.y := p.y + 2)
 
 Controlled system:                     exactly 490 states.
 
-Initial (synthesis result):            <bdd 20n 63p>
+Initial (synthesis result):            <bdd 17n 63p>
 Initial (uncontrolled system):         <bdd 13n 125p>
 Initial (controlled system):           <bdd 13n 27p>
 Initial (removed by supervisor):       <bdd 29n 300p>
-Initial (added by supervisor):         <bdd 29n 623p>
+Initial (added by supervisor):         <bdd 29n 329p>
 
 Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
   Initial: <bdd 13n 27p> -> <bdd 12n 27p> [assume <bdd 13n 125p>].
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/state_req_inv_all_ctrl_beh.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/state_req_inv_all_ctrl_beh.ctrlsys.cif
index 883598427449a5cc001cc5c26d22cc957bd9cbb3..e50d4a30f7d2d80294153e088c66067f13793425 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/datasynth/state_req_inv_all_ctrl_beh.ctrlsys.cif
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/state_req_inv_all_ctrl_beh.ctrlsys.cif
@@ -13,9 +13,9 @@ plant automaton p:
 end
 supervisor automaton sup:
   alphabet c_e;
-  initial (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and (p.x = 0 or p.x = 4)) or ((p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and p.x = 2) or (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and (p.x = 1 or p.x = 3))) or ((p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and ((p.y = 1 or p.y = 5) and (p.x = 0 or p.x = 4)) or ((p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and ((p.y = 1 or p.y = 5) and p.x = 2) or (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and ((p.y = 1 or p.y = 5) and (p.x = 1 or p.x = 3)))) or ((p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and (p.y = 3 and (p.x = 0 or p.x = 4)) or ((p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and (p.y = 3 and p.x = 2) or (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and (p.y = 3 and (p.x = 1 or p.x = 3))) or ((p.z = 1 or p.z = 5) and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and (p.x = 0 or p.x = 4)) or (p.z = 1 or p.z = 5) and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and p.x = 2) or ((p.z = 1 or p.z = 5) and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and (p.x = 1 or p.x = 3)) or (p.z = 1 or p.z = 5) and ((p.y = 1 or p.y = 5) and (p.x = 0 or p.x = 4))))) or ((p.z = 1 or p.z = 5) and ((p.y = 1 or p.y = 5) and p.x = 2) or ((p.z = 1 or p.z = 5) and ((p.y = 1 or p.y = 5) and (p.x = 1 or p.x = 3)) or (p.z = 1 or p.z = 5) and (p.y = 3 and (p.x = 0 or p.x = 4))) or ((p.z = 1 or p.z = 5) and (p.y = 3 and p.x = 2) or (p.z = 1 or p.z = 5) and (p.y = 3 and (p.x = 1 or p.x = 3)) or (p.z = 3 and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and (p.x = 0 or p.x = 4)) or p.z = 3 and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and p.x = 2))) or (p.z = 3 and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and (p.x = 1 or p.x = 3)) or (p.z = 3 and ((p.y = 1 or p.y = 5) and (p.x = 0 or p.x = 4)) or p.z = 3 and ((p.y = 1 or p.y = 5) and p.x = 2)) or (p.z = 3 and ((p.y = 1 or p.y = 5) and (p.x = 1 or p.x = 3)) or p.z = 3 and (p.y = 3 and (p.x = 0 or p.x = 4)) or (p.z = 3 and (p.y = 3 and p.x = 2) or p.z = 3 and (p.y = 3 and (p.x = 1 or p.x = 3))))));
+  initial (p.x = 0 or p.x = 4) and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or ((p.x = 0 or p.x = 4) and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and (p.z = 1 or p.z = 5)) or (p.x = 0 or p.x = 4) and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and p.z = 3)) or ((p.x = 0 or p.x = 4) and ((p.y = 1 or p.y = 5) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or ((p.x = 0 or p.x = 4) and ((p.y = 1 or p.y = 5) and (p.z = 1 or p.z = 5)) or (p.x = 0 or p.x = 4) and ((p.y = 1 or p.y = 5) and p.z = 3))) or ((p.x = 0 or p.x = 4) and (p.y = 3 and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or ((p.x = 0 or p.x = 4) and (p.y = 3 and (p.z = 1 or p.z = 5)) or (p.x = 0 or p.x = 4) and (p.y = 3 and p.z = 3)) or (p.x = 2 and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or p.x = 2 and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and (p.z = 1 or p.z = 5)) or (p.x = 2 and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and p.z = 3) or p.x = 2 and ((p.y = 1 or p.y = 5) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)))))) or (p.x = 2 and ((p.y = 1 or p.y = 5) and (p.z = 1 or p.z = 5)) or (p.x = 2 and ((p.y = 1 or p.y = 5) and p.z = 3) or p.x = 2 and (p.y = 3 and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)))) or (p.x = 2 and (p.y = 3 and (p.z = 1 or p.z = 5)) or p.x = 2 and (p.y = 3 and p.z = 3) or ((p.x = 1 or p.x = 3) and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or (p.x = 1 or p.x = 3) and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and (p.z = 1 or p.z = 5)))) or ((p.x = 1 or p.x = 3) and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and p.z = 3) or ((p.x = 1 or p.x = 3) and ((p.y = 1 or p.y = 5) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or (p.x = 1 or p.x = 3) and ((p.y = 1 or p.y = 5) and (p.z = 1 or p.z = 5))) or ((p.x = 1 or p.x = 3) and ((p.y = 1 or p.y = 5) and p.z = 3) or (p.x = 1 or p.x = 3) and (p.y = 3 and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or ((p.x = 1 or p.x = 3) and (p.y = 3 and (p.z = 1 or p.z = 5)) or (p.x = 1 or p.x = 3) and (p.y = 3 and p.z = 3)))));
   location:
     initial;
     marked;
-    edge c_e when (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and (p.y = 0 or p.y = 4) and (p.x = 0 and not p.b) or ((p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and ((p.y = 0 or p.y = 4) and p.x = 4) or (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and ((p.y = 0 or p.y = 4) and p.x = 2)) or ((p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and (p.y = 0 or p.y = 4) and (p.x = 6 and p.b) or (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and (p.y = 0 or p.y = 4) and (p.x = 1 and not p.b) or ((p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and (p.y = 0 or p.y = 4) and (p.x = 5 and p.b) or (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and ((p.y = 0 or p.y = 4) and p.x = 3))) or ((p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and p.y = 2 and (p.x = 0 and not p.b) or (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and (p.y = 2 and p.x = 4) or ((p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and (p.y = 2 and p.x = 2) or (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and p.y = 2 and (p.x = 6 and p.b)) or ((p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and p.y = 2 and (p.x = 1 and not p.b) or (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and p.y = 2 and (p.x = 5 and p.b) or ((p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and (p.y = 2 and p.x = 3) or (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and (p.y = 1 or p.y = 3) and (p.x = 0 and not p.b)))) or ((p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and ((p.y = 1 or p.y = 3) and p.x = 4) or (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and ((p.y = 1 or p.y = 3) and p.x = 2) or ((p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and (p.y = 1 or p.y = 3) and (p.x = 6 and p.b) or (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and (p.y = 1 or p.y = 3) and (p.x = 1 and not p.b)) or ((p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and (p.y = 1 or p.y = 3) and (p.x = 5 and p.b) or (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and ((p.y = 1 or p.y = 3) and p.x = 3) or ((p.z = 1 or p.z = 5) and (p.y = 0 or p.y = 4) and (p.x = 0 and not p.b) or (p.z = 1 or p.z = 5) and ((p.y = 0 or p.y = 4) and p.x = 4))) or ((p.z = 1 or p.z = 5) and ((p.y = 0 or p.y = 4) and p.x = 2) or (p.z = 1 or p.z = 5) and (p.y = 0 or p.y = 4) and (p.x = 6 and p.b) or ((p.z = 1 or p.z = 5) and (p.y = 0 or p.y = 4) and (p.x = 1 and not p.b) or (p.z = 1 or p.z = 5) and (p.y = 0 or p.y = 4) and (p.x = 5 and p.b)) or ((p.z = 1 or p.z = 5) and ((p.y = 0 or p.y = 4) and p.x = 3) or (p.z = 1 or p.z = 5) and p.y = 2 and (p.x = 0 and not p.b) or ((p.z = 1 or p.z = 5) and (p.y = 2 and p.x = 4) or (p.z = 1 or p.z = 5) and (p.y = 2 and p.x = 2))))) or ((p.z = 1 or p.z = 5) and p.y = 2 and (p.x = 6 and p.b) or (p.z = 1 or p.z = 5) and p.y = 2 and (p.x = 1 and not p.b) or ((p.z = 1 or p.z = 5) and p.y = 2 and (p.x = 5 and p.b) or (p.z = 1 or p.z = 5) and (p.y = 2 and p.x = 3)) or ((p.z = 1 or p.z = 5) and (p.y = 1 or p.y = 3) and (p.x = 0 and not p.b) or (p.z = 1 or p.z = 5) and ((p.y = 1 or p.y = 3) and p.x = 4) or ((p.z = 1 or p.z = 5) and ((p.y = 1 or p.y = 3) and p.x = 2) or (p.z = 1 or p.z = 5) and (p.y = 1 or p.y = 3) and (p.x = 6 and p.b))) or ((p.z = 1 or p.z = 5) and (p.y = 1 or p.y = 3) and (p.x = 1 and not p.b) or (p.z = 1 or p.z = 5) and (p.y = 1 or p.y = 3) and (p.x = 5 and p.b) or ((p.z = 1 or p.z = 5) and ((p.y = 1 or p.y = 3) and p.x = 3) or p.z = 3 and (p.y = 0 or p.y = 4) and (p.x = 0 and not p.b)) or (p.z = 3 and ((p.y = 0 or p.y = 4) and p.x = 4) or p.z = 3 and ((p.y = 0 or p.y = 4) and p.x = 2) or (p.z = 3 and (p.y = 0 or p.y = 4) and (p.x = 6 and p.b) or p.z = 3 and (p.y = 0 or p.y = 4) and (p.x = 1 and not p.b)))) or (p.z = 3 and (p.y = 0 or p.y = 4) and (p.x = 5 and p.b) or p.z = 3 and ((p.y = 0 or p.y = 4) and p.x = 3) or (p.z = 3 and p.y = 2 and (p.x = 0 and not p.b) or p.z = 3 and (p.y = 2 and p.x = 4)) or (p.z = 3 and (p.y = 2 and p.x = 2) or p.z = 3 and p.y = 2 and (p.x = 6 and p.b) or (p.z = 3 and p.y = 2 and (p.x = 1 and not p.b) or p.z = 3 and p.y = 2 and (p.x = 5 and p.b))) or (p.z = 3 and (p.y = 2 and p.x = 3) or p.z = 3 and (p.y = 1 or p.y = 3) and (p.x = 0 and not p.b) or (p.z = 3 and ((p.y = 1 or p.y = 3) and p.x = 4) or p.z = 3 and ((p.y = 1 or p.y = 3) and p.x = 2)) or (p.z = 3 and (p.y = 1 or p.y = 3) and (p.x = 6 and p.b) or p.z = 3 and (p.y = 1 or p.y = 3) and (p.x = 1 and not p.b) or (p.z = 3 and (p.y = 1 or p.y = 3) and (p.x = 5 and p.b) or p.z = 3 and ((p.y = 1 or p.y = 3) and p.x = 3))))));
+    edge c_e when not p.b and (p.x = 0 or p.x = 4) and ((p.y = 0 or p.y = 4) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or (not p.b and (p.x = 0 or p.x = 4) and ((p.y = 0 or p.y = 4) and (p.z = 1 or p.z = 5)) or not p.b and (p.x = 0 or p.x = 4) and ((p.y = 0 or p.y = 4) and p.z = 3)) or (not p.b and (p.x = 0 or p.x = 4) and (p.y = 2 and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or not p.b and (p.x = 0 or p.x = 4) and (p.y = 2 and (p.z = 1 or p.z = 5)) or (not p.b and (p.x = 0 or p.x = 4) and (p.y = 2 and p.z = 3) or not p.b and (p.x = 0 or p.x = 4) and ((p.y = 1 or p.y = 3) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))))) or (not p.b and (p.x = 0 or p.x = 4) and ((p.y = 1 or p.y = 3) and (p.z = 1 or p.z = 5)) or not p.b and (p.x = 0 or p.x = 4) and ((p.y = 1 or p.y = 3) and p.z = 3) or (not p.b and p.x = 2 and ((p.y = 0 or p.y = 4) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or not p.b and p.x = 2 and ((p.y = 0 or p.y = 4) and (p.z = 1 or p.z = 5))) or (not p.b and p.x = 2 and ((p.y = 0 or p.y = 4) and p.z = 3) or not p.b and p.x = 2 and (p.y = 2 and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or (not p.b and p.x = 2 and (p.y = 2 and (p.z = 1 or p.z = 5)) or not p.b and p.x = 2 and (p.y = 2 and p.z = 3)))) or (not p.b and p.x = 2 and ((p.y = 1 or p.y = 3) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or not p.b and p.x = 2 and ((p.y = 1 or p.y = 3) and (p.z = 1 or p.z = 5)) or (not p.b and p.x = 2 and ((p.y = 1 or p.y = 3) and p.z = 3) or not p.b and (p.x = 1 or p.x = 3) and ((p.y = 0 or p.y = 4) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)))) or (not p.b and (p.x = 1 or p.x = 3) and ((p.y = 0 or p.y = 4) and (p.z = 1 or p.z = 5)) or not p.b and (p.x = 1 or p.x = 3) and ((p.y = 0 or p.y = 4) and p.z = 3) or (not p.b and (p.x = 1 or p.x = 3) and (p.y = 2 and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or not p.b and (p.x = 1 or p.x = 3) and (p.y = 2 and (p.z = 1 or p.z = 5)))) or (not p.b and (p.x = 1 or p.x = 3) and (p.y = 2 and p.z = 3) or not p.b and (p.x = 1 or p.x = 3) and ((p.y = 1 or p.y = 3) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or (not p.b and (p.x = 1 or p.x = 3) and ((p.y = 1 or p.y = 3) and (p.z = 1 or p.z = 5)) or not p.b and (p.x = 1 or p.x = 3) and ((p.y = 1 or p.y = 3) and p.z = 3)) or (p.b and p.x = 4 and ((p.y = 0 or p.y = 4) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or p.b and p.x = 4 and ((p.y = 0 or p.y = 4) and (p.z = 1 or p.z = 5)) or (p.b and p.x = 4 and ((p.y = 0 or p.y = 4) and p.z = 3) or p.b and p.x = 4 and (p.y = 2 and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))))))) or (p.b and p.x = 4 and (p.y = 2 and (p.z = 1 or p.z = 5)) or p.b and p.x = 4 and (p.y = 2 and p.z = 3) or (p.b and p.x = 4 and ((p.y = 1 or p.y = 3) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or p.b and p.x = 4 and ((p.y = 1 or p.y = 3) and (p.z = 1 or p.z = 5))) or (p.b and p.x = 4 and ((p.y = 1 or p.y = 3) and p.z = 3) or p.b and (p.x = 2 or p.x = 6) and ((p.y = 0 or p.y = 4) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or (p.b and (p.x = 2 or p.x = 6) and ((p.y = 0 or p.y = 4) and (p.z = 1 or p.z = 5)) or p.b and (p.x = 2 or p.x = 6) and ((p.y = 0 or p.y = 4) and p.z = 3))) or (p.b and (p.x = 2 or p.x = 6) and (p.y = 2 and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or p.b and (p.x = 2 or p.x = 6) and (p.y = 2 and (p.z = 1 or p.z = 5)) or (p.b and (p.x = 2 or p.x = 6) and (p.y = 2 and p.z = 3) or p.b and (p.x = 2 or p.x = 6) and ((p.y = 1 or p.y = 3) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)))) or (p.b and (p.x = 2 or p.x = 6) and ((p.y = 1 or p.y = 3) and (p.z = 1 or p.z = 5)) or p.b and (p.x = 2 or p.x = 6) and ((p.y = 1 or p.y = 3) and p.z = 3) or (p.b and p.x = 5 and ((p.y = 0 or p.y = 4) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or p.b and p.x = 5 and ((p.y = 0 or p.y = 4) and (p.z = 1 or p.z = 5))))) or (p.b and p.x = 5 and ((p.y = 0 or p.y = 4) and p.z = 3) or p.b and p.x = 5 and (p.y = 2 and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or (p.b and p.x = 5 and (p.y = 2 and (p.z = 1 or p.z = 5)) or p.b and p.x = 5 and (p.y = 2 and p.z = 3)) or (p.b and p.x = 5 and ((p.y = 1 or p.y = 3) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or p.b and p.x = 5 and ((p.y = 1 or p.y = 3) and (p.z = 1 or p.z = 5)) or (p.b and p.x = 5 and ((p.y = 1 or p.y = 3) and p.z = 3) or p.b and p.x = 3 and ((p.y = 0 or p.y = 4) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))))) or (p.b and p.x = 3 and ((p.y = 0 or p.y = 4) and (p.z = 1 or p.z = 5)) or p.b and p.x = 3 and ((p.y = 0 or p.y = 4) and p.z = 3) or (p.b and p.x = 3 and (p.y = 2 and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or p.b and p.x = 3 and (p.y = 2 and (p.z = 1 or p.z = 5))) or (p.b and p.x = 3 and (p.y = 2 and p.z = 3) or p.b and p.x = 3 and ((p.y = 1 or p.y = 3) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or (p.b and p.x = 3 and ((p.y = 1 or p.y = 3) and (p.z = 1 or p.z = 5)) or p.b and p.x = 3 and ((p.y = 1 or p.y = 3) and p.z = 3))))));
 end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/state_req_inv_per_edge.cif.out b/cif/org.eclipse.escet.cif.tests/tests/datasynth/state_req_inv_per_edge.cif.out
index d740a5c5e8f82351b07525824c3e6d7b872432a2..c67edbc4836bfbb157878dccb942aad62e48ef07 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/datasynth/state_req_inv_per_edge.cif.out
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/state_req_inv_per_edge.cif.out
@@ -21,7 +21,7 @@ Applying variable ordering:
       Metric: wes
       Relations: legacy
       Effect: var-order
-      Number of hyper-edges: 11
+      Number of hyper-edges: 8
 
       Applying Weighted Cuthill-McKee algorithm:
         Node finder: george-liu
@@ -29,8 +29,8 @@ Applying variable ordering:
         Effect: var-order
         Number of graph edges: 1
 
-        Total span:   1 (total)   0.09 (avg/edge) / WES:   0.215909 (total)   0.019628 (avg/edge) [before]
-        Total span:   1 (total)   0.09 (avg/edge) / WES:   0.215909 (total)   0.019628 (avg/edge) [after]
+        Total span:   1 (total)   0.13 (avg/edge) / WES:   0.203125 (total)   0.025391 (avg/edge) [before]
+        Total span:   1 (total)   0.13 (avg/edge) / WES:   0.203125 (total)   0.025391 (avg/edge) [after]
 
       Found new best variable order.
 
@@ -39,8 +39,8 @@ Applying variable ordering:
         Effect: var-order
         Number of graph edges: 1
 
-        Total span:   1 (total)   0.09 (avg/edge) / WES:   0.215909 (total)   0.019628 (avg/edge) [before]
-        Total span:   1 (total)   0.09 (avg/edge) / WES:   0.215909 (total)   0.019628 (avg/edge) [after]
+        Total span:   1 (total)   0.13 (avg/edge) / WES:   0.203125 (total)   0.025391 (avg/edge) [before]
+        Total span:   1 (total)   0.13 (avg/edge) / WES:   0.203125 (total)   0.025391 (avg/edge) [after]
 
       Applying 2 orderers, sequentially:
         Applying Weighted Cuthill-McKee algorithm:
@@ -49,18 +49,16 @@ Applying variable ordering:
           Effect: var-order
           Number of graph edges: 1
 
-          Total span:   1 (total)   0.09 (avg/edge) / WES:   0.215909 (total)   0.019628 (avg/edge) [before]
-          Total span:   1 (total)   0.09 (avg/edge) / WES:   0.215909 (total)   0.019628 (avg/edge) [after]
+          Total span:   1 (total)   0.13 (avg/edge) / WES:   0.203125 (total)   0.025391 (avg/edge) [before]
+          Total span:   1 (total)   0.13 (avg/edge) / WES:   0.203125 (total)   0.025391 (avg/edge) [after]
 
         Reversing the variable order:
           Relations: legacy
           Effect: var-order
-          Number of hyper-edges: 11
+          Number of hyper-edges: 8
 
-          Total span:   1 (total)   0.09 (avg/edge) / WES:   0.215909 (total)   0.019628 (avg/edge) [before]
-          Total span:   1 (total)   0.09 (avg/edge) / WES:   0.215909 (total)   0.019628 (avg/edge) [reversed]
-
-      Found new best variable order.
+          Total span:   1 (total)   0.13 (avg/edge) / WES:   0.203125 (total)   0.025391 (avg/edge) [before]
+          Total span:   1 (total)   0.13 (avg/edge) / WES:   0.203125 (total)   0.025391 (avg/edge) [reversed]
 
       Applying 2 orderers, sequentially:
         Applying Sloan algorithm:
@@ -68,16 +66,16 @@ Applying variable ordering:
           Effect: var-order
           Number of graph edges: 1
 
-          Total span:   1 (total)   0.09 (avg/edge) / WES:   0.215909 (total)   0.019628 (avg/edge) [before]
-          Total span:   1 (total)   0.09 (avg/edge) / WES:   0.215909 (total)   0.019628 (avg/edge) [after]
+          Total span:   1 (total)   0.13 (avg/edge) / WES:   0.203125 (total)   0.025391 (avg/edge) [before]
+          Total span:   1 (total)   0.13 (avg/edge) / WES:   0.203125 (total)   0.025391 (avg/edge) [after]
 
         Reversing the variable order:
           Relations: legacy
           Effect: var-order
-          Number of hyper-edges: 11
+          Number of hyper-edges: 8
 
-          Total span:   1 (total)   0.09 (avg/edge) / WES:   0.215909 (total)   0.019628 (avg/edge) [before]
-          Total span:   1 (total)   0.09 (avg/edge) / WES:   0.215909 (total)   0.019628 (avg/edge) [reversed]
+          Total span:   1 (total)   0.13 (avg/edge) / WES:   0.203125 (total)   0.025391 (avg/edge) [before]
+          Total span:   1 (total)   0.13 (avg/edge) / WES:   0.203125 (total)   0.025391 (avg/edge) [reversed]
 
     Applying FORCE algorithm:
       Metric: total-span
@@ -86,9 +84,9 @@ Applying variable ordering:
       Number of hyper-edges: 2
       Maximum number of iterations: 20
 
-      Total span:   1 (total)   0.50 (avg/edge) / WES:   0.437500 (total)   0.218750 (avg/edge) [before]
+      Total span:   1 (total)   0.50 (avg/edge) / WES:   0.250000 (total)   0.125000 (avg/edge) [before]
       Total span:   1 (total)   0.50 (avg/edge) / WES:   0.250000 (total)   0.125000 (avg/edge) [iteration 1]
-      Total span:   1 (total)   0.50 (avg/edge) / WES:   0.437500 (total)   0.218750 (avg/edge) [after]
+      Total span:   1 (total)   0.50 (avg/edge) / WES:   0.250000 (total)   0.125000 (avg/edge) [after]
 
     Applying sliding window algorithm:
       Size: 4
@@ -98,20 +96,10 @@ Applying variable ordering:
       Number of hyper-edges: 2
       Window length: 4
 
-      Total span:   1 (total)   0.50 (avg/edge) / WES:   0.437500 (total)   0.218750 (avg/edge) [before]
-      Total span:   1 (total)   0.50 (avg/edge) / WES:   0.437500 (total)   0.218750 (avg/edge) [after]
+      Total span:   1 (total)   0.50 (avg/edge) / WES:   0.250000 (total)   0.125000 (avg/edge) [before]
+      Total span:   1 (total)   0.50 (avg/edge) / WES:   0.250000 (total)   0.125000 (avg/edge) [after]
 
-Variable order changed.
-
-CIF variables and location pointers:
-  Nr     Kind               Type        Name  Group  BDD vars  CIF values  BDD values  Values used
-  -----  -----------------  ----------  ----  -----  --------  ----------  ----------  -----------
-  1      discrete variable  int[0..10]  p.z   0      4 * 2     11 * 2      16 * 2      ~69%
-  2      discrete variable  int[0..10]  p.y   1      4 * 2     11 * 2      16 * 2      ~69%
-  3      discrete variable  int[0..10]  p.x   2      4 * 2     11 * 2      16 * 2      ~69%
-  4      discrete variable  bool        p.b   3      1 * 2     2 * 2       2 * 2       100%
-  -----  -----------------  ----------  ----  -----  --------  ----------  ----------  -----------
-  Total                                       4      26        70          100         70%
+Variable order unchanged.
 
 Starting data-based synthesis.
 
@@ -126,10 +114,10 @@ Invariant (components state req invariant):  <bdd 12n 27p>
 Invariant (locations state req invariant):   true
 Invariant (system state req invariant):      <bdd 12n 27p>
 
-Initial   (discrete variable 0):             true
+Initial   (discrete variable 0):             not p.b
 Initial   (discrete variable 1):             true
 Initial   (discrete variable 2):             true
-Initial   (discrete variable 3):             not p.b
+Initial   (discrete variable 3):             true
 Initial   (discrete variables):              <bdd 13n 125p>
 Initial   (components init predicate):       true
 Initial   (aut/locs init predicate):         true
@@ -163,25 +151,25 @@ Initialized controlled-initialization predicate: <bdd 13n 125p>.
 
 Restricting behavior using state requirements.
 
-Controlled behavior: true -> (p.x != 8 or p.b) and (p.x != 10 or p.b) and ((p.x != 6 or p.b) and ((p.x != 9 or p.b) and (not(p.x = 5 or p.x = 7) or p.b))) [state requirement: (p.x = 0 or p.x = 4) and not p.b or (p.x = 2 and not p.b or (p.x = 1 or p.x = 3) and not p.b), edge: (event: u_e) (guard: not p.b) (assignments: p.x := p.x + 2, p.b := true)].
-Controlled behavior: (p.x != 8 or p.b) and (p.x != 10 or p.b) and ((p.x != 6 or p.b) and ((p.x != 9 or p.b) and (not(p.x = 5 or p.x = 7) or p.b))) -> <bdd 9n 28p> [state requirement: (p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and ((p.x = 0 or (p.x = 1 or p.x = 4) or (p.x = 5 or (p.x = 8 or p.x = 9))) and not p.b) or (p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and ((p.x = 2 or (p.x = 3 or p.x = 10)) and not p.b) or ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and ((p.x = 6 or p.x = 7) and not p.b) or (p.y = 1 or p.y = 5) and ((p.x = 0 or (p.x = 1 or p.x = 4) or (p.x = 5 or (p.x = 8 or p.x = 9))) and not p.b)) or ((p.y = 1 or p.y = 5) and ((p.x = 2 or (p.x = 3 or p.x = 10)) and not p.b) or (p.y = 1 or p.y = 5) and ((p.x = 6 or p.x = 7) and not p.b) or (p.y = 3 and ((p.x = 0 or (p.x = 1 or p.x = 4) or (p.x = 5 or (p.x = 8 or p.x = 9))) and not p.b) or (p.y = 3 and ((p.x = 2 or (p.x = 3 or p.x = 10)) and not p.b) or p.y = 3 and ((p.x = 6 or p.x = 7) and not p.b)))), edge: (event: u_e) (guard: not p.b) (assignments: p.x := p.x + 2, p.b := true)].
-Controlled behavior: <bdd 9n 28p> -> <bdd 13n 88p> [state requirement: (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and ((p.x = 0 or (p.x = 1 or p.x = 4) or (p.x = 5 or (p.x = 8 or p.x = 9))) and not p.b) or (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and ((p.x = 2 or (p.x = 3 or p.x = 10)) and not p.b) or ((p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and ((p.x = 6 or p.x = 7) and not p.b) or (p.z = 1 or p.z = 5) and ((p.x = 0 or (p.x = 1 or p.x = 4) or (p.x = 5 or (p.x = 8 or p.x = 9))) and not p.b)) or ((p.z = 1 or p.z = 5) and ((p.x = 2 or (p.x = 3 or p.x = 10)) and not p.b) or (p.z = 1 or p.z = 5) and ((p.x = 6 or p.x = 7) and not p.b) or (p.z = 3 and ((p.x = 0 or (p.x = 1 or p.x = 4) or (p.x = 5 or (p.x = 8 or p.x = 9))) and not p.b) or (p.z = 3 and ((p.x = 2 or (p.x = 3 or p.x = 10)) and not p.b) or p.z = 3 and ((p.x = 6 or p.x = 7) and not p.b)))), edge: (event: u_e) (guard: not p.b) (assignments: p.x := p.x + 2, p.b := true)].
-Edge (event: c_e) (guard: true) (assignments: p.y := p.y + 2): guard: true -> (p.y = 2 or (p.y = 3 or p.y = 6) or (p.y = 7 or p.y = 10 or (0 <= p.x and p.x <= 7 or p.x = 9))) and (p.y = 2 or (p.y = 3 or p.y = 6) or (p.y = 7 or (p.y = 10 or p.x != 9))) and ((p.y = 2 or (p.y = 3 or p.y = 6) or (p.y = 7 or (p.y = 10 or p.x != 7))) and (p.y = 0 or p.y = 1 or (4 <= p.y and p.y <= 9 or (0 <= p.x and p.x <= 7 or p.x = 9)))) and ((p.y = 0 or p.y = 1 or (4 <= p.y and p.y <= 9 or p.x != 9)) and (p.y = 0 or p.y = 1 or (4 <= p.y and p.y <= 9 or p.x != 7)) and ((not(p.y = 6 or p.y = 7) or (0 <= p.x and p.x <= 7 or p.x = 9)) and ((not(p.y = 6 or p.y = 7) or p.x != 9) and (not(p.y = 6 or p.y = 7) or p.x != 7)))) [state requirement: (p.y = 2 or (p.y = 3 or p.y = 6) or (p.y = 7 or p.y = 10 or (0 <= p.x and p.x <= 7 or p.x = 9))) and (p.y = 2 or (p.y = 3 or p.y = 6) or (p.y = 7 or (p.y = 10 or p.x != 9))) and ((p.y = 2 or (p.y = 3 or p.y = 6) or (p.y = 7 or (p.y = 10 or p.x != 7))) and (p.y = 0 or p.y = 1 or (4 <= p.y and p.y <= 9 or (0 <= p.x and p.x <= 7 or p.x = 9)))) and ((p.y = 0 or p.y = 1 or (4 <= p.y and p.y <= 9 or p.x != 9)) and (p.y = 0 or p.y = 1 or (4 <= p.y and p.y <= 9 or p.x != 7)) and ((not(p.y = 6 or p.y = 7) or (0 <= p.x and p.x <= 7 or p.x = 9)) and ((not(p.y = 6 or p.y = 7) or p.x != 9) and (not(p.y = 6 or p.y = 7) or p.x != 7))))].
-Edge (event: c_e) (guard: true -> (p.y = 2 or (p.y = 3 or p.y = 6) or (p.y = 7 or p.y = 10 or (0 <= p.x and p.x <= 7 or p.x = 9))) and (p.y = 2 or (p.y = 3 or p.y = 6) or (p.y = 7 or (p.y = 10 or p.x != 9))) and ((p.y = 2 or (p.y = 3 or p.y = 6) or (p.y = 7 or (p.y = 10 or p.x != 7))) and (p.y = 0 or p.y = 1 or (4 <= p.y and p.y <= 9 or (0 <= p.x and p.x <= 7 or p.x = 9)))) and ((p.y = 0 or p.y = 1 or (4 <= p.y and p.y <= 9 or p.x != 9)) and (p.y = 0 or p.y = 1 or (4 <= p.y and p.y <= 9 or p.x != 7)) and ((not(p.y = 6 or p.y = 7) or (0 <= p.x and p.x <= 7 or p.x = 9)) and ((not(p.y = 6 or p.y = 7) or p.x != 9) and (not(p.y = 6 or p.y = 7) or p.x != 7))))) (assignments: p.y := p.y + 2): guard: (p.y = 2 or (p.y = 3 or p.y = 6) or (p.y = 7 or p.y = 10 or (0 <= p.x and p.x <= 7 or p.x = 9))) and (p.y = 2 or (p.y = 3 or p.y = 6) or (p.y = 7 or (p.y = 10 or p.x != 9))) and ((p.y = 2 or (p.y = 3 or p.y = 6) or (p.y = 7 or (p.y = 10 or p.x != 7))) and (p.y = 0 or p.y = 1 or (4 <= p.y and p.y <= 9 or (0 <= p.x and p.x <= 7 or p.x = 9)))) and ((p.y = 0 or p.y = 1 or (4 <= p.y and p.y <= 9 or p.x != 9)) and (p.y = 0 or p.y = 1 or (4 <= p.y and p.y <= 9 or p.x != 7)) and ((not(p.y = 6 or p.y = 7) or (0 <= p.x and p.x <= 7 or p.x = 9)) and ((not(p.y = 6 or p.y = 7) or p.x != 9) and (not(p.y = 6 or p.y = 7) or p.x != 7)))) -> (p.y = 0 or p.y = 4) and (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) or (p.y = 0 or p.y = 4) and (p.x = 1 or p.x = 5) or ((p.y = 0 or p.y = 4) and p.x = 3 or p.y = 2 and (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6))) or (p.y = 2 and (p.x = 1 or p.x = 5) or p.y = 2 and p.x = 3 or ((p.y = 1 or p.y = 3) and (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) or ((p.y = 1 or p.y = 3) and (p.x = 1 or p.x = 5) or (p.y = 1 or p.y = 3) and p.x = 3))) [state requirement: p.y = 0 or p.y = 4 or (p.y = 2 or (p.y = 1 or p.y = 3))].
+Controlled behavior: true -> not p.b and (p.x = 0 or p.x = 4) or not p.b and p.x = 2 or (not p.b and (p.x = 1 or p.x = 3) or p.b) [state requirement: not p.b and (p.x = 0 or p.x = 4) or (not p.b and p.x = 2 or not p.b and (p.x = 1 or p.x = 3)), edge: (event: u_e) (guard: not p.b) (assignments: p.x := p.x + 2, p.b := true)].
+Controlled behavior: not p.b and (p.x = 0 or p.x = 4) or not p.b and p.x = 2 or (not p.b and (p.x = 1 or p.x = 3) or p.b) -> not p.b and ((p.x = 0 or p.x = 4) and (p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6))) or not p.b and ((p.x = 0 or p.x = 4) and (p.y = 1 or p.y = 5)) or (not p.b and ((p.x = 0 or p.x = 4) and p.y = 3) or (not p.b and (p.x = 2 and (p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6))) or not p.b and (p.x = 2 and (p.y = 1 or p.y = 5)))) or (not p.b and (p.x = 2 and p.y = 3) or not p.b and ((p.x = 1 or p.x = 3) and (p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6))) or (not p.b and ((p.x = 1 or p.x = 3) and (p.y = 1 or p.y = 5)) or (not p.b and ((p.x = 1 or p.x = 3) and p.y = 3) or p.b))) [state requirement: (p.b or p.x = 2 or (p.x = 3 or p.x = 6) or (p.x = 7 or p.x = 10 or (0 <= p.y and p.y <= 7 or p.y = 9))) and (p.b or (p.x = 2 or p.x = 3) or (p.x = 6 or p.x = 7 or (p.x = 10 or p.y != 9))) and ((p.b or (p.x = 2 or p.x = 3) or (p.x = 6 or p.x = 7 or (p.x = 10 or p.y != 7))) and ((p.b or (p.x = 0 or p.x = 1) or (4 <= p.x and p.x <= 9 or (0 <= p.y and p.y <= 7 or p.y = 9))) and (p.b or p.x = 0 or (p.x = 1 or (4 <= p.x and p.x <= 9 or p.y != 9))))) and ((p.b or p.x = 0 or (p.x = 1 or (4 <= p.x and p.x <= 9 or p.y != 7))) and (p.b or not(p.x = 6 or p.x = 7) or (0 <= p.y and p.y <= 7 or p.y = 9)) and ((p.b or (not(p.x = 6 or p.x = 7) or p.y != 9)) and ((p.b or (not(p.x = 6 or p.x = 7) or p.y != 7)) and not p.b))), edge: (event: u_e) (guard: not p.b) (assignments: p.x := p.x + 2, p.b := true)].
+Controlled behavior: not p.b and ((p.x = 0 or p.x = 4) and (p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6))) or not p.b and ((p.x = 0 or p.x = 4) and (p.y = 1 or p.y = 5)) or (not p.b and ((p.x = 0 or p.x = 4) and p.y = 3) or (not p.b and (p.x = 2 and (p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6))) or not p.b and (p.x = 2 and (p.y = 1 or p.y = 5)))) or (not p.b and (p.x = 2 and p.y = 3) or not p.b and ((p.x = 1 or p.x = 3) and (p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6))) or (not p.b and ((p.x = 1 or p.x = 3) and (p.y = 1 or p.y = 5)) or (not p.b and ((p.x = 1 or p.x = 3) and p.y = 3) or p.b))) -> <bdd 13n 28p> [state requirement: (p.b or p.x = 2 or (p.x = 3 or p.x = 6) or (p.x = 7 or p.x = 10 or (0 <= p.z and p.z <= 7 or p.z = 9))) and (p.b or (p.x = 2 or p.x = 3) or (p.x = 6 or p.x = 7 or (p.x = 10 or p.z != 9))) and ((p.b or (p.x = 2 or p.x = 3) or (p.x = 6 or p.x = 7 or (p.x = 10 or p.z != 7))) and ((p.b or (p.x = 0 or p.x = 1) or (4 <= p.x and p.x <= 9 or (0 <= p.z and p.z <= 7 or p.z = 9))) and (p.b or p.x = 0 or (p.x = 1 or (4 <= p.x and p.x <= 9 or p.z != 9))))) and ((p.b or p.x = 0 or (p.x = 1 or (4 <= p.x and p.x <= 9 or p.z != 7))) and (p.b or not(p.x = 6 or p.x = 7) or (0 <= p.z and p.z <= 7 or p.z = 9)) and ((p.b or (not(p.x = 6 or p.x = 7) or p.z != 9)) and ((p.b or (not(p.x = 6 or p.x = 7) or p.z != 7)) and not p.b))), edge: (event: u_e) (guard: not p.b) (assignments: p.x := p.x + 2, p.b := true)].
+Edge (event: c_e) (guard: true) (assignments: p.y := p.y + 2): guard: true -> (0 <= p.x and p.x <= 7 or p.x = 9) and (p.x != 9 and p.x != 7) [state requirement: (0 <= p.x and p.x <= 7 or p.x = 9) and (p.x != 9 and p.x != 7)].
+Edge (event: c_e) (guard: true -> (0 <= p.x and p.x <= 7 or p.x = 9) and (p.x != 9 and p.x != 7)) (assignments: p.y := p.y + 2): guard: (0 <= p.x and p.x <= 7 or p.x = 9) and (p.x != 9 and p.x != 7) -> (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) and (p.y = 0 or p.y = 4) or (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) and p.y = 2 or ((p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) and (p.y = 1 or p.y = 3) or (p.x = 1 or p.x = 5) and (p.y = 0 or p.y = 4)) or ((p.x = 1 or p.x = 5) and p.y = 2 or (p.x = 1 or p.x = 5) and (p.y = 1 or p.y = 3) or (p.x = 3 and (p.y = 0 or p.y = 4) or (p.x = 3 and p.y = 2 or p.x = 3 and (p.y = 1 or p.y = 3)))) [state requirement: p.y = 0 or p.y = 4 or (p.y = 2 or (p.y = 1 or p.y = 3))].
 
 Restricted behavior using state requirements:
-  State: (controlled-behavior: <bdd 13n 88p>)
+  State: (controlled-behavior: <bdd 13n 28p>)
     Edge: (event: u_e) (guard: not p.b) (assignments: p.x := p.x + 2, p.b := true)
-    Edge: (event: c_e) (guard: true -> (p.y = 0 or p.y = 4) and (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) or (p.y = 0 or p.y = 4) and (p.x = 1 or p.x = 5) or ((p.y = 0 or p.y = 4) and p.x = 3 or p.y = 2 and (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6))) or (p.y = 2 and (p.x = 1 or p.x = 5) or p.y = 2 and p.x = 3 or ((p.y = 1 or p.y = 3) and (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) or ((p.y = 1 or p.y = 3) and (p.x = 1 or p.x = 5) or (p.y = 1 or p.y = 3) and p.x = 3)))) (assignments: p.y := p.y + 2)
+    Edge: (event: c_e) (guard: true -> (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) and (p.y = 0 or p.y = 4) or (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) and p.y = 2 or ((p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) and (p.y = 1 or p.y = 3) or (p.x = 1 or p.x = 5) and (p.y = 0 or p.y = 4)) or ((p.x = 1 or p.x = 5) and p.y = 2 or (p.x = 1 or p.x = 5) and (p.y = 1 or p.y = 3) or (p.x = 3 and (p.y = 0 or p.y = 4) or (p.x = 3 and p.y = 2 or p.x = 3 and (p.y = 1 or p.y = 3))))) (assignments: p.y := p.y + 2)
 Controlled initialization: <bdd 13n 125p> -> <bdd 13n 27p> [state requirements: <bdd 12n 27p>].
 
 Extending controlled-behavior predicate using variable ranges.
 
-Controlled behavior: <bdd 13n 88p> -> <bdd 16n 143p> [range: true, variable: discrete variable "p.z" of type "int[0..10]" (group: 0, domain: 0+1, BDD variables: 4, CIF/BDD values: 11/16)].
-Controlled behavior: <bdd 16n 143p> -> <bdd 22n 230p> [range: true, variable: discrete variable "p.y" of type "int[0..10]" (group: 1, domain: 2+3, BDD variables: 4, CIF/BDD values: 11/16)].
-Controlled behavior: <bdd 22n 230p> -> <bdd 30n 425p> [range: true, variable: discrete variable "p.x" of type "int[0..10]" (group: 2, domain: 4+5, BDD variables: 4, CIF/BDD values: 11/16)].
+Controlled behavior: <bdd 13n 28p> -> <bdd 17n 32p> [range: true, variable: discrete variable "p.x" of type "int[0..10]" (group: 1, domain: 2+3, BDD variables: 4, CIF/BDD values: 11/16)].
+Controlled behavior: <bdd 17n 32p> -> <bdd 21n 52p> [range: true, variable: discrete variable "p.y" of type "int[0..10]" (group: 2, domain: 4+5, BDD variables: 4, CIF/BDD values: 11/16)].
+Controlled behavior: <bdd 21n 52p> -> <bdd 24n 152p> [range: true, variable: discrete variable "p.z" of type "int[0..10]" (group: 3, domain: 6+7, BDD variables: 4, CIF/BDD values: 11/16)].
 
-Extended controlled-behavior predicate using variable ranges: <bdd 30n 425p>.
+Extended controlled-behavior predicate using variable ranges: <bdd 24n 152p>.
 
 Restricting behavior using state/event exclusion requirements.
 
@@ -189,22 +177,22 @@ Round 1: started.
 
 Round 1: computing backward controlled-behavior predicate.
 Backward controlled-behavior: true [marker predicate]
-Backward controlled-behavior: true -> <bdd 30n 425p> [restricted to current/previous controlled-behavior predicate: <bdd 30n 425p>]
+Backward controlled-behavior: true -> <bdd 24n 152p> [restricted to current/previous controlled-behavior predicate: <bdd 24n 152p>]
 Backward reachability: iteration 1.
-Backward controlled-behavior: <bdd 30n 425p> [fixed point].
+Backward controlled-behavior: <bdd 24n 152p> [fixed point].
 
 Round 1: computing backward uncontrolled bad-state predicate.
-Backward uncontrolled bad-state: <bdd 30n 548p> [current/previous controlled behavior predicate]
+Backward uncontrolled bad-state: <bdd 24n 146p> [current/previous controlled behavior predicate]
 Backward reachability: iteration 1.
 
 Round 1: computing forward controlled-behavior predicate.
 Forward controlled-behavior: <bdd 13n 27p> [initialization predicate]
-Forward controlled-behavior: <bdd 13n 27p> -> <bdd 13n 27p> [restricted to current/previous controlled-behavior predicate: <bdd 30n 425p>]
+Forward controlled-behavior: <bdd 13n 27p> -> <bdd 13n 27p> [restricted to current/previous controlled-behavior predicate: <bdd 24n 152p>]
 Forward reachability: iteration 1.
-Forward controlled-behavior: <bdd 13n 27p> -> <bdd 20n 63p> [forward reach with edge: (event: u_e) (guard: not p.b) (assignments: p.x := p.x + 2, p.b := true), restricted to current/previous controlled-behavior predicate: <bdd 30n 425p>]
+Forward controlled-behavior: <bdd 13n 27p> -> <bdd 17n 63p> [forward reach with edge: (event: u_e) (guard: not p.b) (assignments: p.x := p.x + 2, p.b := true), restricted to current/previous controlled-behavior predicate: <bdd 24n 152p>]
 Forward reachability: iteration 2.
-Forward controlled-behavior: <bdd 20n 63p> [fixed point].
-Controlled behavior: <bdd 30n 425p> -> <bdd 20n 63p>.
+Forward controlled-behavior: <bdd 17n 63p> [fixed point].
+Controlled behavior: <bdd 24n 152p> -> <bdd 17n 63p>.
 
 Round 1: finished, need another round.
 
@@ -212,32 +200,32 @@ Round 2: started.
 
 Round 2: computing backward controlled-behavior predicate.
 Backward controlled-behavior: true [marker predicate]
-Backward controlled-behavior: true -> <bdd 20n 63p> [restricted to current/previous controlled-behavior predicate: <bdd 20n 63p>]
+Backward controlled-behavior: true -> <bdd 17n 63p> [restricted to current/previous controlled-behavior predicate: <bdd 17n 63p>]
 Backward reachability: iteration 1.
-Backward controlled-behavior: <bdd 20n 63p> [fixed point].
+Backward controlled-behavior: <bdd 17n 63p> [fixed point].
 
 Round 2: computing backward uncontrolled bad-state predicate.
-Backward uncontrolled bad-state: <bdd 20n 124p> [current/previous controlled behavior predicate]
+Backward uncontrolled bad-state: <bdd 17n 124p> [current/previous controlled behavior predicate]
 Backward reachability: iteration 1.
 
 Round 2: finished, controlled behavior is stable.
 
 Computing controlled system guards.
 
-Edge (event: c_e) (guard: true -> (p.y = 0 or p.y = 4) and (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) or (p.y = 0 or p.y = 4) and (p.x = 1 or p.x = 5) or ((p.y = 0 or p.y = 4) and p.x = 3 or p.y = 2 and (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6))) or (p.y = 2 and (p.x = 1 or p.x = 5) or p.y = 2 and p.x = 3 or ((p.y = 1 or p.y = 3) and (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) or ((p.y = 1 or p.y = 3) and (p.x = 1 or p.x = 5) or (p.y = 1 or p.y = 3) and p.x = 3)))) (assignments: p.y := p.y + 2): guard: (p.y = 0 or p.y = 4) and (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) or (p.y = 0 or p.y = 4) and (p.x = 1 or p.x = 5) or ((p.y = 0 or p.y = 4) and p.x = 3 or p.y = 2 and (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6))) or (p.y = 2 and (p.x = 1 or p.x = 5) or p.y = 2 and p.x = 3 or ((p.y = 1 or p.y = 3) and (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) or ((p.y = 1 or p.y = 3) and (p.x = 1 or p.x = 5) or (p.y = 1 or p.y = 3) and p.x = 3))) -> <bdd 20n 63p>.
+Edge (event: c_e) (guard: true -> (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) and (p.y = 0 or p.y = 4) or (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) and p.y = 2 or ((p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) and (p.y = 1 or p.y = 3) or (p.x = 1 or p.x = 5) and (p.y = 0 or p.y = 4)) or ((p.x = 1 or p.x = 5) and p.y = 2 or (p.x = 1 or p.x = 5) and (p.y = 1 or p.y = 3) or (p.x = 3 and (p.y = 0 or p.y = 4) or (p.x = 3 and p.y = 2 or p.x = 3 and (p.y = 1 or p.y = 3))))) (assignments: p.y := p.y + 2): guard: (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) and (p.y = 0 or p.y = 4) or (p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) and p.y = 2 or ((p.x = 0 or p.x = 2 or (p.x = 4 or p.x = 6)) and (p.y = 1 or p.y = 3) or (p.x = 1 or p.x = 5) and (p.y = 0 or p.y = 4)) or ((p.x = 1 or p.x = 5) and p.y = 2 or (p.x = 1 or p.x = 5) and (p.y = 1 or p.y = 3) or (p.x = 3 and (p.y = 0 or p.y = 4) or (p.x = 3 and p.y = 2 or p.x = 3 and (p.y = 1 or p.y = 3)))) -> <bdd 17n 63p>.
 
 Final synthesis result:
-  State: (controlled-behavior: <bdd 20n 63p>)
+  State: (controlled-behavior: <bdd 17n 63p>)
     Edge: (event: u_e) (guard: not p.b) (assignments: p.x := p.x + 2, p.b := true)
-    Edge: (event: c_e) (guard: true -> <bdd 20n 63p>) (assignments: p.y := p.y + 2)
+    Edge: (event: c_e) (guard: true -> <bdd 17n 63p>) (assignments: p.y := p.y + 2)
 
 Controlled system:                     exactly 490 states.
 
-Initial (synthesis result):            <bdd 20n 63p>
+Initial (synthesis result):            <bdd 17n 63p>
 Initial (uncontrolled system):         <bdd 13n 125p>
 Initial (controlled system):           <bdd 13n 27p>
 Initial (removed by supervisor):       <bdd 29n 300p>
-Initial (added by supervisor):         <bdd 29n 623p>
+Initial (added by supervisor):         <bdd 29n 329p>
 
 Simplification of controlled system initialization predicate under the assumption of the uncontrolled system initialization predicates:
   Initial: <bdd 13n 27p> -> <bdd 12n 27p> [assume <bdd 13n 125p>].
diff --git a/cif/org.eclipse.escet.cif.tests/tests/datasynth/state_req_inv_per_edge.ctrlsys.cif b/cif/org.eclipse.escet.cif.tests/tests/datasynth/state_req_inv_per_edge.ctrlsys.cif
index 883598427449a5cc001cc5c26d22cc957bd9cbb3..e50d4a30f7d2d80294153e088c66067f13793425 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/datasynth/state_req_inv_per_edge.ctrlsys.cif
+++ b/cif/org.eclipse.escet.cif.tests/tests/datasynth/state_req_inv_per_edge.ctrlsys.cif
@@ -13,9 +13,9 @@ plant automaton p:
 end
 supervisor automaton sup:
   alphabet c_e;
-  initial (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and (p.x = 0 or p.x = 4)) or ((p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and p.x = 2) or (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and (p.x = 1 or p.x = 3))) or ((p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and ((p.y = 1 or p.y = 5) and (p.x = 0 or p.x = 4)) or ((p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and ((p.y = 1 or p.y = 5) and p.x = 2) or (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and ((p.y = 1 or p.y = 5) and (p.x = 1 or p.x = 3)))) or ((p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and (p.y = 3 and (p.x = 0 or p.x = 4)) or ((p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and (p.y = 3 and p.x = 2) or (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and (p.y = 3 and (p.x = 1 or p.x = 3))) or ((p.z = 1 or p.z = 5) and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and (p.x = 0 or p.x = 4)) or (p.z = 1 or p.z = 5) and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and p.x = 2) or ((p.z = 1 or p.z = 5) and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and (p.x = 1 or p.x = 3)) or (p.z = 1 or p.z = 5) and ((p.y = 1 or p.y = 5) and (p.x = 0 or p.x = 4))))) or ((p.z = 1 or p.z = 5) and ((p.y = 1 or p.y = 5) and p.x = 2) or ((p.z = 1 or p.z = 5) and ((p.y = 1 or p.y = 5) and (p.x = 1 or p.x = 3)) or (p.z = 1 or p.z = 5) and (p.y = 3 and (p.x = 0 or p.x = 4))) or ((p.z = 1 or p.z = 5) and (p.y = 3 and p.x = 2) or (p.z = 1 or p.z = 5) and (p.y = 3 and (p.x = 1 or p.x = 3)) or (p.z = 3 and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and (p.x = 0 or p.x = 4)) or p.z = 3 and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and p.x = 2))) or (p.z = 3 and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and (p.x = 1 or p.x = 3)) or (p.z = 3 and ((p.y = 1 or p.y = 5) and (p.x = 0 or p.x = 4)) or p.z = 3 and ((p.y = 1 or p.y = 5) and p.x = 2)) or (p.z = 3 and ((p.y = 1 or p.y = 5) and (p.x = 1 or p.x = 3)) or p.z = 3 and (p.y = 3 and (p.x = 0 or p.x = 4)) or (p.z = 3 and (p.y = 3 and p.x = 2) or p.z = 3 and (p.y = 3 and (p.x = 1 or p.x = 3))))));
+  initial (p.x = 0 or p.x = 4) and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or ((p.x = 0 or p.x = 4) and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and (p.z = 1 or p.z = 5)) or (p.x = 0 or p.x = 4) and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and p.z = 3)) or ((p.x = 0 or p.x = 4) and ((p.y = 1 or p.y = 5) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or ((p.x = 0 or p.x = 4) and ((p.y = 1 or p.y = 5) and (p.z = 1 or p.z = 5)) or (p.x = 0 or p.x = 4) and ((p.y = 1 or p.y = 5) and p.z = 3))) or ((p.x = 0 or p.x = 4) and (p.y = 3 and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or ((p.x = 0 or p.x = 4) and (p.y = 3 and (p.z = 1 or p.z = 5)) or (p.x = 0 or p.x = 4) and (p.y = 3 and p.z = 3)) or (p.x = 2 and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or p.x = 2 and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and (p.z = 1 or p.z = 5)) or (p.x = 2 and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and p.z = 3) or p.x = 2 and ((p.y = 1 or p.y = 5) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)))))) or (p.x = 2 and ((p.y = 1 or p.y = 5) and (p.z = 1 or p.z = 5)) or (p.x = 2 and ((p.y = 1 or p.y = 5) and p.z = 3) or p.x = 2 and (p.y = 3 and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)))) or (p.x = 2 and (p.y = 3 and (p.z = 1 or p.z = 5)) or p.x = 2 and (p.y = 3 and p.z = 3) or ((p.x = 1 or p.x = 3) and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or (p.x = 1 or p.x = 3) and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and (p.z = 1 or p.z = 5)))) or ((p.x = 1 or p.x = 3) and ((p.y = 0 or p.y = 2 or (p.y = 4 or p.y = 6)) and p.z = 3) or ((p.x = 1 or p.x = 3) and ((p.y = 1 or p.y = 5) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or (p.x = 1 or p.x = 3) and ((p.y = 1 or p.y = 5) and (p.z = 1 or p.z = 5))) or ((p.x = 1 or p.x = 3) and ((p.y = 1 or p.y = 5) and p.z = 3) or (p.x = 1 or p.x = 3) and (p.y = 3 and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or ((p.x = 1 or p.x = 3) and (p.y = 3 and (p.z = 1 or p.z = 5)) or (p.x = 1 or p.x = 3) and (p.y = 3 and p.z = 3)))));
   location:
     initial;
     marked;
-    edge c_e when (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and (p.y = 0 or p.y = 4) and (p.x = 0 and not p.b) or ((p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and ((p.y = 0 or p.y = 4) and p.x = 4) or (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and ((p.y = 0 or p.y = 4) and p.x = 2)) or ((p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and (p.y = 0 or p.y = 4) and (p.x = 6 and p.b) or (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and (p.y = 0 or p.y = 4) and (p.x = 1 and not p.b) or ((p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and (p.y = 0 or p.y = 4) and (p.x = 5 and p.b) or (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and ((p.y = 0 or p.y = 4) and p.x = 3))) or ((p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and p.y = 2 and (p.x = 0 and not p.b) or (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and (p.y = 2 and p.x = 4) or ((p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and (p.y = 2 and p.x = 2) or (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and p.y = 2 and (p.x = 6 and p.b)) or ((p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and p.y = 2 and (p.x = 1 and not p.b) or (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and p.y = 2 and (p.x = 5 and p.b) or ((p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and (p.y = 2 and p.x = 3) or (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and (p.y = 1 or p.y = 3) and (p.x = 0 and not p.b)))) or ((p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and ((p.y = 1 or p.y = 3) and p.x = 4) or (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and ((p.y = 1 or p.y = 3) and p.x = 2) or ((p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and (p.y = 1 or p.y = 3) and (p.x = 6 and p.b) or (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and (p.y = 1 or p.y = 3) and (p.x = 1 and not p.b)) or ((p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and (p.y = 1 or p.y = 3) and (p.x = 5 and p.b) or (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)) and ((p.y = 1 or p.y = 3) and p.x = 3) or ((p.z = 1 or p.z = 5) and (p.y = 0 or p.y = 4) and (p.x = 0 and not p.b) or (p.z = 1 or p.z = 5) and ((p.y = 0 or p.y = 4) and p.x = 4))) or ((p.z = 1 or p.z = 5) and ((p.y = 0 or p.y = 4) and p.x = 2) or (p.z = 1 or p.z = 5) and (p.y = 0 or p.y = 4) and (p.x = 6 and p.b) or ((p.z = 1 or p.z = 5) and (p.y = 0 or p.y = 4) and (p.x = 1 and not p.b) or (p.z = 1 or p.z = 5) and (p.y = 0 or p.y = 4) and (p.x = 5 and p.b)) or ((p.z = 1 or p.z = 5) and ((p.y = 0 or p.y = 4) and p.x = 3) or (p.z = 1 or p.z = 5) and p.y = 2 and (p.x = 0 and not p.b) or ((p.z = 1 or p.z = 5) and (p.y = 2 and p.x = 4) or (p.z = 1 or p.z = 5) and (p.y = 2 and p.x = 2))))) or ((p.z = 1 or p.z = 5) and p.y = 2 and (p.x = 6 and p.b) or (p.z = 1 or p.z = 5) and p.y = 2 and (p.x = 1 and not p.b) or ((p.z = 1 or p.z = 5) and p.y = 2 and (p.x = 5 and p.b) or (p.z = 1 or p.z = 5) and (p.y = 2 and p.x = 3)) or ((p.z = 1 or p.z = 5) and (p.y = 1 or p.y = 3) and (p.x = 0 and not p.b) or (p.z = 1 or p.z = 5) and ((p.y = 1 or p.y = 3) and p.x = 4) or ((p.z = 1 or p.z = 5) and ((p.y = 1 or p.y = 3) and p.x = 2) or (p.z = 1 or p.z = 5) and (p.y = 1 or p.y = 3) and (p.x = 6 and p.b))) or ((p.z = 1 or p.z = 5) and (p.y = 1 or p.y = 3) and (p.x = 1 and not p.b) or (p.z = 1 or p.z = 5) and (p.y = 1 or p.y = 3) and (p.x = 5 and p.b) or ((p.z = 1 or p.z = 5) and ((p.y = 1 or p.y = 3) and p.x = 3) or p.z = 3 and (p.y = 0 or p.y = 4) and (p.x = 0 and not p.b)) or (p.z = 3 and ((p.y = 0 or p.y = 4) and p.x = 4) or p.z = 3 and ((p.y = 0 or p.y = 4) and p.x = 2) or (p.z = 3 and (p.y = 0 or p.y = 4) and (p.x = 6 and p.b) or p.z = 3 and (p.y = 0 or p.y = 4) and (p.x = 1 and not p.b)))) or (p.z = 3 and (p.y = 0 or p.y = 4) and (p.x = 5 and p.b) or p.z = 3 and ((p.y = 0 or p.y = 4) and p.x = 3) or (p.z = 3 and p.y = 2 and (p.x = 0 and not p.b) or p.z = 3 and (p.y = 2 and p.x = 4)) or (p.z = 3 and (p.y = 2 and p.x = 2) or p.z = 3 and p.y = 2 and (p.x = 6 and p.b) or (p.z = 3 and p.y = 2 and (p.x = 1 and not p.b) or p.z = 3 and p.y = 2 and (p.x = 5 and p.b))) or (p.z = 3 and (p.y = 2 and p.x = 3) or p.z = 3 and (p.y = 1 or p.y = 3) and (p.x = 0 and not p.b) or (p.z = 3 and ((p.y = 1 or p.y = 3) and p.x = 4) or p.z = 3 and ((p.y = 1 or p.y = 3) and p.x = 2)) or (p.z = 3 and (p.y = 1 or p.y = 3) and (p.x = 6 and p.b) or p.z = 3 and (p.y = 1 or p.y = 3) and (p.x = 1 and not p.b) or (p.z = 3 and (p.y = 1 or p.y = 3) and (p.x = 5 and p.b) or p.z = 3 and ((p.y = 1 or p.y = 3) and p.x = 3))))));
+    edge c_e when not p.b and (p.x = 0 or p.x = 4) and ((p.y = 0 or p.y = 4) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or (not p.b and (p.x = 0 or p.x = 4) and ((p.y = 0 or p.y = 4) and (p.z = 1 or p.z = 5)) or not p.b and (p.x = 0 or p.x = 4) and ((p.y = 0 or p.y = 4) and p.z = 3)) or (not p.b and (p.x = 0 or p.x = 4) and (p.y = 2 and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or not p.b and (p.x = 0 or p.x = 4) and (p.y = 2 and (p.z = 1 or p.z = 5)) or (not p.b and (p.x = 0 or p.x = 4) and (p.y = 2 and p.z = 3) or not p.b and (p.x = 0 or p.x = 4) and ((p.y = 1 or p.y = 3) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))))) or (not p.b and (p.x = 0 or p.x = 4) and ((p.y = 1 or p.y = 3) and (p.z = 1 or p.z = 5)) or not p.b and (p.x = 0 or p.x = 4) and ((p.y = 1 or p.y = 3) and p.z = 3) or (not p.b and p.x = 2 and ((p.y = 0 or p.y = 4) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or not p.b and p.x = 2 and ((p.y = 0 or p.y = 4) and (p.z = 1 or p.z = 5))) or (not p.b and p.x = 2 and ((p.y = 0 or p.y = 4) and p.z = 3) or not p.b and p.x = 2 and (p.y = 2 and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or (not p.b and p.x = 2 and (p.y = 2 and (p.z = 1 or p.z = 5)) or not p.b and p.x = 2 and (p.y = 2 and p.z = 3)))) or (not p.b and p.x = 2 and ((p.y = 1 or p.y = 3) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or not p.b and p.x = 2 and ((p.y = 1 or p.y = 3) and (p.z = 1 or p.z = 5)) or (not p.b and p.x = 2 and ((p.y = 1 or p.y = 3) and p.z = 3) or not p.b and (p.x = 1 or p.x = 3) and ((p.y = 0 or p.y = 4) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)))) or (not p.b and (p.x = 1 or p.x = 3) and ((p.y = 0 or p.y = 4) and (p.z = 1 or p.z = 5)) or not p.b and (p.x = 1 or p.x = 3) and ((p.y = 0 or p.y = 4) and p.z = 3) or (not p.b and (p.x = 1 or p.x = 3) and (p.y = 2 and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or not p.b and (p.x = 1 or p.x = 3) and (p.y = 2 and (p.z = 1 or p.z = 5)))) or (not p.b and (p.x = 1 or p.x = 3) and (p.y = 2 and p.z = 3) or not p.b and (p.x = 1 or p.x = 3) and ((p.y = 1 or p.y = 3) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or (not p.b and (p.x = 1 or p.x = 3) and ((p.y = 1 or p.y = 3) and (p.z = 1 or p.z = 5)) or not p.b and (p.x = 1 or p.x = 3) and ((p.y = 1 or p.y = 3) and p.z = 3)) or (p.b and p.x = 4 and ((p.y = 0 or p.y = 4) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or p.b and p.x = 4 and ((p.y = 0 or p.y = 4) and (p.z = 1 or p.z = 5)) or (p.b and p.x = 4 and ((p.y = 0 or p.y = 4) and p.z = 3) or p.b and p.x = 4 and (p.y = 2 and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))))))) or (p.b and p.x = 4 and (p.y = 2 and (p.z = 1 or p.z = 5)) or p.b and p.x = 4 and (p.y = 2 and p.z = 3) or (p.b and p.x = 4 and ((p.y = 1 or p.y = 3) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or p.b and p.x = 4 and ((p.y = 1 or p.y = 3) and (p.z = 1 or p.z = 5))) or (p.b and p.x = 4 and ((p.y = 1 or p.y = 3) and p.z = 3) or p.b and (p.x = 2 or p.x = 6) and ((p.y = 0 or p.y = 4) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or (p.b and (p.x = 2 or p.x = 6) and ((p.y = 0 or p.y = 4) and (p.z = 1 or p.z = 5)) or p.b and (p.x = 2 or p.x = 6) and ((p.y = 0 or p.y = 4) and p.z = 3))) or (p.b and (p.x = 2 or p.x = 6) and (p.y = 2 and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or p.b and (p.x = 2 or p.x = 6) and (p.y = 2 and (p.z = 1 or p.z = 5)) or (p.b and (p.x = 2 or p.x = 6) and (p.y = 2 and p.z = 3) or p.b and (p.x = 2 or p.x = 6) and ((p.y = 1 or p.y = 3) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6)))) or (p.b and (p.x = 2 or p.x = 6) and ((p.y = 1 or p.y = 3) and (p.z = 1 or p.z = 5)) or p.b and (p.x = 2 or p.x = 6) and ((p.y = 1 or p.y = 3) and p.z = 3) or (p.b and p.x = 5 and ((p.y = 0 or p.y = 4) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or p.b and p.x = 5 and ((p.y = 0 or p.y = 4) and (p.z = 1 or p.z = 5))))) or (p.b and p.x = 5 and ((p.y = 0 or p.y = 4) and p.z = 3) or p.b and p.x = 5 and (p.y = 2 and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or (p.b and p.x = 5 and (p.y = 2 and (p.z = 1 or p.z = 5)) or p.b and p.x = 5 and (p.y = 2 and p.z = 3)) or (p.b and p.x = 5 and ((p.y = 1 or p.y = 3) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or p.b and p.x = 5 and ((p.y = 1 or p.y = 3) and (p.z = 1 or p.z = 5)) or (p.b and p.x = 5 and ((p.y = 1 or p.y = 3) and p.z = 3) or p.b and p.x = 3 and ((p.y = 0 or p.y = 4) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))))) or (p.b and p.x = 3 and ((p.y = 0 or p.y = 4) and (p.z = 1 or p.z = 5)) or p.b and p.x = 3 and ((p.y = 0 or p.y = 4) and p.z = 3) or (p.b and p.x = 3 and (p.y = 2 and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or p.b and p.x = 3 and (p.y = 2 and (p.z = 1 or p.z = 5))) or (p.b and p.x = 3 and (p.y = 2 and p.z = 3) or p.b and p.x = 3 and ((p.y = 1 or p.y = 3) and (p.z = 0 or p.z = 2 or (p.z = 4 or p.z = 6))) or (p.b and p.x = 3 and ((p.y = 1 or p.y = 3) and (p.z = 1 or p.z = 5)) or p.b and p.x = 3 and ((p.y = 1 or p.y = 3) and p.z = 3))))));
 end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/event_based/supervisor_synthesis/no_requirement.err b/cif/org.eclipse.escet.cif.tests/tests/event_based/supervisor_synthesis/no_requirement.err
index 1fa7fa4cdfa3e016f03552c14c5d9d864755d2ef..3ea4e98e1d32078b0a371fbbbd0b0bebd4d5914d 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/event_based/supervisor_synthesis/no_requirement.err
+++ b/cif/org.eclipse.escet.cif.tests/tests/event_based/supervisor_synthesis/no_requirement.err
@@ -1,2 +1,3 @@
 WARNING: Automaton "p" is not trim.
+WARNING: The specification has no requirement automata.
 WARNING: Controllable event "e" is only used by automaton "p".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/event_based/supervisor_synthesis/no_requirement.out b/cif/org.eclipse.escet.cif.tests/tests/event_based/supervisor_synthesis/no_requirement.out
index f1ac50400bb382587133aa7cfeb37e799f7d31da..9e839407c48764f83ed1f3b80fa3498bcfb8d3c4 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/event_based/supervisor_synthesis/no_requirement.out
+++ b/cif/org.eclipse.escet.cif.tests/tests/event_based/supervisor_synthesis/no_requirement.out
@@ -1 +1 @@
-Reported 2 synthesis warnings.
+Reported 3 synthesis warnings.
diff --git a/cif/org.eclipse.escet.cif.tests/tests/explorer/requirements.cif b/cif/org.eclipse.escet.cif.tests/tests/explorer/requirements.cif
new file mode 100644
index 0000000000000000000000000000000000000000..586f46b1c66745937fe767bda89056a31422c35e
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/explorer/requirements.cif
@@ -0,0 +1,33 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+requirement r1.x + r2.x >= 0;
+
+requirement r1:
+  disc int x;
+  requirement x >= 0;
+
+  location:
+    initial;
+    requirement x >= 0;
+end
+
+requirement r2:
+  disc int x;
+  requirement x >= 0;
+
+  location loc:
+    initial;
+    requirement x >= 0;
+    requirement x <= 1 div x;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/explorer/requirements.err b/cif/org.eclipse.escet.cif.tests/tests/explorer/requirements.err
new file mode 100644
index 0000000000000000000000000000000000000000..7536528e564ae10d5c8a9ad9eb6d42703d482ea2
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/explorer/requirements.err
@@ -0,0 +1,32 @@
+WARNING: The CIF specification has features that may cause an unexpected resulting state space:
+
+  ------------------------------------------------------------------
+  (1/2) Automaton is a requirement, but will be explored as a plant.
+  ------------------------------------------------------------------
+   * In the top-level scope of the specification:
+     - requirement automaton r1:
+                             ^
+     - requirement automaton r2:
+                             ^
+
+  ------------------------------------------------------------------
+  (2/2) Invariant is a requirement, but will be explored as a plant.
+  ------------------------------------------------------------------
+   * In the top-level scope of the specification:
+     - requirement invariant r1.x + r2.x >= 0;
+                                         ^
+   * In automaton "r1":
+     - requirement invariant x >= 0;
+                               ^
+     - requirement invariant x >= 0;
+                               ^
+   * In automaton "r2":
+     - requirement invariant x >= 0;
+                               ^
+   * In location "r2.loc":
+     - requirement invariant x >= 0;
+                               ^
+     - requirement invariant x <= 1 div x;
+                               ^
+ERROR: Failed to compute invariant "r2.x <= 1 div r2.x" in initial state.
+CAUSE: Division by zero: 1 div 0.
diff --git a/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp.plcopen.xml b/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp.plcopen.xml
index 0734fa86a543c80696a9588e13938429623257ac..a7a13235a385dfc437e1a8baffe6157c842008ed 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp.plcopen.xml
+++ b/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp.plcopen.xml
@@ -20,7 +20,12 @@
         <interface/>
         <body>
           <ST>
-            <xhtml xmlns="http://www.w3.org/1999/xhtml"/>
+            <xhtml xmlns="http://www.w3.org/1999/xhtml">IF firstRun THEN
+    firstRun := FALSE;
+
+    (* Initialize the state variables. *)
+    hw_lamp_bit := FALSE;
+END_IF;</xhtml>
           </ST>
         </body>
       </pou>
@@ -50,6 +55,14 @@
             </variable>
           </globalVars>
           <globalVars constant="false" name="TIMERS">
+            <variable name="firstRun">
+              <type>
+                <BOOL/>
+              </type>
+              <initialValue>
+                <simpleValue value="TRUE"/>
+              </initialValue>
+            </variable>
             <variable name="timer0">
               <type>
                 <derived name="TON"/>
diff --git a/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_abb/MAIN.plcprog b/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_abb/MAIN.plcprog
index 8d8048359c217c55b320c5a023e4ee361d08b84f..1843dfb652525bd946d9b5407e1165749f011cf9 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_abb/MAIN.plcprog
+++ b/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_abb/MAIN.plcprog
@@ -1,3 +1,9 @@
 PROGRAM MAIN
 
+IF firstRun THEN
+    firstRun := FALSE;
+
+    (* Initialize the state variables. *)
+    hw_lamp_bit := FALSE;
+END_IF;
 END_PROGRAM
diff --git a/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_abb/MyConfig.plccfg b/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_abb/MyConfig.plccfg
index 387289442cdbeeee7ff59ed7d700bf1ff66cc7ed..9a26a960519f342c4e77fc3118e9a3c09d50c0fa 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_abb/MyConfig.plccfg
+++ b/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_abb/MyConfig.plccfg
@@ -4,6 +4,7 @@ CONFIGURATION MyConfig
         hw_lamp_bit: BOOL;
     END_VAR
     VAR_GLOBAL // TIMERS
+        firstRun: BOOL := TRUE;
         timer0: TON;
         timer1: TON;
         curTimer: INT := 0;
diff --git a/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_iec/MAIN.plcprog b/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_iec/MAIN.plcprog
index 8d8048359c217c55b320c5a023e4ee361d08b84f..1843dfb652525bd946d9b5407e1165749f011cf9 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_iec/MAIN.plcprog
+++ b/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_iec/MAIN.plcprog
@@ -1,3 +1,9 @@
 PROGRAM MAIN
 
+IF firstRun THEN
+    firstRun := FALSE;
+
+    (* Initialize the state variables. *)
+    hw_lamp_bit := FALSE;
+END_IF;
 END_PROGRAM
diff --git a/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_iec/MyConfig.plccfg b/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_iec/MyConfig.plccfg
index 387289442cdbeeee7ff59ed7d700bf1ff66cc7ed..9a26a960519f342c4e77fc3118e9a3c09d50c0fa 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_iec/MyConfig.plccfg
+++ b/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_iec/MyConfig.plccfg
@@ -4,6 +4,7 @@ CONFIGURATION MyConfig
         hw_lamp_bit: BOOL;
     END_VAR
     VAR_GLOBAL // TIMERS
+        firstRun: BOOL := TRUE;
         timer0: TON;
         timer1: TON;
         curTimer: INT := 0;
diff --git a/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_s7-1200/MAIN.scl b/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_s7-1200/MAIN.scl
index 1d6a041016b3dfd7c28862f3f39191cb50402301..2c9b6fe2a77acde9555a58474670003ecb650254 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_s7-1200/MAIN.scl
+++ b/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_s7-1200/MAIN.scl
@@ -2,4 +2,10 @@ ORGANIZATION_BLOCK MAIN
 { S7_Optimized_Access := 'true' }
 
 BEGIN
+    IF firstRun THEN
+        firstRun := FALSE;
+
+        (* Initialize the state variables. *)
+        hw_lamp_bit := FALSE;
+    END_IF;
 END_ORGANIZATION_BLOCK
diff --git a/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_s7-1500/MAIN.scl b/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_s7-1500/MAIN.scl
index 1d6a041016b3dfd7c28862f3f39191cb50402301..2c9b6fe2a77acde9555a58474670003ecb650254 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_s7-1500/MAIN.scl
+++ b/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_s7-1500/MAIN.scl
@@ -2,4 +2,10 @@ ORGANIZATION_BLOCK MAIN
 { S7_Optimized_Access := 'true' }
 
 BEGIN
+    IF firstRun THEN
+        firstRun := FALSE;
+
+        (* Initialize the state variables. *)
+        hw_lamp_bit := FALSE;
+    END_IF;
 END_ORGANIZATION_BLOCK
diff --git a/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_s7-300/MAIN.scl b/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_s7-300/MAIN.scl
index ea7d18df2c6a7bccc71858bf8bad3a77fbb64c14..ee25fb8fe892e4d5816ebfff9713a6bbf899e3ec 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_s7-300/MAIN.scl
+++ b/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_s7-300/MAIN.scl
@@ -2,4 +2,10 @@ ORGANIZATION_BLOCK MAIN
 { S7_Optimized_Access := 'false' }
 
 BEGIN
+    IF firstRun THEN
+        firstRun := FALSE;
+
+        (* Initialize the state variables. *)
+        hw_lamp_bit := FALSE;
+    END_IF;
 END_ORGANIZATION_BLOCK
diff --git a/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_s7-400/MAIN.scl b/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_s7-400/MAIN.scl
index ea7d18df2c6a7bccc71858bf8bad3a77fbb64c14..ee25fb8fe892e4d5816ebfff9713a6bbf899e3ec 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_s7-400/MAIN.scl
+++ b/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_s7-400/MAIN.scl
@@ -2,4 +2,10 @@ ORGANIZATION_BLOCK MAIN
 { S7_Optimized_Access := 'false' }
 
 BEGIN
+    IF firstRun THEN
+        firstRun := FALSE;
+
+        (* Initialize the state variables. *)
+        hw_lamp_bit := FALSE;
+    END_IF;
 END_ORGANIZATION_BLOCK
diff --git a/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_twincat/button_lamp_twincat_real/MyProj/GVLs/TIMERS.TcGVL b/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_twincat/button_lamp_twincat_real/MyProj/GVLs/TIMERS.TcGVL
index 2c87e010f5c80eab8821ff5dc2c78edbb8c6edbe..e530a1402c3fc1085787bd0f986f976e829663d1 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_twincat/button_lamp_twincat_real/MyProj/GVLs/TIMERS.TcGVL
+++ b/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_twincat/button_lamp_twincat_real/MyProj/GVLs/TIMERS.TcGVL
@@ -2,6 +2,7 @@
 <TcPlcObject ProductVersion="3.1.0.18" Version="1.1.0.1">
   <GVL Name="TIMERS">
     <Declaration><![CDATA[VAR_GLOBAL // TIMERS
+    firstRun: BOOL := TRUE;
     timer0: TON;
     timer1: TON;
     curTimer: INT := 0;
diff --git a/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_twincat/button_lamp_twincat_real/MyProj/POUs/MAIN.TcPOU b/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_twincat/button_lamp_twincat_real/MyProj/POUs/MAIN.TcPOU
index d3ea4fb19721addadcc9df1a4d621f2fa4876da1..7b01327180b764c29621738c732df47c802f5f25 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_twincat/button_lamp_twincat_real/MyProj/POUs/MAIN.TcPOU
+++ b/cif/org.eclipse.escet.cif.tests/tests/plcgen/button_lamp_twincat/button_lamp_twincat_real/MyProj/POUs/MAIN.TcPOU
@@ -3,7 +3,12 @@
   <POU Name="MAIN">
     <Declaration><![CDATA[PROGRAM MAIN]]></Declaration>
     <Implementation>
-      <ST/>
+      <ST><![CDATA[IF firstRun THEN
+    firstRun := FALSE;
+
+    (* Initialize the state variables. *)
+    hw_lamp_bit := FALSE;
+END_IF;]]></ST>
     </Implementation>
     <ObjectProperties/>
   </POU>
diff --git a/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1.plcopen.xml b/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1.plcopen.xml
index 358d243ab526cfb4daef4ccb391321dc2ed28f52..7114c9092962b718a5ec33d0de97f579812aa108 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1.plcopen.xml
+++ b/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1.plcopen.xml
@@ -79,7 +79,29 @@
         <interface/>
         <body>
           <ST>
-            <xhtml xmlns="http://www.w3.org/1999/xhtml"/>
+            <xhtml xmlns="http://www.w3.org/1999/xhtml">IF firstRun THEN
+    firstRun := FALSE;
+
+    (* Initialize the state variables. *)
+    p_b := TRUE;
+    p_x := 0;
+    p_y := 1.23;
+    p_ve := g_LIT1;
+    p_v1 := 0;
+    litStruct.field1 := 0.0;
+    litStruct.field2 := 0.0;
+    p_v2 := litStruct;
+    litStruct.field1 := 0.0;
+    litStruct.field2 := 0.0;
+    litStruct__1.field1 := litStruct;
+    litStruct__1.field2 := 0.0;
+    p_v3 := litStruct__1;
+    litStruct__2.field1 := 0;
+    litStruct__2.field2 := 0;
+    p_tv := litStruct__2;
+    p_j := 0;
+    p_r := 1000000.0;
+END_IF;</xhtml>
           </ST>
         </body>
       </pou>
@@ -154,6 +176,14 @@
             </variable>
           </globalVars>
           <globalVars constant="false" name="TIMERS">
+            <variable name="firstRun">
+              <type>
+                <BOOL/>
+              </type>
+              <initialValue>
+                <simpleValue value="TRUE"/>
+              </initialValue>
+            </variable>
             <variable name="timer0">
               <type>
                 <derived name="TON"/>
diff --git a/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_abb/MAIN.plcprog b/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_abb/MAIN.plcprog
index 8d8048359c217c55b320c5a023e4ee361d08b84f..d789f6d1433ab77ee313678fe64c093ff8a2d50a 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_abb/MAIN.plcprog
+++ b/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_abb/MAIN.plcprog
@@ -1,3 +1,26 @@
 PROGRAM MAIN
 
+IF firstRun THEN
+    firstRun := FALSE;
+
+    (* Initialize the state variables. *)
+    p_b := TRUE;
+    p_x := 0;
+    p_y := 1.23;
+    p_ve := someConstantvariable;
+    p_v1 := 0;
+    litStruct.field1 := 0.0;
+    litStruct.field2 := 0.0;
+    p_v2 := litStruct;
+    litStruct.field1 := 0.0;
+    litStruct.field2 := 0.0;
+    litStruct__1.field1 := litStruct;
+    litStruct__1.field2 := 0.0;
+    p_v3 := litStruct__1;
+    litStruct__2.field1 := 0;
+    litStruct__2.field2 := 0;
+    p_tv := litStruct__2;
+    p_j := 0;
+    p_r := 1000000.0;
+END_IF;
 END_PROGRAM
diff --git a/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_abb/Untitled1.plccfg b/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_abb/Untitled1.plccfg
index 84c1e0aab45da9dcaa8fbb28cf0101f6f5c98fda..91596a4f4567057083ff70273bf4d020ddfe9918 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_abb/Untitled1.plccfg
+++ b/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_abb/Untitled1.plccfg
@@ -13,6 +13,7 @@ CONFIGURATION Untitled1
         p_r: REAL;
     END_VAR
     VAR_GLOBAL // TIMERS
+        firstRun: BOOL := TRUE;
         timer0: TON;
         timer1: TON;
         curTimer: INT := 0;
diff --git a/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_iec/MAIN.plcprog b/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_iec/MAIN.plcprog
index 8d8048359c217c55b320c5a023e4ee361d08b84f..1e4b24d20bf133a38967147fe753236666d488b1 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_iec/MAIN.plcprog
+++ b/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_iec/MAIN.plcprog
@@ -1,3 +1,26 @@
 PROGRAM MAIN
 
+IF firstRun THEN
+    firstRun := FALSE;
+
+    (* Initialize the state variables. *)
+    p_b := TRUE;
+    p_x := 0;
+    p_y := 1.23;
+    p_ve := g_LIT1;
+    p_v1 := 0;
+    litStruct.field1 := 0.0;
+    litStruct.field2 := 0.0;
+    p_v2 := litStruct;
+    litStruct.field1 := 0.0;
+    litStruct.field2 := 0.0;
+    litStruct__1.field1 := litStruct;
+    litStruct__1.field2 := 0.0;
+    p_v3 := litStruct__1;
+    litStruct__2.field1 := 0;
+    litStruct__2.field2 := 0;
+    p_tv := litStruct__2;
+    p_j := 0;
+    p_r := 1000000.0;
+END_IF;
 END_PROGRAM
diff --git a/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_iec/Untitled1.plccfg b/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_iec/Untitled1.plccfg
index f02722b7cc8c8b5dcaaac73dba5b5abee99a2e04..597b61c45fc6948a1a96b2671439e95bded84be9 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_iec/Untitled1.plccfg
+++ b/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_iec/Untitled1.plccfg
@@ -13,6 +13,7 @@ CONFIGURATION Untitled1
         p_r: LREAL;
     END_VAR
     VAR_GLOBAL // TIMERS
+        firstRun: BOOL := TRUE;
         timer0: TON;
         timer1: TON;
         curTimer: INT := 0;
diff --git a/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_s7-1200/MAIN.scl b/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_s7-1200/MAIN.scl
index 1d6a041016b3dfd7c28862f3f39191cb50402301..02d9d0e31c1dd9f4fbe25e714be09e71f9efd825 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_s7-1200/MAIN.scl
+++ b/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_s7-1200/MAIN.scl
@@ -2,4 +2,27 @@ ORGANIZATION_BLOCK MAIN
 { S7_Optimized_Access := 'true' }
 
 BEGIN
+    IF firstRun THEN
+        firstRun := FALSE;
+
+        (* Initialize the state variables. *)
+        p_b := TRUE;
+        p_x := 0;
+        p_y := 1.23;
+        p_ve := someConstantvariable;
+        p_v1 := 0;
+        litStruct.field1 := 0.0;
+        litStruct.field2 := 0.0;
+        p_v2 := litStruct;
+        litStruct.field1 := 0.0;
+        litStruct.field2 := 0.0;
+        litStruct__1.field1 := litStruct;
+        litStruct__1.field2 := 0.0;
+        p_v3 := litStruct__1;
+        litStruct__2.field1 := 0;
+        litStruct__2.field2 := 0;
+        p_tv := litStruct__2;
+        p_j := 0;
+        p_r := 1000000.0;
+    END_IF;
 END_ORGANIZATION_BLOCK
diff --git a/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_s7-1500/MAIN.scl b/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_s7-1500/MAIN.scl
index 1d6a041016b3dfd7c28862f3f39191cb50402301..02d9d0e31c1dd9f4fbe25e714be09e71f9efd825 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_s7-1500/MAIN.scl
+++ b/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_s7-1500/MAIN.scl
@@ -2,4 +2,27 @@ ORGANIZATION_BLOCK MAIN
 { S7_Optimized_Access := 'true' }
 
 BEGIN
+    IF firstRun THEN
+        firstRun := FALSE;
+
+        (* Initialize the state variables. *)
+        p_b := TRUE;
+        p_x := 0;
+        p_y := 1.23;
+        p_ve := someConstantvariable;
+        p_v1 := 0;
+        litStruct.field1 := 0.0;
+        litStruct.field2 := 0.0;
+        p_v2 := litStruct;
+        litStruct.field1 := 0.0;
+        litStruct.field2 := 0.0;
+        litStruct__1.field1 := litStruct;
+        litStruct__1.field2 := 0.0;
+        p_v3 := litStruct__1;
+        litStruct__2.field1 := 0;
+        litStruct__2.field2 := 0;
+        p_tv := litStruct__2;
+        p_j := 0;
+        p_r := 1000000.0;
+    END_IF;
 END_ORGANIZATION_BLOCK
diff --git a/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_s7-300/MAIN.scl b/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_s7-300/MAIN.scl
index ea7d18df2c6a7bccc71858bf8bad3a77fbb64c14..7d424df443b68260b422a81a2f92fd774851038f 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_s7-300/MAIN.scl
+++ b/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_s7-300/MAIN.scl
@@ -2,4 +2,27 @@ ORGANIZATION_BLOCK MAIN
 { S7_Optimized_Access := 'false' }
 
 BEGIN
+    IF firstRun THEN
+        firstRun := FALSE;
+
+        (* Initialize the state variables. *)
+        p_b := TRUE;
+        p_x := 0;
+        p_y := 1.23;
+        p_ve := someConstantvariable;
+        p_v1 := 0;
+        litStruct.field1 := 0.0;
+        litStruct.field2 := 0.0;
+        p_v2 := litStruct;
+        litStruct.field1 := 0.0;
+        litStruct.field2 := 0.0;
+        litStruct__1.field1 := litStruct;
+        litStruct__1.field2 := 0.0;
+        p_v3 := litStruct__1;
+        litStruct__2.field1 := 0;
+        litStruct__2.field2 := 0;
+        p_tv := litStruct__2;
+        p_j := 0;
+        p_r := 1000000.0;
+    END_IF;
 END_ORGANIZATION_BLOCK
diff --git a/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_s7-400/MAIN.scl b/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_s7-400/MAIN.scl
index ea7d18df2c6a7bccc71858bf8bad3a77fbb64c14..7d424df443b68260b422a81a2f92fd774851038f 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_s7-400/MAIN.scl
+++ b/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_s7-400/MAIN.scl
@@ -2,4 +2,27 @@ ORGANIZATION_BLOCK MAIN
 { S7_Optimized_Access := 'false' }
 
 BEGIN
+    IF firstRun THEN
+        firstRun := FALSE;
+
+        (* Initialize the state variables. *)
+        p_b := TRUE;
+        p_x := 0;
+        p_y := 1.23;
+        p_ve := someConstantvariable;
+        p_v1 := 0;
+        litStruct.field1 := 0.0;
+        litStruct.field2 := 0.0;
+        p_v2 := litStruct;
+        litStruct.field1 := 0.0;
+        litStruct.field2 := 0.0;
+        litStruct__1.field1 := litStruct;
+        litStruct__1.field2 := 0.0;
+        p_v3 := litStruct__1;
+        litStruct__2.field1 := 0;
+        litStruct__2.field2 := 0;
+        p_tv := litStruct__2;
+        p_j := 0;
+        p_r := 1000000.0;
+    END_IF;
 END_ORGANIZATION_BLOCK
diff --git a/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_twincat/simple_all1_twincat_real/Untitled1/GVLs/TIMERS.TcGVL b/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_twincat/simple_all1_twincat_real/Untitled1/GVLs/TIMERS.TcGVL
index 2c87e010f5c80eab8821ff5dc2c78edbb8c6edbe..e530a1402c3fc1085787bd0f986f976e829663d1 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_twincat/simple_all1_twincat_real/Untitled1/GVLs/TIMERS.TcGVL
+++ b/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_twincat/simple_all1_twincat_real/Untitled1/GVLs/TIMERS.TcGVL
@@ -2,6 +2,7 @@
 <TcPlcObject ProductVersion="3.1.0.18" Version="1.1.0.1">
   <GVL Name="TIMERS">
     <Declaration><![CDATA[VAR_GLOBAL // TIMERS
+    firstRun: BOOL := TRUE;
     timer0: TON;
     timer1: TON;
     curTimer: INT := 0;
diff --git a/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_twincat/simple_all1_twincat_real/Untitled1/POUs/MAIN.TcPOU b/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_twincat/simple_all1_twincat_real/Untitled1/POUs/MAIN.TcPOU
index d3ea4fb19721addadcc9df1a4d621f2fa4876da1..dc2d4e1a8f8869fb9faf8d2eb87fa68fdde5bc84 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_twincat/simple_all1_twincat_real/Untitled1/POUs/MAIN.TcPOU
+++ b/cif/org.eclipse.escet.cif.tests/tests/plcgen/simple_all1_twincat/simple_all1_twincat_real/Untitled1/POUs/MAIN.TcPOU
@@ -3,7 +3,29 @@
   <POU Name="MAIN">
     <Declaration><![CDATA[PROGRAM MAIN]]></Declaration>
     <Implementation>
-      <ST/>
+      <ST><![CDATA[IF firstRun THEN
+    firstRun := FALSE;
+
+    (* Initialize the state variables. *)
+    p_b := TRUE;
+    p_x := 0;
+    p_y := 1.23;
+    p_ve := g_LIT1;
+    p_v1 := 0;
+    litStruct.field1 := 0.0;
+    litStruct.field2 := 0.0;
+    p_v2 := litStruct;
+    litStruct.field1 := 0.0;
+    litStruct.field2 := 0.0;
+    litStruct__1.field1 := litStruct;
+    litStruct__1.field2 := 0.0;
+    p_v3 := litStruct__1;
+    litStruct__2.field1 := 0;
+    litStruct__2.field2 := 0;
+    p_tv := litStruct__2;
+    p_j := 0;
+    p_r := 1000000.0;
+END_IF;]]></ST>
     </Implementation>
     <ObjectProperties/>
   </POU>
diff --git a/cif/org.eclipse.escet.cif.tests/tests/tchecker/def_use_cycle_post.cif b/cif/org.eclipse.escet.cif.tests/tests/tchecker/def_use_cycle_post.cif
index 81e9ffad9b5fa6b5b8102df7fd4c1b1690422c55..18f86c29d227c380d976b871529e4920ce982043 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/tchecker/def_use_cycle_post.cif
+++ b/cif/org.eclipse.escet.cif.tests/tests/tchecker/def_use_cycle_post.cif
@@ -117,7 +117,7 @@ group all:
     disc real x27 = {0.0: x28}[0.0];       // Dictionary value expression.
     disc real x28 = x29 + inp;             // Input variable expression.
     disc real x29 = x30 + size(<string>self); // Self reference.
-    disc real x30 = x31 + switch 5: case 5:  1.0 else 2.0 end; // Switch expr.
+    disc real x30 = x31 + switch 5: case 5:  1.0          end; // Switch expr.
     disc real x31 = x32 + switch z: case l1: 1.0 else 2.0 end; // Switch expr.
 
     disc real x32 = x1;          // Closing the cycle.
diff --git a/cif/org.eclipse.escet.cif.tests/tests/tchecker/dupl_invariants.cif b/cif/org.eclipse.escet.cif.tests/tests/tchecker/dupl_invariants.cif
index d00f650e520d76a3d5a63773452b487ebe42bae6..28eb5be03a10101de385bf72fefe4f65fa1b4782 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/tchecker/dupl_invariants.cif
+++ b/cif/org.eclipse.escet.cif.tests/tests/tchecker/dupl_invariants.cif
@@ -153,16 +153,17 @@ invariant e24 needs if true,  true:  true  elif false, false: true  else true  e
 invariant e24 needs if true,  true:  true  elif false, false: false else false end; // Different else.
 
 // Switch expression.
+input int i25, k25;
 event e25;
-invariant e25 needs switch true:  case true:  true  case false: false else true  end; // Original.
-invariant e25 needs switch true:  case true:  true  case false: false else true  end; // Original.
-invariant e25 needs switch false: case true:  true  case false: false else true  end; // Different switch.
-invariant e25 needs switch true:  case false: true  case false: false else true  end; // Different key 1.
-invariant e25 needs switch true:  case true:  false case false: false else true  end; // Different value 1.
-invariant e25 needs switch true:  case true:  true  case true:  false else true  end; // Different key 2.
-invariant e25 needs switch true:  case true:  true  case false: true  else true  end; // Different value 2.
-invariant e25 needs switch true:  case true:  true  case false: true  else false end; // Different else.
-invariant e25 needs switch true:  case true:  true                    else true  end; // Different number of cases.
+invariant e25 needs switch i25: case 1: true  case 2: false else true  end; // Original.
+invariant e25 needs switch i25: case 1: true  case 2: false else true  end; // Original.
+invariant e25 needs switch k25: case 1: true  case 2: false else true  end; // Different switch.
+invariant e25 needs switch i25: case 2: true  case 2: false else true  end; // Different key 1.
+invariant e25 needs switch i25: case 1: false case 2: false else true  end; // Different value 1.
+invariant e25 needs switch i25: case 1: true  case 1: false else true  end; // Different key 2.
+invariant e25 needs switch i25: case 1: true  case 2: true  else true  end; // Different value 2.
+invariant e25 needs switch i25: case 1: true  case 2: false else false end; // Different else.
+invariant e25 needs switch i25: case 1: true                else true  end; // Different number of cases.
 
 invariant e25 needs switch a4: case l1: true case l2: true case l3: false end; // Switch case without else and with else.
 invariant e25 needs switch a4: case l1: true case l2: true else false end;
diff --git a/cif/org.eclipse.escet.cif.tests/tests/tchecker/dupl_invariants.cif.compile.err b/cif/org.eclipse.escet.cif.tests/tests/tchecker/dupl_invariants.cif.compile.err
index 2dd3cd3eebd35d2a42ab883703842353f54d9c51..5a93fe831696576c4a82caff48b2ed5aa26b5245 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/tchecker/dupl_invariants.cif.compile.err
+++ b/cif/org.eclipse.escet.cif.tests/tests/tchecker/dupl_invariants.cif.compile.err
@@ -50,46 +50,46 @@ WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 135, colu
 WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 136, column 11: Duplicate invariant for event "e23".
 WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 142, column 11: Duplicate invariant for event "e24".
 WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 143, column 11: Duplicate invariant for event "e24".
-WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 157, column 11: Duplicate invariant for event "e25".
 WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 158, column 11: Duplicate invariant for event "e25".
-WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 175, column 11: Duplicate invariant for event "e26".
+WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 159, column 11: Duplicate invariant for event "e25".
 WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 176, column 11: Duplicate invariant for event "e26".
-WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 180, column 11: Duplicate invariant for event "e26".
+WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 177, column 11: Duplicate invariant for event "e26".
 WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 181, column 11: Duplicate invariant for event "e26".
-WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 189, column 11: Duplicate invariant for event "e27".
+WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 182, column 11: Duplicate invariant for event "e26".
 WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 190, column 11: Duplicate invariant for event "e27".
-WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 199, column 11: Duplicate invariant for event "e28".
+WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 191, column 11: Duplicate invariant for event "e27".
 WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 200, column 11: Duplicate invariant for event "e28".
-WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 204, column 11: Duplicate invariant for event "e28".
+WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 201, column 11: Duplicate invariant for event "e28".
 WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 205, column 11: Duplicate invariant for event "e28".
-WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 209, column 11: Duplicate invariant for event "e28".
+WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 206, column 11: Duplicate invariant for event "e28".
 WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 210, column 11: Duplicate invariant for event "e28".
-WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 228, column 11: Duplicate invariant for event "e29".
+WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 211, column 11: Duplicate invariant for event "e28".
 WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 229, column 11: Duplicate invariant for event "e29".
-WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 235, column 11: Duplicate invariant for event "e30".
+WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 230, column 11: Duplicate invariant for event "e29".
 WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 236, column 11: Duplicate invariant for event "e30".
-WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 242, column 11: Duplicate invariant for event "e31".
+WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 237, column 11: Duplicate invariant for event "e30".
 WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 243, column 11: Duplicate invariant for event "e31".
-WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 251, column 11: Duplicate invariant for event "e32".
+WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 244, column 11: Duplicate invariant for event "e31".
 WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 252, column 11: Duplicate invariant for event "e32".
-WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 262, column 11: Duplicate invariant for event "e33".
+WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 253, column 11: Duplicate invariant for event "e32".
 WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 263, column 11: Duplicate invariant for event "e33".
-WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 274, column 11: Duplicate invariant for event "e34".
+WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 264, column 11: Duplicate invariant for event "e33".
 WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 275, column 11: Duplicate invariant for event "e34".
-WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 281, column 11: Duplicate invariant for event "e35".
+WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 276, column 11: Duplicate invariant for event "e34".
 WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 282, column 11: Duplicate invariant for event "e35".
-WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 289, column 11: Duplicate invariant for event "e36".
+WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 283, column 11: Duplicate invariant for event "e35".
 WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 290, column 11: Duplicate invariant for event "e36".
-WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 293, column 11: Duplicate invariant for event "e36".
+WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 291, column 11: Duplicate invariant for event "e36".
 WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 294, column 11: Duplicate invariant for event "e36".
-WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 311, column 11: Duplicate invariant for event "e37".
+WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 295, column 11: Duplicate invariant for event "e36".
 WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 312, column 11: Duplicate invariant for event "e37".
-WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 319, column 11: Duplicate invariant for event "e38".
+WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 313, column 11: Duplicate invariant for event "e37".
 WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 320, column 11: Duplicate invariant for event "e38".
-WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 338, column 11: Duplicate invariant for event "e39".
+WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 321, column 11: Duplicate invariant for event "e38".
 WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 339, column 11: Duplicate invariant for event "e39".
-WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 348, column 11: Duplicate invariant for event "e40".
+WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 340, column 11: Duplicate invariant for event "e39".
 WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 349, column 11: Duplicate invariant for event "e40".
-WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 350, column 46: Switch "else" is superfluous, as all locations already have a "case".
-WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 364, column 13: Duplicate invariant for event "e41".
+WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 350, column 11: Duplicate invariant for event "e40".
+WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 351, column 46: Switch "else" is superfluous, as all locations already have a "case".
 WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 365, column 13: Duplicate invariant for event "e41".
+WARNING: File "tchecker/dupl_invariants.cif": Semantic warning at line 366, column 13: Duplicate invariant for event "e41".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_aut_dupl_loc.cif.compile.err b/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_aut_dupl_loc.cif.compile.err
deleted file mode 100644
index 162e9d43319c5f63dccfe0a5f340e5ff94cfe12d..0000000000000000000000000000000000000000
--- a/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_aut_dupl_loc.cif.compile.err
+++ /dev/null
@@ -1,5 +0,0 @@
-ERROR: File "tchecker/switch_aut_dupl_loc.cif": Semantic error at line 16, column 25: Duplicate switch "case" for location "a.l1".
-ERROR: File "tchecker/switch_aut_dupl_loc.cif": Semantic error at line 18, column 25: Duplicate switch "case" for location "a.l1".
-ERROR: File "tchecker/switch_aut_dupl_loc.cif": Semantic error at line 21, column 25: Duplicate switch "case" for location "a.l1".
-ERROR: File "tchecker/switch_aut_dupl_loc.cif": Semantic error at line 22, column 25: Duplicate switch "case" for location "a.l1".
-ERROR: Failed to load CIF file "tchecker/switch_aut_dupl_loc.cif": the file has errors.
diff --git a/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_aut_missing_loc.cif.compile.err b/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_aut_missing_loc.cif.compile.err
deleted file mode 100644
index 6389ad699ad901ec99655c2f9cdd0358e1a7b305..0000000000000000000000000000000000000000
--- a/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_aut_missing_loc.cif.compile.err
+++ /dev/null
@@ -1,4 +0,0 @@
-ERROR: File "tchecker/switch_aut_missing_loc.cif": Semantic error at line 15, column 18: Missing switch "case" for location "a.l1".
-ERROR: File "tchecker/switch_aut_missing_loc.cif": Semantic error at line 15, column 18: Missing switch "case" for location "a.l3".
-ERROR: File "tchecker/switch_aut_missing_loc.cif": Semantic error at line 18, column 18: Missing switch "case" for location "a.l2".
-ERROR: Failed to load CIF file "tchecker/switch_aut_missing_loc.cif": the file has errors.
diff --git a/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_aut_superfluous_else.cif.compile.err b/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_aut_superfluous_else.cif.compile.err
deleted file mode 100644
index 703a6eda200a9811bc5775fd75fe06934a6eff62..0000000000000000000000000000000000000000
--- a/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_aut_superfluous_else.cif.compile.err
+++ /dev/null
@@ -1 +0,0 @@
-WARNING: File "tchecker/switch_aut_superfluous_else.cif": Semantic warning at line 18, column 18: Switch "else" is superfluous, as all locations already have a "case".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_case_out_of_range.cif b/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_case_out_of_range.cif
new file mode 100644
index 0000000000000000000000000000000000000000..253d00b85fb4a93cb21e934fe9e81f90d753936c
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_case_out_of_range.cif
@@ -0,0 +1,20 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+input int[1..3] i;
+alg int c1 = switch i:
+               case 1: 1
+               case 2: 2
+               case 3: 3
+               case 4: 4 // Key is out of range.
+             end;
diff --git a/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_complete_cases.cif b/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_complete_cases.cif
new file mode 100644
index 0000000000000000000000000000000000000000..759ae892c4f46d465249673d6040376b9df2b8ba
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_complete_cases.cif
@@ -0,0 +1,147 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+// bool
+
+input bool ib;
+alg int ab = switch ib:
+               case true:  1
+               case false: 2
+             end;
+
+// bool (via type definition)
+
+type t = bool;
+input t it;
+alg int at = switch it:
+               case true:  1
+               case false: 2
+             end;
+
+// bool (via component instantiation wrapping expression)
+
+group def G():
+  type t = bool;
+end
+g: G();
+input g.t iw;
+alg int aw = switch iw:
+               case true:  1
+               case false: 2
+             end;
+
+// bool (via component parameter wrapping expression)
+
+group def H(G g):
+  input g.t iw;
+  alg int aw = switch iw:
+                 case true:  1
+                 case false: 2
+               end;
+end
+h: H(g);
+
+// int (ranged)
+
+input int[8..9] ii;
+alg int ai = switch ii:
+               case 8: 1
+               case 9: 2
+             end;
+
+// enum
+
+enum e = e1, e2;
+input e ie;
+alg int ae = switch ie:
+               case e1: 1
+               case e2: 2
+             end;
+
+// real
+
+input real ir;
+alg int ar = switch ir:
+               case 1.0: 1
+               case 2.0: 2
+               else      3
+             end;
+
+// string
+
+input string is;
+alg int as = switch is:
+               case "a": 1
+               case "b": 2
+               else      3
+             end;
+
+// list (rangeless)
+
+input list bool il;
+alg int al = switch il:
+               case []:     1
+               case [true]: 2
+               else         3
+             end;
+
+// list (bounded)
+
+input list[1..2] int[5..5] il12;
+alg int al12 = switch il12:
+                 case [5]:    1
+                 case [5, 5]: 2
+               end;
+
+// list (array)
+
+input list[2] int[5..5] il1;
+alg int al1 = switch il1:
+                case [5, 5]: 1
+              end;
+
+// set
+
+input set bool iset;
+alg int aset = switch iset:
+                case {}:            1
+                case {false}:       2
+                case {true}:        3
+                case {false, true}: 4
+              end;
+
+// dict
+
+input dict(int[8..8]:bool) idict;
+alg int adict = switch idict:
+                  case {}:        1
+                  case {8:false}: 2
+                  case {8:true}:  3
+                end;
+
+// tuple
+
+input tuple(int[1..2] a, b) itup;
+alg int atup = switch itup:
+                 case (1, 1): 1
+                 case (1, 2): 1
+                 case (2, 1): 1
+                 case (2, 2): 1
+               end;
+
+// Types that don't support value equality:
+// - function
+// - distribution
+// - component
+// - component definition
+// - void
diff --git a/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_aut_dupl_loc.cif b/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_dupl_case.cif
similarity index 73%
rename from cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_aut_dupl_loc.cif
rename to cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_dupl_case.cif
index 86812cde858152928ca0df8b956cb0ee0226eb13..335ebeec5b300c3b5de1f0b01e3d943b0183d954 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_aut_dupl_loc.cif
+++ b/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_dupl_case.cif
@@ -11,6 +11,7 @@
 // SPDX-License-Identifier: MIT
 //////////////////////////////////////////////////////////////////////////////
 
+// Switch on automaton.
 automaton a:
   const int c1 = switch self:
                    case l1: 1
@@ -28,3 +29,16 @@ automaton a:
   location l2:
     initial;
 end
+
+// Switch on non-automaton.
+input int[1..3] i;
+const int c1 = switch i:
+                 case 1: 1
+                 case 2: 2
+                 case 1: 3
+               end;
+const int c2 = switch i:
+                 case 1: 1
+                 case 1: 2
+                 else    3
+               end;
diff --git a/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_dupl_case.cif.compile.err b/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_dupl_case.cif.compile.err
new file mode 100644
index 0000000000000000000000000000000000000000..91cb6689790849159bde7f8667bfd9895f906f63
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_dupl_case.cif.compile.err
@@ -0,0 +1,9 @@
+ERROR: File "tchecker/switch_dupl_case.cif": Semantic error at line 17, column 25: Duplicate switch "case" for location "a.l1".
+ERROR: File "tchecker/switch_dupl_case.cif": Semantic error at line 19, column 25: Duplicate switch "case" for location "a.l1".
+ERROR: File "tchecker/switch_dupl_case.cif": Semantic error at line 22, column 25: Duplicate switch "case" for location "a.l1".
+ERROR: File "tchecker/switch_dupl_case.cif": Semantic error at line 23, column 25: Duplicate switch "case" for location "a.l1".
+ERROR: File "tchecker/switch_dupl_case.cif": Semantic error at line 36, column 23: Duplicate switch "case" for value "1".
+ERROR: File "tchecker/switch_dupl_case.cif": Semantic error at line 38, column 23: Duplicate switch "case" for value "1".
+ERROR: File "tchecker/switch_dupl_case.cif": Semantic error at line 41, column 23: Duplicate switch "case" for value "1".
+ERROR: File "tchecker/switch_dupl_case.cif": Semantic error at line 42, column 23: Duplicate switch "case" for value "1".
+ERROR: Failed to load CIF file "tchecker/switch_dupl_case.cif": the file has errors.
diff --git a/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_eval_failure.cif b/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_eval_failure.cif
new file mode 100644
index 0000000000000000000000000000000000000000..73911d063706ca7756f0af16511ef0e66a1c9da3
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_eval_failure.cif
@@ -0,0 +1,20 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+input int[1..3] i;
+const int[0..2] a = 0;
+alg int c = switch i:
+              case 1: 1
+              case 2: 2
+              case 1 div a: 3
+            end;
diff --git a/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_eval_failure.cif.compile.err b/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_eval_failure.cif.compile.err
new file mode 100644
index 0000000000000000000000000000000000000000..c37c22acfac69ee41e6079cce2647042f1bfcaa4
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_eval_failure.cif.compile.err
@@ -0,0 +1,2 @@
+ERROR: File "tchecker/switch_eval_failure.cif": Semantic error at line 19, column 22: Evaluation failure: Division by zero: 1 div 0.
+ERROR: Failed to load CIF file "tchecker/switch_eval_failure.cif": the file has errors.
diff --git a/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_missing_case.cif b/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_missing_case.cif
new file mode 100644
index 0000000000000000000000000000000000000000..26b9828eccc7296e6ae674dfc712b0b01c773b2b
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_missing_case.cif
@@ -0,0 +1,49 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+// Switch on automaton.
+automaton a:
+  const int c1 = switch self:
+                   case l2: 1
+                 end;
+  const int c2 = switch a:
+                   case l1: 1
+                   case l3: 2
+                 end;
+
+  location l1:
+    initial;
+  location l2:
+    initial;
+  location l3:
+    initial;
+end
+
+// Switch on non-automaton.
+input int[1..3] i;
+const int c1 = switch i:
+                 case 2: 2
+               end;
+const int c2 = switch i:
+                 case 1: 1
+                 case 3: 3
+               end;
+
+// Switch with many possible values.
+input int[1..2147000] ix;
+alg int cx = switch ix:
+               case 1: 1
+               case 2: 2
+               case 3: 3
+               case 4: 4
+             end;
diff --git a/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_missing_case.cif.compile.err b/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_missing_case.cif.compile.err
new file mode 100644
index 0000000000000000000000000000000000000000..aacb8b9fa25be91770ddff6fdff328ca5a0d92cc
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_missing_case.cif.compile.err
@@ -0,0 +1,8 @@
+ERROR: File "tchecker/switch_missing_case.cif": Semantic error at line 16, column 18: Missing switch "case" for location "a.l1".
+ERROR: File "tchecker/switch_missing_case.cif": Semantic error at line 16, column 18: Missing switch "case" for location "a.l3".
+ERROR: File "tchecker/switch_missing_case.cif": Semantic error at line 19, column 18: Missing switch "case" for location "a.l2".
+ERROR: File "tchecker/switch_missing_case.cif": Semantic error at line 34, column 16: Missing switch "case" for value "1".
+ERROR: File "tchecker/switch_missing_case.cif": Semantic error at line 34, column 16: Missing switch "case" for value "3".
+ERROR: File "tchecker/switch_missing_case.cif": Semantic error at line 37, column 16: Missing switch "case" for value "2".
+ERROR: File "tchecker/switch_missing_case.cif": Semantic error at line 44, column 14: Missing switch "case" for some values.
+ERROR: Failed to load CIF file "tchecker/switch_missing_case.cif": the file has errors.
diff --git a/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_missing_else.cif b/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_missing_else.cif
index 5e8bb47c49733a6eec43333b5d1c527123327799..5945c3d4bb05f65c5573e728b6722efad1877710 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_missing_else.cif
+++ b/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_missing_else.cif
@@ -11,4 +11,17 @@
 // SPDX-License-Identifier: MIT
 //////////////////////////////////////////////////////////////////////////////
 
-const int c = switch 5: case 5: 6 end;
+// Type has too many values.
+input list int[5..5] i1;
+const int c1 = switch 5: case i1[0]: 6 end;
+
+input real i2;
+const int c2 = switch 5.0: case i2: 6 end;
+
+// Discrete variable can not be statically evaluated.
+automaton a:
+  disc int[8..8] d = 8;
+  alg int c = switch 8: case d: 6 end;
+  location:
+    initial;
+end
diff --git a/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_missing_else.cif.compile.err b/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_missing_else.cif.compile.err
index aa6f3e715525bbb14a9c0cec63bb9d3011836084..aca4e9c85bfb4f5ed010726ca2edc43c2210ff31 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_missing_else.cif.compile.err
+++ b/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_missing_else.cif.compile.err
@@ -1,2 +1,4 @@
-ERROR: File "tchecker/switch_missing_else.cif": Semantic error at line 14, column 15: The switch is missing an "else".
+ERROR: File "tchecker/switch_missing_else.cif": Semantic error at line 16, column 16: The switch is missing an "else".
+ERROR: File "tchecker/switch_missing_else.cif": Semantic error at line 19, column 16: The switch is missing an "else".
+ERROR: File "tchecker/switch_missing_else.cif": Semantic error at line 24, column 15: The switch is missing an "else".
 ERROR: Failed to load CIF file "tchecker/switch_missing_else.cif": the file has errors.
diff --git a/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_aut_superfluous_else.cif b/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_superfluous_else.cif
similarity index 77%
rename from cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_aut_superfluous_else.cif
rename to cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_superfluous_else.cif
index dda76ff79210b1b60f440d7d3d044ec9fdff962a..6bbb01befa5af0e52b9677b0efb11030b9fb290a 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_aut_superfluous_else.cif
+++ b/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_superfluous_else.cif
@@ -11,6 +11,7 @@
 // SPDX-License-Identifier: MIT
 //////////////////////////////////////////////////////////////////////////////
 
+// Switch on automaton.
 automaton a:
   alg int c1 = switch self:
                  case l1: 1
@@ -29,4 +30,12 @@ automaton b:
     initial;
 end
 
-alg real c1 = switch b: else 1.0 end;
+alg real a1 = switch b: else 1.0 end;
+
+// Switch on non-automaton.
+input int[1..2] i;
+alg int a2 = switch i:
+               case 1: 1
+               case 2: 2
+               else    3
+             end;
diff --git a/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_superfluous_else.cif.compile.err b/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_superfluous_else.cif.compile.err
new file mode 100644
index 0000000000000000000000000000000000000000..9deb46a1c300627d5db030dfd9f9e94f29d7f2e9
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tests/tests/tchecker/switch_superfluous_else.cif.compile.err
@@ -0,0 +1,2 @@
+WARNING: File "tchecker/switch_superfluous_else.cif": Semantic warning at line 19, column 18: Switch "else" is superfluous, as all locations already have a "case".
+WARNING: File "tchecker/switch_superfluous_else.cif": Semantic warning at line 40, column 16: Switch "else" is superfluous, as all values already have a "case".
diff --git a/cif/org.eclipse.escet.cif.tests/tests/test_datasynth.tooldef b/cif/org.eclipse.escet.cif.tests/tests/test_datasynth.tooldef
index 1f65f2c39397e93ee3a15f43e59c543c36d828b8..4b98faab268f93652272e7fd22d94ef5dc5859db 100644
--- a/cif/org.eclipse.escet.cif.tests/tests/test_datasynth.tooldef
+++ b/cif/org.eclipse.escet.cif.tests/tests/test_datasynth.tooldef
@@ -24,6 +24,7 @@ list string default_options = [
     "--bdd-dbg-maxpaths=20",
     "--bdd-simplify=guards-plants,initial-unctrl",
     "--forward-reach=on",
+    "--edge-granularity=per-edge",
 ];
 
 string opt_algos_on      = "--dcsh-order=on  --force-order=on  --sliding-window-order=on";
@@ -32,95 +33,139 @@ string var_order_default = "--dcsh-order=on  --force-order=on  --sliding-window-
 string opt_simplify_all  = "--bdd-simplify=guards-plants,guards-req-auts,guards-se-excl-plant-invs,guards-se-excl-req-invs,guards-state-plant-invs,guards-state-req-invs,guards-ctrl-beh,initial-unctrl,initial-state-plant-invs";
 
 map(string:list string) test_options = {
-    "datasynth/bdd_dbg_maxnodes.cif":                          ["--bdd-dbg-maxnodes=2"],
-    "datasynth/bdd_dbg_maxpaths.cif":                          ["--bdd-dbg-maxpaths=2"],
-    "datasynth/bdd_out_nodes.cif":                             ["-t nodes -p n"],
-    "datasynth/dining_philosophers4.cif":                      [opt_simplify_all],
-    "datasynth/edge_order_both_custom_basic.cif":              ["--backward-edge-order=C,p.event,D,p.z,p.a,p.X,p.Y,p.c --forward-edge-order=C,p.event,D,p.z,p.a,p.X,p.Y,p.c"],
-    "datasynth/edge_order_both_custom_dupl_no.cif":            ["--stats=bdd-perf-cache,bdd-perf-max-nodes --backward-edge-order=Counter.dec,Actuator.off,Counter.inc,Actuator.on --forward-edge-order=Counter.dec,Actuator.off,Counter.inc,Actuator.on"],
-    "datasynth/edge_order_both_custom_dupl_yes.cif":           ["--stats=bdd-perf-cache,bdd-perf-max-nodes --backward-edge-order=Counter.dec,Counter.dec,Counter.dec,Counter.dec,Counter.dec,Actuator.off,Counter.inc,Counter.inc,Counter.inc,Counter.inc,Counter.inc,Actuator.on --forward-edge-order=Counter.dec,Counter.dec,Counter.dec,Counter.dec,Counter.dec,Actuator.off,Counter.inc,Counter.inc,Counter.inc,Counter.inc,Counter.inc,Actuator.on --edge-order-duplicate-events=allowed"],
-    "datasynth/edge_order_both_dupl_match1.cif":               ["--backward-edge-order=p.c,*          --forward-edge-order=p.c,*"],
-    "datasynth/edge_order_both_dupl_match2.cif":               ["--backward-edge-order=p.event,*      --forward-edge-order=p.event,*"],
-    "datasynth/edge_order_both_missing.cif":                   ["--backward-edge-order=q.*            --forward-edge-order=q.*"],
-    "datasynth/edge_order_both_model.cif":                     ["--backward-edge-order=model          --forward-edge-order=model"],
-    "datasynth/edge_order_both_no_match.cif":                  ["--backward-edge-order=*3             --forward-edge-order=*3"],
-    "datasynth/edge_order_both_random_invalid_seed.cif":       ["--backward-edge-order=random:x       --forward-edge-order=random:x"],
-    "datasynth/edge_order_both_random.cif":                    ["--backward-edge-order=random:88      --forward-edge-order=random:88"],
-    "datasynth/edge_order_both_reverse_model.cif":             ["--backward-edge-order=reverse-model  --forward-edge-order=reverse-model"],
-    "datasynth/edge_order_both_reverse_sorted.cif":            ["--backward-edge-order=reverse-sorted --forward-edge-order=reverse-sorted"],
-    "datasynth/edge_order_both_sorted.cif":                    ["--backward-edge-order=sorted         --forward-edge-order=sorted"],
-    "datasynth/edge_order_forward_random_off.cif":             ["--forward-edge-order=random:88 --forward-reach=off"],
-    "datasynth/edge_order_forward_random_on.cif":              ["--forward-edge-order=random:88 --forward-reach=on"],
-    "datasynth/edge_order_old_option_unsupported.cif":         ["-e random"],
-    "datasynth/edge_order_single_backward_random.cif":         ["--backward-edge-order=random:88"],
-    "datasynth/edge_order_single_forward_random.cif":          ["--forward-edge-order=random:88"],
-    "datasynth/event_warnings.cif":                            ["--forward-reach=on"],
-    "datasynth/forward_reach_off.cif":                         ["--forward-reach=off --bdd-simplify="],
-    "datasynth/forward_reach_on.cif":                          ["--forward-reach=on  --bdd-simplify="],
-    "datasynth/inv_state_evt_exclusion_plant_simple.cif":      ["--event-warn=false"],
-    "datasynth/namespace.cif":                                 ["-n a.b.c"],
-    "datasynth/namespace_conflict.cif":                        ["-n g.h.c.n"],
-    "datasynth/namespace_invalid.cif":                         ["-n a.b."],
-    "datasynth/namespace_non_empty.cif":                       ["-n g.h"],
-    "datasynth/simplify_ctrl_beh_off.cif":                     ["--bdd-simplify="],
-    "datasynth/simplify_ctrl_beh_on.cif":                      ["--bdd-simplify=guards-ctrl-beh"],
-    "datasynth/simplify_initial_plant_inv_off.cif":            ["--bdd-simplify="],
-    "datasynth/simplify_initial_plant_inv_on.cif":             ["--bdd-simplify=initial-state-plant-invs"],
-    "datasynth/simplify_initial_unctrl_off.cif":               ["--bdd-simplify="],
-    "datasynth/simplify_initial_unctrl_on.cif":                ["--bdd-simplify=initial-unctrl"],
-    "datasynth/simplify_plants_off.cif":                       ["--bdd-simplify="],
-    "datasynth/simplify_plants_on.cif":                        ["--bdd-simplify=guards-plants"],
-    "datasynth/simplify_propagation_all.cif":                  ["--bdd-simplify=guards-plants,guards-req-auts,guards-se-excl-req-invs,guards-state-req-invs,guards-ctrl-beh,initial-unctrl"],
-    "datasynth/simplify_propagation_none.cif":                 ["--bdd-simplify="],
-    "datasynth/simplify_range_invs_off.cif":                   ["--bdd-simplify="],
-    "datasynth/simplify_range_invs_on.cif":                    ["--bdd-simplify=guards-state-req-invs"],
-    "datasynth/simplify_req_auts_off.cif":                     ["--bdd-simplify="],
-    "datasynth/simplify_req_auts_on.cif":                      ["--bdd-simplify=guards-req-auts"],
-    "datasynth/simplify_se_excl_plant_invs_off.cif":           ["--bdd-simplify="],
-    "datasynth/simplify_se_excl_plant_invs_on.cif":            ["--bdd-simplify=guards-se-excl-plant-invs"],
-    "datasynth/simplify_se_excl_req_invs_off.cif":             ["--bdd-simplify="],
-    "datasynth/simplify_se_excl_req_invs_on.cif":              ["--bdd-simplify=guards-se-excl-req-invs"],
-    "datasynth/simplify_state_plant_invs_off.cif":             ["--bdd-simplify="],
-    "datasynth/simplify_state_plant_invs_on.cif":              ["--bdd-simplify=guards-state-plant-invs"],
-    "datasynth/simplify_state_req_invs_off.cif":               ["--bdd-simplify="],
-    "datasynth/simplify_state_req_invs_on.cif":                ["--bdd-simplify=guards-state-req-invs"],
-    "datasynth/state_plant_invs_ctrl.cif":                     [opt_simplify_all],
-    "datasynth/state_plant_invs_init.cif":                     ["--forward-reach=on"],
-    "datasynth/state_plant_invs_req_aut.cif":                  ["--forward-reach=on"],
-    "datasynth/state_plant_invs_simple.cif":                   ["--forward-reach=on"],
-    "datasynth/state_plant_invs_unctrl.cif":                   [opt_simplify_all],
-    "datasynth/state_req_inv_all_ctrl_beh.cif":                ["--state-req-invs=all-ctrl-beh"],
-    "datasynth/state_req_inv_per_edge.cif":                    ["--state-req-invs=per-edge"],
-    "datasynth/stats.cif":                                     ["--stats=bdd-perf-cache,bdd-perf-cont,bdd-perf-max-nodes"],
-    "datasynth/traffic_lights_req_state_inv_all_ctrl_beh.cif": ["--state-req-invs=all-ctrl-beh"],
-    "datasynth/traffic_lights_req_state_inv_per_edge.cif":     ["--state-req-invs=per-edge"],
-    "datasynth/supname_custom.cif":                            ["-s g"],
-    "datasynth/supname_invalid.cif":                           ["-s b@"],
-    "datasynth/var_order_adv_dcsh_from_paper.cif":             ["--adv-var-order=sorted->dcsh(metric=wes,relations=linearized)->force(metric=total-span,relations=legacy)->slidwin(metric=total-span,relations=legacy) " + var_order_default],
-    "datasynth/var_order_adv_parse_err.cif":                   ["--adv-var-order=model-> " + var_order_default],
-    "datasynth/var_order_adv_basic_mix.cif":                   ["--adv-var-order=random(seed=1)"],
-    "datasynth/var_order_adv_tcheck_err.cif":                  ["--adv-var-order=model(a=1) " + var_order_default],
-    "datasynth/var_order_custom_algos_off.cif":                ["-r *c*;*3,*1;*2 " + opt_algos_off + " " + opt_simplify_all],
-    "datasynth/var_order_custom_algos_on.cif":                 ["-r *c*;*3,*1;*2 " + opt_algos_on + " " + opt_simplify_all],
-    "datasynth/var_order_custom_dupl_match.cif":               ["-r p.x;*"],
-    "datasynth/var_order_custom_missing.cif":                  ["-r q"],
-    "datasynth/var_order_custom_no_match.cif":                 ["-r *3"],
-    "datasynth/var_order_hyper_edge_legacy.cif":               ["--hyper-edge-algo=legacy"],
-    "datasynth/var_order_hyper_edge_linearized.cif":           ["--hyper-edge-algo=linearized"],
-    "datasynth/var_order_model_algos_off.cif":                 ["-r model " + opt_algos_off + " " + opt_simplify_all],
-    "datasynth/var_order_model_algos_on.cif":                  ["-r model " + opt_algos_on + " " + opt_simplify_all],
-    "datasynth/var_order_random_algo_dcsh_on.cif":             ["-r random:88 " + opt_algos_off + " --dcsh-order=on " + opt_simplify_all],
-    "datasynth/var_order_random_algo_force_on.cif":            ["-r random:88 " + opt_algos_off + " --force-order=on " + opt_simplify_all],
-    "datasynth/var_order_random_algo_slidwin_on.cif":          ["-r random:88 " + opt_algos_off + " --sliding-window-order=on " + opt_simplify_all],
-    "datasynth/var_order_random_algos_off.cif":                ["-r random:88 " + opt_algos_off + " " + opt_simplify_all],
-    "datasynth/var_order_random_algos_on.cif":                 ["-r random:88 " + opt_algos_on + " " + opt_simplify_all],
-    "datasynth/var_order_random_invalid_seed.cif":             ["-r random:x"],
-    "datasynth/var_order_reverse_model_algos_off.cif":         ["-r reverse-model " + opt_algos_off + " " + opt_simplify_all],
-    "datasynth/var_order_reverse_model_algos_on.cif":          ["-r reverse-model " + opt_algos_on + " " + opt_simplify_all],
-    "datasynth/var_order_reverse_sorted_algos_off.cif":        ["-r reverse-sorted " + opt_algos_off + " " + opt_simplify_all],
-    "datasynth/var_order_reverse_sorted_algos_on.cif":         ["-r reverse-sorted " + opt_algos_on + " " + opt_simplify_all],
-    "datasynth/var_order_sorted_algos_off.cif":                ["-r sorted " + opt_algos_off + " " + opt_simplify_all],
-    "datasynth/var_order_sorted_algos_on.cif":                 ["-r sorted " + opt_algos_on + " " + opt_simplify_all],
+    "datasynth/bdd_dbg_maxnodes.cif":                           ["--bdd-dbg-maxnodes=2"],
+    "datasynth/bdd_dbg_maxpaths.cif":                           ["--bdd-dbg-maxpaths=2"],
+    "datasynth/bdd_out_nodes.cif":                              ["-t nodes -p n"],
+    "datasynth/dining_philosophers4.cif":                       [opt_simplify_all],
+    "datasynth/edge_granularity_errors01_per_edge.cif":         ["--edge-granularity=per-edge"],
+    "datasynth/edge_granularity_errors01_per_event.cif":        ["--edge-granularity=per-event"],
+    "datasynth/edge_granularity_errors02_per_edge.cif":         ["--edge-granularity=per-edge"],
+    "datasynth/edge_granularity_errors02_per_event.cif":        ["--edge-granularity=per-event"],
+    "datasynth/edge_granularity_errors03_per_edge.cif":         ["--edge-granularity=per-edge"],
+    "datasynth/edge_granularity_errors03_per_event.cif":        ["--edge-granularity=per-event"],
+    "datasynth/edge_granularity_errors04_per_edge.cif":         ["--edge-granularity=per-edge"],
+    "datasynth/edge_granularity_errors04_per_event.cif":        ["--edge-granularity=per-event"],
+    "datasynth/edge_granularity_errors05_per_edge.cif":         ["--edge-granularity=per-edge"],
+    "datasynth/edge_granularity_errors05_per_event.cif":        ["--edge-granularity=per-event"],
+    "datasynth/edge_granularity_errors06_per_edge.cif":         ["--edge-granularity=per-edge"],
+    "datasynth/edge_granularity_errors06_per_event.cif":        ["--edge-granularity=per-event"],
+    "datasynth/edge_granularity_errors07_per_edge.cif":         ["--edge-granularity=per-edge"],
+    "datasynth/edge_granularity_errors07_per_event.cif":        ["--edge-granularity=per-event"],
+    "datasynth/edge_granularity_errors08_per_edge.cif":         ["--edge-granularity=per-edge"],
+    "datasynth/edge_granularity_errors08_per_event.cif":        ["--edge-granularity=per-event"],
+    "datasynth/edge_granularity_errors09_per_edge.cif":         ["--edge-granularity=per-edge"],
+    "datasynth/edge_granularity_errors09_per_event.cif":        ["--edge-granularity=per-event"],
+    "datasynth/edge_granularity_errors10_per_edge.cif":         ["--edge-granularity=per-edge"],
+    "datasynth/edge_granularity_errors10_per_event.cif":        ["--edge-granularity=per-event"],
+    "datasynth/edge_granularity_errors11_per_edge.cif":         ["--edge-granularity=per-edge"],
+    "datasynth/edge_granularity_errors11_per_event.cif":        ["--edge-granularity=per-event"],
+    "datasynth/edge_granularity_errors12_per_edge.cif":         ["--edge-granularity=per-edge"],
+    "datasynth/edge_granularity_errors12_per_event.cif":        ["--edge-granularity=per-event"],
+    "datasynth/edge_granularity_errors13_per_edge.cif":         ["--edge-granularity=per-edge"],
+    "datasynth/edge_granularity_errors13_per_event.cif":        ["--edge-granularity=per-event"],
+    "datasynth/edge_granularity_guards_updates1_per_edge.cif":  ["--edge-granularity=per-edge"],
+    "datasynth/edge_granularity_guards_updates1_per_event.cif": ["--edge-granularity=per-event"],
+    "datasynth/edge_granularity_guards_updates2_per_edge.cif":  ["--edge-granularity=per-edge"],
+    "datasynth/edge_granularity_guards_updates2_per_event.cif": ["--edge-granularity=per-event"],
+    "datasynth/edge_granularity_guards_updates3_per_edge.cif":  ["--edge-granularity=per-edge"],
+    "datasynth/edge_granularity_guards_updates3_per_event.cif": ["--edge-granularity=per-event"],
+    "datasynth/edge_granularity_guards_updates4_per_edge.cif":  ["--edge-granularity=per-edge"],
+    "datasynth/edge_granularity_guards_updates4_per_event.cif": ["--edge-granularity=per-event"],
+    "datasynth/edge_granularity_guards_updates5_per_edge.cif":  ["--edge-granularity=per-edge"],
+    "datasynth/edge_granularity_guards_updates5_per_event.cif": ["--edge-granularity=per-event"],
+    "datasynth/edge_granularity_guards_updates6_per_edge.cif":  ["--edge-granularity=per-edge"],
+    "datasynth/edge_granularity_guards_updates6_per_event.cif": ["--edge-granularity=per-event"],
+    "datasynth/edge_granularity_guards_updates7_per_edge.cif":  ["--edge-granularity=per-edge"],
+    "datasynth/edge_granularity_guards_updates7_per_event.cif": ["--edge-granularity=per-event"],
+    "datasynth/edge_granularity_guards_updates8_per_edge.cif":  ["--edge-granularity=per-edge"],
+    "datasynth/edge_granularity_guards_updates8_per_event.cif": ["--edge-granularity=per-event"],
+    "datasynth/edge_granularity_simple_per_edge.cif":           ["--edge-granularity=per-edge"],
+    "datasynth/edge_granularity_simple_per_event.cif":          ["--edge-granularity=per-event"],
+    "datasynth/edge_order_both_custom_basic.cif":               ["--backward-edge-order=C,p.event,D,p.z,p.a,p.X,p.Y,p.c --forward-edge-order=C,p.event,D,p.z,p.a,p.X,p.Y,p.c"],
+    "datasynth/edge_order_both_custom_dupl_no.cif":             ["--stats=bdd-perf-cache,bdd-perf-max-nodes --backward-edge-order=Counter.dec,Actuator.off,Counter.inc,Actuator.on --forward-edge-order=Counter.dec,Actuator.off,Counter.inc,Actuator.on"],
+    "datasynth/edge_order_both_custom_dupl_yes.cif":            ["--stats=bdd-perf-cache,bdd-perf-max-nodes --backward-edge-order=Counter.dec,Counter.dec,Counter.dec,Counter.dec,Counter.dec,Actuator.off,Counter.inc,Counter.inc,Counter.inc,Counter.inc,Counter.inc,Actuator.on --forward-edge-order=Counter.dec,Counter.dec,Counter.dec,Counter.dec,Counter.dec,Actuator.off,Counter.inc,Counter.inc,Counter.inc,Counter.inc,Counter.inc,Actuator.on --edge-order-duplicate-events=allowed"],
+    "datasynth/edge_order_both_dupl_match1.cif":                ["--backward-edge-order=p.c,*          --forward-edge-order=p.c,*"],
+    "datasynth/edge_order_both_dupl_match2.cif":                ["--backward-edge-order=p.event,*      --forward-edge-order=p.event,*"],
+    "datasynth/edge_order_both_missing.cif":                    ["--backward-edge-order=q.*            --forward-edge-order=q.*"],
+    "datasynth/edge_order_both_model.cif":                      ["--backward-edge-order=model          --forward-edge-order=model"],
+    "datasynth/edge_order_both_no_match.cif":                   ["--backward-edge-order=*3             --forward-edge-order=*3"],
+    "datasynth/edge_order_both_random_invalid_seed.cif":        ["--backward-edge-order=random:x       --forward-edge-order=random:x"],
+    "datasynth/edge_order_both_random.cif":                     ["--backward-edge-order=random:88      --forward-edge-order=random:88"],
+    "datasynth/edge_order_both_reverse_model.cif":              ["--backward-edge-order=reverse-model  --forward-edge-order=reverse-model"],
+    "datasynth/edge_order_both_reverse_sorted.cif":             ["--backward-edge-order=reverse-sorted --forward-edge-order=reverse-sorted"],
+    "datasynth/edge_order_both_sorted.cif":                     ["--backward-edge-order=sorted         --forward-edge-order=sorted"],
+    "datasynth/edge_order_forward_random_off.cif":              ["--forward-edge-order=random:88 --forward-reach=off"],
+    "datasynth/edge_order_forward_random_on.cif":               ["--forward-edge-order=random:88 --forward-reach=on"],
+    "datasynth/edge_order_old_option_unsupported.cif":          ["-e random"],
+    "datasynth/edge_order_single_backward_random.cif":          ["--backward-edge-order=random:88"],
+    "datasynth/edge_order_single_forward_random.cif":           ["--forward-edge-order=random:88"],
+    "datasynth/event_warnings.cif":                             ["--forward-reach=on"],
+    "datasynth/forward_reach_off.cif":                          ["--forward-reach=off --bdd-simplify="],
+    "datasynth/forward_reach_on.cif":                           ["--forward-reach=on  --bdd-simplify="],
+    "datasynth/inv_state_evt_exclusion_plant_simple.cif":       ["--event-warn=false"],
+    "datasynth/namespace.cif":                                  ["-n a.b.c"],
+    "datasynth/namespace_conflict.cif":                         ["-n g.h.c.n"],
+    "datasynth/namespace_invalid.cif":                          ["-n a.b."],
+    "datasynth/namespace_non_empty.cif":                        ["-n g.h"],
+    "datasynth/simplify_ctrl_beh_off.cif":                      ["--bdd-simplify="],
+    "datasynth/simplify_ctrl_beh_on.cif":                       ["--bdd-simplify=guards-ctrl-beh"],
+    "datasynth/simplify_initial_plant_inv_off.cif":             ["--bdd-simplify="],
+    "datasynth/simplify_initial_plant_inv_on.cif":              ["--bdd-simplify=initial-state-plant-invs"],
+    "datasynth/simplify_initial_unctrl_off.cif":                ["--bdd-simplify="],
+    "datasynth/simplify_initial_unctrl_on.cif":                 ["--bdd-simplify=initial-unctrl"],
+    "datasynth/simplify_plants_off.cif":                        ["--bdd-simplify="],
+    "datasynth/simplify_plants_on.cif":                         ["--bdd-simplify=guards-plants"],
+    "datasynth/simplify_propagation_all.cif":                   ["--bdd-simplify=guards-plants,guards-req-auts,guards-se-excl-req-invs,guards-state-req-invs,guards-ctrl-beh,initial-unctrl"],
+    "datasynth/simplify_propagation_none.cif":                  ["--bdd-simplify="],
+    "datasynth/simplify_range_invs_off.cif":                    ["--bdd-simplify="],
+    "datasynth/simplify_range_invs_on.cif":                     ["--bdd-simplify=guards-state-req-invs"],
+    "datasynth/simplify_req_auts_off.cif":                      ["--bdd-simplify="],
+    "datasynth/simplify_req_auts_on.cif":                       ["--bdd-simplify=guards-req-auts"],
+    "datasynth/simplify_se_excl_plant_invs_off.cif":            ["--bdd-simplify="],
+    "datasynth/simplify_se_excl_plant_invs_on.cif":             ["--bdd-simplify=guards-se-excl-plant-invs"],
+    "datasynth/simplify_se_excl_req_invs_off.cif":              ["--bdd-simplify="],
+    "datasynth/simplify_se_excl_req_invs_on.cif":               ["--bdd-simplify=guards-se-excl-req-invs"],
+    "datasynth/simplify_state_plant_invs_off.cif":              ["--bdd-simplify="],
+    "datasynth/simplify_state_plant_invs_on.cif":               ["--bdd-simplify=guards-state-plant-invs"],
+    "datasynth/simplify_state_req_invs_off.cif":                ["--bdd-simplify="],
+    "datasynth/simplify_state_req_invs_on.cif":                 ["--bdd-simplify=guards-state-req-invs"],
+    "datasynth/state_plant_invs_ctrl.cif":                      [opt_simplify_all],
+    "datasynth/state_plant_invs_init.cif":                      ["--forward-reach=on"],
+    "datasynth/state_plant_invs_req_aut.cif":                   ["--forward-reach=on"],
+    "datasynth/state_plant_invs_simple.cif":                    ["--forward-reach=on"],
+    "datasynth/state_plant_invs_unctrl.cif":                    [opt_simplify_all],
+    "datasynth/state_req_inv_all_ctrl_beh.cif":                 ["--state-req-invs=all-ctrl-beh"],
+    "datasynth/state_req_inv_per_edge.cif":                     ["--state-req-invs=per-edge"],
+    "datasynth/stats.cif":                                      ["--stats=bdd-perf-cache,bdd-perf-cont,bdd-perf-max-nodes"],
+    "datasynth/traffic_lights_req_state_inv_all_ctrl_beh.cif":  ["--state-req-invs=all-ctrl-beh"],
+    "datasynth/traffic_lights_req_state_inv_per_edge.cif":      ["--state-req-invs=per-edge"],
+    "datasynth/supname_custom.cif":                             ["-s g"],
+    "datasynth/supname_invalid.cif":                            ["-s b@"],
+    "datasynth/var_order_adv_dcsh_from_paper.cif":              ["--adv-var-order=sorted->dcsh(metric=wes,relations=linearized)->force(metric=total-span,relations=legacy)->slidwin(metric=total-span,relations=legacy) " + var_order_default],
+    "datasynth/var_order_adv_parse_err.cif":                    ["--adv-var-order=model-> " + var_order_default],
+    "datasynth/var_order_adv_basic_mix.cif":                    ["--adv-var-order=random(seed=1)"],
+    "datasynth/var_order_adv_tcheck_err.cif":                   ["--adv-var-order=model(a=1) " + var_order_default],
+    "datasynth/var_order_custom_algos_off.cif":                 ["-r *c*;*3,*1;*2 " + opt_algos_off + " " + opt_simplify_all],
+    "datasynth/var_order_custom_algos_on.cif":                  ["-r *c*;*3,*1;*2 " + opt_algos_on + " " + opt_simplify_all],
+    "datasynth/var_order_custom_dupl_match.cif":                ["-r p.x;*"],
+    "datasynth/var_order_custom_missing.cif":                   ["-r q"],
+    "datasynth/var_order_custom_no_match.cif":                  ["-r *3"],
+    "datasynth/var_order_hyper_edge_legacy.cif":                ["--hyper-edge-algo=legacy"],
+    "datasynth/var_order_hyper_edge_linearized.cif":            ["--hyper-edge-algo=linearized"],
+    "datasynth/var_order_model_algos_off.cif":                  ["-r model " + opt_algos_off + " " + opt_simplify_all],
+    "datasynth/var_order_model_algos_on.cif":                   ["-r model " + opt_algos_on + " " + opt_simplify_all],
+    "datasynth/var_order_random_algo_dcsh_on.cif":              ["-r random:88 " + opt_algos_off + " --dcsh-order=on " + opt_simplify_all],
+    "datasynth/var_order_random_algo_force_on.cif":             ["-r random:88 " + opt_algos_off + " --force-order=on " + opt_simplify_all],
+    "datasynth/var_order_random_algo_slidwin_on.cif":           ["-r random:88 " + opt_algos_off + " --sliding-window-order=on " + opt_simplify_all],
+    "datasynth/var_order_random_algos_off.cif":                 ["-r random:88 " + opt_algos_off + " " + opt_simplify_all],
+    "datasynth/var_order_random_algos_on.cif":                  ["-r random:88 " + opt_algos_on + " " + opt_simplify_all],
+    "datasynth/var_order_random_invalid_seed.cif":              ["-r random:x"],
+    "datasynth/var_order_reverse_model_algos_off.cif":          ["-r reverse-model " + opt_algos_off + " " + opt_simplify_all],
+    "datasynth/var_order_reverse_model_algos_on.cif":           ["-r reverse-model " + opt_algos_on + " " + opt_simplify_all],
+    "datasynth/var_order_reverse_sorted_algos_off.cif":         ["-r reverse-sorted " + opt_algos_off + " " + opt_simplify_all],
+    "datasynth/var_order_reverse_sorted_algos_on.cif":          ["-r reverse-sorted " + opt_algos_on + " " + opt_simplify_all],
+    "datasynth/var_order_sorted_algos_off.cif":                 ["-r sorted " + opt_algos_off + " " + opt_simplify_all],
+    "datasynth/var_order_sorted_algos_on.cif":                  ["-r sorted " + opt_algos_on + " " + opt_simplify_all],
 };
 set string test_skip = {};
 
diff --git a/cif/org.eclipse.escet.cif.texteditor/.settings/org.eclipse.jdt.core.prefs b/cif/org.eclipse.escet.cif.texteditor/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/cif/org.eclipse.escet.cif.texteditor/.settings/org.eclipse.jdt.core.prefs
+++ b/cif/org.eclipse.escet.cif.texteditor/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/cif/org.eclipse.escet.cif.texteditor/.settings/org.eclipse.jdt.ui.prefs b/cif/org.eclipse.escet.cif.texteditor/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/cif/org.eclipse.escet.cif.texteditor/.settings/org.eclipse.jdt.ui.prefs
+++ b/cif/org.eclipse.escet.cif.texteditor/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/cif/org.eclipse.escet.cif.texteditor/.settings/org.eclipse.ltk.core.refactoring.prefs b/cif/org.eclipse.escet.cif.texteditor/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.texteditor/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/cif/org.eclipse.escet.cif.texteditor/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.texteditor/META-INF/MANIFEST.MF
index 2c93b68246eb9920e9bbf425a77b99e110c61697..c67bf618c45aeb047898f8a5af46a334b3ca900a 100644
--- a/cif/org.eclipse.escet.cif.texteditor/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.texteditor/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET CIF Text Editor (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.cif.texteditor;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
@@ -10,17 +10,17 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="3.17.0",
  org.eclipse.ui;bundle-version="3.115.0",
  org.eclipse.ui.editors;bundle-version="3.13.0",
  org.eclipse.jface.text;bundle-version="3.16.100",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.cif.parser;bundle-version="0.9.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.cif.parser;bundle-version="0.10.0",
  org.eclipse.core.resources;bundle-version="3.13.600",
- org.eclipse.escet.common.position.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.cif.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
+ org.eclipse.escet.common.position.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.cif.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
  org.apache.commons.lang3;bundle-version="3.1.0",
- org.eclipse.escet.setext.texteditorbase;bundle-version="0.9.0",
+ org.eclipse.escet.setext.texteditorbase;bundle-version="0.10.0",
  org.eclipse.ui.ide;bundle-version="3.18.200",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0"
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0"
 Export-Package: org.eclipse.escet.cif.texteditor
 Automatic-Module-Name: org.eclipse.escet.cif.texteditor
diff --git a/cif/org.eclipse.escet.cif.tooldefs/.settings/org.eclipse.jdt.core.prefs b/cif/org.eclipse.escet.cif.tooldefs/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/cif/org.eclipse.escet.cif.tooldefs/.settings/org.eclipse.jdt.core.prefs
+++ b/cif/org.eclipse.escet.cif.tooldefs/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/cif/org.eclipse.escet.cif.tooldefs/.settings/org.eclipse.jdt.ui.prefs b/cif/org.eclipse.escet.cif.tooldefs/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/cif/org.eclipse.escet.cif.tooldefs/.settings/org.eclipse.jdt.ui.prefs
+++ b/cif/org.eclipse.escet.cif.tooldefs/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/cif/org.eclipse.escet.cif.tooldefs/.settings/org.eclipse.ltk.core.refactoring.prefs b/cif/org.eclipse.escet.cif.tooldefs/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.tooldefs/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/cif/org.eclipse.escet.cif.tooldefs/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.tooldefs/META-INF/MANIFEST.MF
index ea7ff8304708eccdf9bc709de79ef0a0772be850..c1bccd6cbc2f09d73b3891221d63429bf0c59224 100644
--- a/cif/org.eclipse.escet.cif.tooldefs/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.tooldefs/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET CIF ToolDefs (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.cif.tooldefs;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
diff --git a/cif/org.eclipse.escet.cif.typechecker/.settings/org.eclipse.jdt.core.prefs b/cif/org.eclipse.escet.cif.typechecker/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/cif/org.eclipse.escet.cif.typechecker/.settings/org.eclipse.jdt.core.prefs
+++ b/cif/org.eclipse.escet.cif.typechecker/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/cif/org.eclipse.escet.cif.typechecker/.settings/org.eclipse.jdt.ui.prefs b/cif/org.eclipse.escet.cif.typechecker/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/cif/org.eclipse.escet.cif.typechecker/.settings/org.eclipse.jdt.ui.prefs
+++ b/cif/org.eclipse.escet.cif.typechecker/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/cif/org.eclipse.escet.cif.typechecker/.settings/org.eclipse.ltk.core.refactoring.prefs b/cif/org.eclipse.escet.cif.typechecker/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/cif/org.eclipse.escet.cif.typechecker/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/cif/org.eclipse.escet.cif.typechecker/META-INF/MANIFEST.MF b/cif/org.eclipse.escet.cif.typechecker/META-INF/MANIFEST.MF
index e36bc79ede1b55bbbe198ee4db4b51aebe6c6efc..cf022cef4317f2496001541addcb32c9fb99b2c9 100644
--- a/cif/org.eclipse.escet.cif.typechecker/META-INF/MANIFEST.MF
+++ b/cif/org.eclipse.escet.cif.typechecker/META-INF/MANIFEST.MF
@@ -2,24 +2,24 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET CIF Type Checker (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.cif.typechecker;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.cif.common;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.cif.parser;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.cif.metamodel.java;bundle-version="0.9.0",
- org.eclipse.escet.common.box;bundle-version="0.9.0",
- org.eclipse.escet.common.emf;bundle-version="0.9.0",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.cif.common;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.cif.parser;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.cif.metamodel.java;bundle-version="0.10.0",
+ org.eclipse.escet.common.box;bundle-version="0.10.0",
+ org.eclipse.escet.common.emf;bundle-version="0.10.0",
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
  org.apache.commons.lang3;bundle-version="3.1.0",
- org.eclipse.escet.cif.cif2cif;bundle-version="0.9.0",
- org.eclipse.escet.common.position.common;bundle-version="0.9.0",
- org.eclipse.escet.common.svg;bundle-version="0.9.0"
+ org.eclipse.escet.cif.cif2cif;bundle-version="0.10.0",
+ org.eclipse.escet.common.position.common;bundle-version="0.10.0",
+ org.eclipse.escet.common.svg;bundle-version="0.10.0"
 Export-Package: org.eclipse.escet.cif.typechecker,
  org.eclipse.escet.cif.typechecker.declwrap,
  org.eclipse.escet.cif.typechecker.postchk,
diff --git a/cif/org.eclipse.escet.cif.typechecker/src/org/eclipse/escet/cif/typechecker/CifExprsTypeChecker.java b/cif/org.eclipse.escet.cif.typechecker/src/org/eclipse/escet/cif/typechecker/CifExprsTypeChecker.java
index d7bc6434400aaab8cd70bb02c02ddec8cf25cf16..5ed31285e971aad9f80f017d4823d2e3f9c94847 100644
--- a/cif/org.eclipse.escet.cif.typechecker/src/org/eclipse/escet/cif/typechecker/CifExprsTypeChecker.java
+++ b/cif/org.eclipse.escet.cif.typechecker/src/org/eclipse/escet/cif/typechecker/CifExprsTypeChecker.java
@@ -74,6 +74,7 @@ import static org.eclipse.escet.common.java.Lists.listc;
 import static org.eclipse.escet.common.java.Maps.map;
 import static org.eclipse.escet.common.java.Pair.pair;
 import static org.eclipse.escet.common.java.Sets.list2set;
+import static org.eclipse.escet.common.java.Sets.setc;
 import static org.eclipse.escet.common.java.Strings.str;
 import static org.eclipse.escet.common.position.common.PositionUtils.copyPosition;
 
@@ -4535,11 +4536,8 @@ public class CifExprsTypeChecker {
             // Check for incomplete/overspecified locations.
             checkSwitchLocsComplete(rslt, scope, tchecker);
         } else {
-            // Check for missing 'else'.
-            if (last(cases).getKey() != null) {
-                tchecker.addProblem(ErrMsg.SWITCH_MISSING_ELSE, expr.position);
-                throw new SemanticException();
-            }
+            // Check for incomplete/overspecified values.
+            checkSwitchValuesComplete(rslt, scope, tchecker);
         }
 
         // Compute type for the 'switch' expression. If we don't merge, we need
@@ -4871,8 +4869,8 @@ public class CifExprsTypeChecker {
                 Position prevPos = done.get(loc);
                 if (prevPos != null) {
                     // Duplicate location.
-                    tchecker.addProblem(ErrMsg.SWITCH_AUT_DUPL_LOC, locRef.getPosition(), getAbsName(loc));
-                    tchecker.addProblem(ErrMsg.SWITCH_AUT_DUPL_LOC, prevPos, getAbsName(loc));
+                    tchecker.addProblem(ErrMsg.SWITCH_DUPL_CASE, locRef.getPosition(), "location", getAbsName(loc));
+                    tchecker.addProblem(ErrMsg.SWITCH_DUPL_CASE, prevPos, "location", getAbsName(loc));
                     throw new SemanticException();
                 } else {
                     // New location.
@@ -4891,7 +4889,7 @@ public class CifExprsTypeChecker {
                 // only specify 'else'. As such, we either have an error, or no
                 // missing locations. As such, in case we have an error, the
                 // location will have a name.
-                tchecker.addProblem(ErrMsg.SWITCH_AUT_MISSING_LOC, switchExpr.getPosition(), getAbsName(loc));
+                tchecker.addProblem(ErrMsg.SWITCH_MISSING_CASE, switchExpr.getPosition(), "location", getAbsName(loc));
             }
             throw new SemanticException();
         }
@@ -4903,11 +4901,129 @@ public class CifExprsTypeChecker {
         // 'else'.
         if (todo.isEmpty() && !aut.getLocations().isEmpty() && elsePos != null) {
             // Overspecified.
-            tchecker.addProblem(ErrMsg.SWITCH_AUT_SUPERFLUOUS_ELSE, elsePos);
+            tchecker.addProblem(ErrMsg.SWITCH_SUPERFLUOUS_ELSE, elsePos, "locations");
             // Non-fatal problem.
         }
     }
 
+    /**
+     * Type check a 'switch' expression on anything but an automaton reference, for completeness of the values. Also
+     * checks for overspecified cases.
+     *
+     * @param switchExpr The expression to check. Must not have an automaton reference (including 'self') as value.
+     * @param scope The scope to resolve references in.
+     * @param tchecker The CIF type checker to use.
+     */
+    private static void checkSwitchValuesComplete(SwitchExpression switchExpr, SymbolScope<?> scope,
+            CifTypeChecker tchecker)
+    {
+        // Determine whether we can check the completeness in full, namely whether 1) the type of the switch value has
+        // a (practically) finite number of values, and 2) all case keys are statically evaluable. Otherwise, we require
+        // an 'else' to be present.
+        boolean checkInFull = true;
+        CifType type = switchExpr.getValue().getType();
+        double nrOfPossibleValuesDouble = CifValueUtils.getPossibleValueCount(type);
+        if (nrOfPossibleValuesDouble > Integer.MAX_VALUE) {
+            checkInFull = false;
+        } else {
+            for (SwitchCase switchCase: switchExpr.getCases()) {
+                if (switchCase.getKey() == null) {
+                    continue; // An 'else' case doesn't have a value.
+                }
+                if (!checkStaticEvaluable(switchCase.getKey(), null)) {
+                    checkInFull = false;
+                    break;
+                }
+            }
+        }
+
+        // Handle not checking in full. Requires an 'else' to be present to ensure it is complete.
+        if (!checkInFull) {
+            if (last(switchExpr.getCases()).getKey() != null) {
+                tchecker.addProblem(ErrMsg.SWITCH_MISSING_ELSE, switchExpr.getPosition());
+                throw new SemanticException();
+            }
+            return;
+        }
+
+        // Initialization for checking in full. If many possible values, don't create, nor report, all missing values,
+        // for performance reasons.
+        int nrOfPossibleValues = (int)nrOfPossibleValuesDouble;
+        boolean tooManyPossibleValues = nrOfPossibleValues > 100;
+        Set<Object> todo = tooManyPossibleValues ? null : setc(nrOfPossibleValues);
+        if (todo != null) {
+            for (Expression possibleValue: CifValueUtils.getPossibleValues(type)) {
+                try {
+                    todo.add(CifEvalUtils.eval(possibleValue, false));
+                } catch (CifEvalException e) {
+                    // Runtime evaluation errors don't happen for possible values of a type, as they are all literals.
+                    throw new RuntimeException("Failed to evaluate possible value of a type.", e);
+                }
+            }
+        }
+        Map<Object, Position> foundValues = map();
+        Position elsePos = null;
+
+        // Process all keys of the cases.
+        List<SwitchCase> cases = switchExpr.getCases();
+        for (SwitchCase cse: cases) {
+            Expression keyExpr = cse.getKey();
+            if (keyExpr == null) {
+                // An 'else' case.
+                Assert.check(elsePos == null);
+                elsePos = cse.getPosition();
+            } else {
+                // Evaluate key.
+                Object keyValue;
+                try {
+                    keyValue = CifEvalUtils.eval(keyExpr, false);
+                } catch (CifEvalException e) {
+                    // Problem reported where the actual expression evaluation fails.
+                    tchecker.addProblem(ErrMsg.EVAL_FAILURE, e.expr.getPosition(), e.getMessage());
+                    throw new SemanticException();
+                }
+
+                // Key value is done, so no longer 'todo'.
+                if (todo != null) {
+                    todo.remove(keyValue);
+                }
+
+                // Check for duplicate and add to 'done'.
+                Position prevPos = foundValues.get(keyValue);
+                if (prevPos != null) {
+                    // Duplicate location.
+                    String valueText = CifEvalUtils.objToStr(keyValue);
+                    tchecker.addProblem(ErrMsg.SWITCH_DUPL_CASE, keyExpr.getPosition(), "value", valueText);
+                    tchecker.addProblem(ErrMsg.SWITCH_DUPL_CASE, prevPos, "value", valueText);
+                    throw new SemanticException();
+                } else {
+                    // New key value.
+                    foundValues.put(keyValue, keyExpr.getPosition());
+                }
+            }
+        }
+
+        // Check for incomplete mapping.
+        if (todo != null && !todo.isEmpty() && elsePos == null) {
+            // Incomplete.
+            for (Object value: todo) {
+                tchecker.addProblem(ErrMsg.SWITCH_MISSING_CASE, switchExpr.getPosition(), "value",
+                        CifEvalUtils.objToStr(value));
+            }
+            throw new SemanticException();
+        } else if (todo == null && elsePos == null && foundValues.size() < nrOfPossibleValues) {
+            tchecker.addProblem(ErrMsg.SWITCH_MISSING_CASE_LARGE, switchExpr.getPosition(), "values");
+            throw new SemanticException();
+        }
+
+        // Check for overspecified mapping.
+        if (todo != null && todo.isEmpty() && elsePos != null) {
+            // Overspecified.
+            tchecker.addProblem(ErrMsg.SWITCH_SUPERFLUOUS_ELSE, elsePos, "values");
+            // Non-fatal problem.
+        } // if 'todo == null', we may have case keys outside of the switch value range, so we're not sure.
+    }
+
     /**
      * Get the automaton referred to by an automaton reference.
      *
diff --git a/cif/org.eclipse.escet.cif.typechecker/src/org/eclipse/escet/cif/typechecker/ErrMsg.java b/cif/org.eclipse.escet.cif.typechecker/src/org/eclipse/escet/cif/typechecker/ErrMsg.java
index 4c7fb0d023f6bc830cc8f9772a0b5308edd283c5..31448aedcc5e48437013bc986e2814d501864db2 100644
--- a/cif/org.eclipse.escet.cif.typechecker/src/org/eclipse/escet/cif/typechecker/ErrMsg.java
+++ b/cif/org.eclipse.escet.cif.typechecker/src/org/eclipse/escet/cif/typechecker/ErrMsg.java
@@ -288,7 +288,7 @@ public enum ErrMsg {
     // AST related constraint.
     INV_REF_IN_EXPR("Cannot use \"%s\" as a value, as it is an invariant.", 1, ERROR),
 
-    // Invariant.unique.
+    // Invariant.unique
     INV_DUPL_EVENT("Duplicate invariant for event \"%s\".", 1, WARNING),
 
     // UnaryExpression.type
@@ -389,14 +389,14 @@ public enum ErrMsg {
     SWITCH_MISSING_ELSE("The switch is missing an \"else\".", 0, ERROR),
 
     // SwitchExpression.overspecified
-    SWITCH_AUT_DUPL_LOC("Duplicate switch \"case\" for location \"%s\".", 1, ERROR),
+    SWITCH_DUPL_CASE("Duplicate switch \"case\" for %s \"%s\".", 2, ERROR),
 
     // SwitchExpression.complete
-    SWITCH_AUT_MISSING_LOC("Missing switch \"case\" for location \"%s\".", 1, ERROR),
+    SWITCH_MISSING_CASE("Missing switch \"case\" for %s \"%s\".", 2, ERROR),
+    SWITCH_MISSING_CASE_LARGE("Missing switch \"case\" for some %s.", 1, ERROR),
 
     // SwitchExpression.superfluousElse
-    SWITCH_AUT_SUPERFLUOUS_ELSE("Switch \"else\" is superfluous, as all locations already have a \"case\".", 0,
-            WARNING),
+    SWITCH_SUPERFLUOUS_ELSE("Switch \"else\" is superfluous, as all %s already have a \"case\".", 1, WARNING),
 
     // ListExpression.type
     // SetExpression.type
diff --git a/common/org.eclipse.escet.common.app.framework.appsview.ui/.settings/org.eclipse.jdt.core.prefs b/common/org.eclipse.escet.common.app.framework.appsview.ui/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/common/org.eclipse.escet.common.app.framework.appsview.ui/.settings/org.eclipse.jdt.core.prefs
+++ b/common/org.eclipse.escet.common.app.framework.appsview.ui/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/common/org.eclipse.escet.common.app.framework.appsview.ui/.settings/org.eclipse.jdt.ui.prefs b/common/org.eclipse.escet.common.app.framework.appsview.ui/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/common/org.eclipse.escet.common.app.framework.appsview.ui/.settings/org.eclipse.jdt.ui.prefs
+++ b/common/org.eclipse.escet.common.app.framework.appsview.ui/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/common/org.eclipse.escet.common.app.framework.appsview.ui/.settings/org.eclipse.ltk.core.refactoring.prefs b/common/org.eclipse.escet.common.app.framework.appsview.ui/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/common/org.eclipse.escet.common.app.framework.appsview.ui/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/common/org.eclipse.escet.common.app.framework.appsview.ui/META-INF/MANIFEST.MF b/common/org.eclipse.escet.common.app.framework.appsview.ui/META-INF/MANIFEST.MF
index be95e21a1e16b7cc7e4bcf31a34fa9b99445d3d8..9f91a451aa339374d5aa6dee09bb5f99d025b5da 100644
--- a/common/org.eclipse.escet.common.app.framework.appsview.ui/META-INF/MANIFEST.MF
+++ b/common/org.eclipse.escet.common.app.framework.appsview.ui/META-INF/MANIFEST.MF
@@ -2,10 +2,10 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Common Application Framework Apps View (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.common.app.framework.appsview.ui;singleton:=true
-Bundle-Version: 0.9.0.qualifier
-Require-Bundle: org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.common.eclipse.ui;bundle-version="0.9.0",
+Bundle-Version: 0.10.0.qualifier
+Require-Bundle: org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.common.eclipse.ui;bundle-version="0.10.0",
  org.eclipse.e4.core.di;bundle-version="1.7.500",
  org.eclipse.e4.ui.model.workbench;bundle-version="2.1.600",
  org.eclipse.e4.ui.di;bundle-version="1.2.700",
diff --git a/common/org.eclipse.escet.common.app.framework.tests/.settings/org.eclipse.jdt.core.prefs b/common/org.eclipse.escet.common.app.framework.tests/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/common/org.eclipse.escet.common.app.framework.tests/.settings/org.eclipse.jdt.core.prefs
+++ b/common/org.eclipse.escet.common.app.framework.tests/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/common/org.eclipse.escet.common.app.framework.tests/.settings/org.eclipse.jdt.ui.prefs b/common/org.eclipse.escet.common.app.framework.tests/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/common/org.eclipse.escet.common.app.framework.tests/.settings/org.eclipse.jdt.ui.prefs
+++ b/common/org.eclipse.escet.common.app.framework.tests/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/common/org.eclipse.escet.common.app.framework.tests/.settings/org.eclipse.ltk.core.refactoring.prefs b/common/org.eclipse.escet.common.app.framework.tests/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/common/org.eclipse.escet.common.app.framework.tests/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/common/org.eclipse.escet.common.app.framework.tests/META-INF/MANIFEST.MF b/common/org.eclipse.escet.common.app.framework.tests/META-INF/MANIFEST.MF
index 222fa164458995f2bf10853a54977ea4a4c9da6b..f658854bd1bff7059202db96f56621cd402f3219 100644
--- a/common/org.eclipse.escet.common.app.framework.tests/META-INF/MANIFEST.MF
+++ b/common/org.eclipse.escet.common.app.framework.tests/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Common Application Framework Tests (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.common.app.framework.tests;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
diff --git a/common/org.eclipse.escet.common.app.framework/.settings/org.eclipse.jdt.core.prefs b/common/org.eclipse.escet.common.app.framework/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/common/org.eclipse.escet.common.app.framework/.settings/org.eclipse.jdt.core.prefs
+++ b/common/org.eclipse.escet.common.app.framework/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/common/org.eclipse.escet.common.app.framework/.settings/org.eclipse.jdt.ui.prefs b/common/org.eclipse.escet.common.app.framework/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/common/org.eclipse.escet.common.app.framework/.settings/org.eclipse.jdt.ui.prefs
+++ b/common/org.eclipse.escet.common.app.framework/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/common/org.eclipse.escet.common.app.framework/.settings/org.eclipse.ltk.core.refactoring.prefs b/common/org.eclipse.escet.common.app.framework/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/common/org.eclipse.escet.common.app.framework/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/common/org.eclipse.escet.common.app.framework/META-INF/MANIFEST.MF b/common/org.eclipse.escet.common.app.framework/META-INF/MANIFEST.MF
index 15280f4fc5f9293f561dc0a55f1855b9053b2446..e4a552f2186d7d24368a4f6e1b7b05ae7632baa6 100644
--- a/common/org.eclipse.escet.common.app.framework/META-INF/MANIFEST.MF
+++ b/common/org.eclipse.escet.common.app.framework/META-INF/MANIFEST.MF
@@ -2,11 +2,11 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Common Application Framework (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.common.app.framework;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.common.java;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.common.java;bundle-version="0.10.0",
  org.eclipse.swt;bundle-version="3.113.0";visibility:=reexport,
  org.eclipse.core.runtime;bundle-version="3.17.0",
  org.eclipse.core.resources;bundle-version="3.13.600",
diff --git a/common/org.eclipse.escet.common.app.framework/src/org/eclipse/escet/common/app/framework/Application.java b/common/org.eclipse.escet.common.app.framework/src/org/eclipse/escet/common/app/framework/Application.java
index b8d34eaf998105dbb10cf824c5ff8c7d1ca26830..df819ef3ab45d053d8ffa38858d8f65c2f2f96ed 100644
--- a/common/org.eclipse.escet.common.app.framework/src/org/eclipse/escet/common/app/framework/Application.java
+++ b/common/org.eclipse.escet.common.app.framework/src/org/eclipse/escet/common/app/framework/Application.java
@@ -637,9 +637,19 @@ public abstract class Application<T extends IOutputComponent> {
      */
     public void printHelpMessage(AppStream s) {
         printHelpHeader(s);
+
+        s.println();
         printHelpOptions(s);
-        printHelpNotes(s);
+
+        if (getHelpMessageNotes().length > 0) {
+            s.println();
+            printHelpNotes(s);
+        }
+
+        s.println();
         printHelpExitCodes(s);
+
+        s.println();
         printHelpCopyright(s);
     }
 
@@ -789,7 +799,7 @@ public abstract class Application<T extends IOutputComponent> {
     public String getCrashReportIssueReportingInstructions() {
         return "Issues can be reported using the Eclipse ESCET issue tracker, at "
                 + "https://gitlab.eclipse.org/eclipse/escet/escet/-/issues. For more information, see "
-                + "https://eclipse.org/escet/contact-and-support.html. This crash report "
+                + "https://eclipse.dev/escet/contact-and-support.html. This crash report "
                 + "contains valuable information that you can include in your bug report, to make it easier for the "
                 + "bug to be fixed. We appreciate you taking the effort to report issues to us!";
     }
diff --git a/common/org.eclipse.escet.common.app.framework/src/org/eclipse/escet/common/app/framework/eclipse/themes/EclipseThemePreferenceChangeListener.java b/common/org.eclipse.escet.common.app.framework/src/org/eclipse/escet/common/app/framework/eclipse/themes/EclipseThemePreferenceChangeListener.java
index e7120049eb5096ab06e7e49e81485f312e2189d2..637ded954378c179498af37e95979628b0d8ff7a 100644
--- a/common/org.eclipse.escet.common.app.framework/src/org/eclipse/escet/common/app/framework/eclipse/themes/EclipseThemePreferenceChangeListener.java
+++ b/common/org.eclipse.escet.common.app.framework/src/org/eclipse/escet/common/app/framework/eclipse/themes/EclipseThemePreferenceChangeListener.java
@@ -17,6 +17,7 @@ import java.util.function.Consumer;
 
 import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
 import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
+import org.eclipse.ui.PlatformUI;
 
 /** Eclipse theme preference change listener. */
 public class EclipseThemePreferenceChangeListener implements IPreferenceChangeListener {
@@ -45,13 +46,29 @@ public class EclipseThemePreferenceChangeListener implements IPreferenceChangeLi
         }
     }
 
-    /** Registers this Eclipse theme preference change listener. */
+    /**
+     * Registers this Eclipse theme preference change listener.
+     *
+     * <p>
+     * For stand-alone (no workspace) executions, this call has no effect (retheming is not supported).
+     * </p>
+     */
     private void register() {
-        EclipseThemeUtils.getEclipseThemePreferences().addPreferenceChangeListener(this);
+        if (PlatformUI.isWorkbenchRunning()) {
+            EclipseThemeUtils.getEclipseThemePreferences().addPreferenceChangeListener(this);
+        }
     }
 
-    /** Unregisters this Eclipse theme preference change listener. */
+    /**
+     * Unregisters this Eclipse theme preference change listener.
+     *
+     * <p>
+     * For stand-alone (no workspace) executions, this call has no effect (retheming is not supported).
+     * </p>
+     */
     public void unregister() {
-        EclipseThemeUtils.getEclipseThemePreferences().removePreferenceChangeListener(this);
+        if (PlatformUI.isWorkbenchRunning()) {
+            EclipseThemeUtils.getEclipseThemePreferences().removePreferenceChangeListener(this);
+        }
     }
 }
diff --git a/common/org.eclipse.escet.common.app.framework/src/org/eclipse/escet/common/app/framework/eclipse/themes/EclipseThemeUtils.java b/common/org.eclipse.escet.common.app.framework/src/org/eclipse/escet/common/app/framework/eclipse/themes/EclipseThemeUtils.java
index 41deebe6eb0708a0ef246bc8360fa20749dfa07c..d40a7d367e53095defccd0410c69b20421e9c63a 100644
--- a/common/org.eclipse.escet.common.app.framework/src/org/eclipse/escet/common/app/framework/eclipse/themes/EclipseThemeUtils.java
+++ b/common/org.eclipse.escet.common.app.framework/src/org/eclipse/escet/common/app/framework/eclipse/themes/EclipseThemeUtils.java
@@ -13,11 +13,13 @@
 
 package org.eclipse.escet.common.app.framework.eclipse.themes;
 
+import org.apache.commons.lang3.SystemUtils;
 import org.eclipse.core.runtime.preferences.IEclipsePreferences;
 import org.eclipse.core.runtime.preferences.InstanceScope;
 import org.eclipse.e4.ui.css.swt.internal.theme.ThemeEngine;
 import org.eclipse.e4.ui.css.swt.theme.ITheme;
 import org.eclipse.e4.ui.css.swt.theme.IThemeEngine;
+import org.eclipse.swt.widgets.Display;
 import org.eclipse.ui.PlatformUI;
 
 /** Eclipse theme utility methods. */
@@ -39,12 +41,20 @@ public class EclipseThemeUtils {
      * @return {@code true} if the current Eclipse theme is a dark theme, {@code false} otherwise.
      */
     public static boolean isDarkThemeInUse() {
-        // This method uses internal Eclipse APIs to prevent hardcoding the theme id. This way, if the theme id changes,
-        // or is removed, we should get a compile error, and we know something is broken. Otherwise, it would just never
-        // detect a dark theme.
-        IThemeEngine themeEngine = PlatformUI.getWorkbench().getService(IThemeEngine.class);
-        ITheme theme = themeEngine.getActiveTheme();
-        return theme != null && theme.getId().equals(ThemeEngine.E4_DARK_THEME_ID);
+        if (PlatformUI.isWorkbenchRunning()) {
+            // This method uses internal Eclipse APIs to prevent hardcoding the theme id. This way, if the theme id
+            // changes, or is removed, we should get a compile error, and we know something is broken. Otherwise, it
+            // would just never detect a dark theme.
+            IThemeEngine themeEngine = PlatformUI.getWorkbench().getService(IThemeEngine.class);
+            ITheme theme = themeEngine.getActiveTheme();
+            return theme != null && theme.getId().equals(ThemeEngine.E4_DARK_THEME_ID);
+        } else if (SystemUtils.IS_OS_WINDOWS) {
+            // In stand-alone mode on Windows, SWT is always light-mode.
+            return false;
+        } else {
+            // Running stand-alone on macOS or Linux, SWT colors depend on the system-mode.
+            return Display.isSystemDarkTheme();
+        }
     }
 
     /**
diff --git a/common/org.eclipse.escet.common.app.framework/src/org/eclipse/escet/common/app/framework/io/AppStream.java b/common/org.eclipse.escet.common.app.framework/src/org/eclipse/escet/common/app/framework/io/AppStream.java
index 5f709f2ad0e025bfce2355db08cfee0402b9f8cb..b46812ae1089b55046fcb4f448acc05d46ba4ec3 100644
--- a/common/org.eclipse.escet.common.app.framework/src/org/eclipse/escet/common/app/framework/io/AppStream.java
+++ b/common/org.eclipse.escet.common.app.framework/src/org/eclipse/escet/common/app/framework/io/AppStream.java
@@ -66,6 +66,15 @@ public abstract class AppStream implements Closeable {
     /** Whether a {@code '\r'} character was detected before checking for a {@code '\n'} character. */
     private boolean seenCR = false;
 
+    /**
+     * Returns the character set to use to encode strings to bytes.
+     *
+     * @return The character set.
+     */
+    public Charset getCharset() {
+        return charset;
+    }
+
     /**
      * Set the 'convert new lines' property of the stream. If enabled, EOL sequences are converted to platform specific
      * or custom new line sequences set by the 'new line bytes' property. If disabled, EOL sequences in the stream are
@@ -90,6 +99,7 @@ public abstract class AppStream implements Closeable {
      *
      * @return {@code true} if the property is enabled, {@code false} otherwise.
      * @see #setConvertNewLines
+     * @see #setPlatformNewLineBytes
      * @see #setUnixNewLineBytes
      * @see #setWindowsNewLineBytes
      * @see #setNewLineBytes
@@ -110,6 +120,7 @@ public abstract class AppStream implements Closeable {
      * @param bytes The new line bytes to use.
      * @see #setConvertNewLines
      * @see #getConvertNewLines
+     * @see #setPlatformNewLineBytes
      * @see #setUnixNewLineBytes
      * @see #setWindowsNewLineBytes
      * @see #getNewLineBytes
@@ -120,6 +131,24 @@ public abstract class AppStream implements Closeable {
         }
     }
 
+    /**
+     * Set the 'new line bytes' property of the stream to use the new line bytes of the current platform. The
+     * platform-specific new line bytes are used when an EOL sequence is to be written and the 'convert new lines'
+     * property is enabled. They are also written when {@link #newline} is called.
+     *
+     * @see #setConvertNewLines
+     * @see #getConvertNewLines
+     * @see #setUnixNewLineBytes
+     * @see #setWindowsNewLineBytes
+     * @see #setNewLineBytes
+     * @see #getNewLineBytes
+     */
+    public void setPlatformNewLineBytes() {
+        synchronized (this) {
+            this.newline = Strings.NL.getBytes(charset);
+        }
+    }
+
     /**
      * Set the 'new line bytes' property of the stream to use Unix new line bytes. Unix new line bytes ('\n') are used
      * when an EOL sequence is to be written and the 'convert new lines' property is enabled. They are also written when
@@ -127,6 +156,7 @@ public abstract class AppStream implements Closeable {
      *
      * @see #setConvertNewLines
      * @see #getConvertNewLines
+     * @see #setPlatformNewLineBytes
      * @see #setWindowsNewLineBytes
      * @see #setNewLineBytes
      * @see #getNewLineBytes
@@ -144,6 +174,7 @@ public abstract class AppStream implements Closeable {
      *
      * @see #setConvertNewLines
      * @see #getConvertNewLines
+     * @see #setPlatformNewLineBytes
      * @see #setUnixNewLineBytes
      * @see #setNewLineBytes
      * @see #getNewLineBytes
@@ -163,6 +194,7 @@ public abstract class AppStream implements Closeable {
      * @return The new line bytes being used.
      * @see #setConvertNewLines
      * @see #getConvertNewLines
+     * @see #setPlatformNewLineBytes
      * @see #setUnixNewLineBytes
      * @see #setWindowsNewLineBytes
      * @see #setNewLineBytes
diff --git a/common/org.eclipse.escet.common.app.framework/src/org/eclipse/escet/common/app/framework/options/HelpOption.java b/common/org.eclipse.escet.common.app.framework/src/org/eclipse/escet/common/app/framework/options/HelpOption.java
index 267f9eaf5b90f90c522cafc9c5584610ea26f0a1..bfd158649eaf35dfbef82655c81efdd2731d99c4 100644
--- a/common/org.eclipse.escet.common.app.framework/src/org/eclipse/escet/common/app/framework/options/HelpOption.java
+++ b/common/org.eclipse.escet.common.app.framework/src/org/eclipse/escet/common/app/framework/options/HelpOption.java
@@ -70,7 +70,6 @@ public class HelpOption extends BooleanOption {
         outw(s, msg);
         s.println();
         outw(s, description);
-        s.println();
     }
 
     /**
@@ -135,24 +134,20 @@ public class HelpOption extends BooleanOption {
 
         outw(s, "The following values can be used to enable any boolean option (BOOL): \"on\", \"true\", \"yes\", "
                 + "and \"1\". The corresponding values to disable are: \"off\", \"false\", \"no\", and \"0\".");
-        s.println();
     }
 
     /**
      * Prints the help message notes of an application to the given stream.
      *
-     * @param notes The help message notes of the application, if any.
+     * @param notes The help message notes of the application. Must not be empty.
      * @param s The stream to print the output to.
      */
     public static void printHelpNotes(String[] notes, AppStream s) {
-        if (notes.length == 0) {
-            return;
-        }
+        Assert.check(notes.length > 0);
         s.println("Notes:");
         for (String note: notes) {
             s.println(wrapEx(" - ", "   ", note));
         }
-        s.println();
     }
 
     /**
@@ -172,7 +167,6 @@ public class HelpOption extends BooleanOption {
         for (int i = 0; i < lines.length; i++) {
             s.println(wrapEx(spaces(2) + i + spaces(2), spaces(5), lines[i]));
         }
-        s.println();
     }
 
     /**
@@ -223,7 +217,7 @@ public class HelpOption extends BooleanOption {
      * @param msg The 'normal' output (pattern) to wrap and forward.
      * @param args The arguments of the 'normal' output pattern.
      */
-    private static void outw(AppStream s, String msg, Object... args) {
+    public static void outw(AppStream s, String msg, Object... args) {
         for (String txt: wrap(fmt(msg, args))) {
             s.println(txt);
         }
diff --git a/common/org.eclipse.escet.common.app.framework/src/org/eclipse/escet/common/app/framework/options/OptionCategory.java b/common/org.eclipse.escet.common.app.framework/src/org/eclipse/escet/common/app/framework/options/OptionCategory.java
index d99d9144d09309443f93705a7a0254ac2cb50aca..8a33a3e472eb20a8ee3dfe2a827b1b6e7ea5fa44 100644
--- a/common/org.eclipse.escet.common.app.framework/src/org/eclipse/escet/common/app/framework/options/OptionCategory.java
+++ b/common/org.eclipse.escet.common.app.framework/src/org/eclipse/escet/common/app/framework/options/OptionCategory.java
@@ -169,8 +169,7 @@ public class OptionCategory {
      *
      * @return The options that are part of this option category, not including any options from sub-categories.
      */
-    @SuppressWarnings("rawtypes")
-    public List<Option> getOptions() {
+    public List<Option<?>> getOptions() {
         return Collections.unmodifiableList(options);
     }
 
diff --git a/common/org.eclipse.escet.common.app.framework/src/org/eclipse/escet/common/app/framework/options/OptionDialog.java b/common/org.eclipse.escet.common.app.framework/src/org/eclipse/escet/common/app/framework/options/OptionDialog.java
index 1c431228d731c5c75bcd6093fa74191cf161e3b7..5affa69cfb1a22b3bcb570b838f0e0774a98cb5b 100644
--- a/common/org.eclipse.escet.common.app.framework/src/org/eclipse/escet/common/app/framework/options/OptionDialog.java
+++ b/common/org.eclipse.escet.common.app.framework/src/org/eclipse/escet/common/app/framework/options/OptionDialog.java
@@ -503,7 +503,11 @@ public class OptionDialog implements Runnable {
         // Set the text.
         MemAppStream helpStream = new MemAppStream();
         AppEnv.getApplication().printHelpHeader(helpStream);
-        AppEnv.getApplication().printHelpNotes(helpStream);
+        if (AppEnv.getApplication().getHelpMessageNotes().length > 0) {
+            helpStream.println();
+            AppEnv.getApplication().printHelpNotes(helpStream);
+        }
+        helpStream.println();
         AppEnv.getApplication().printHelpCopyright(helpStream);
         txt.setText(helpStream.toString());
 
@@ -543,8 +547,11 @@ public class OptionDialog implements Runnable {
         // Set the text.
         MemAppStream helpStream = new MemAppStream();
         AppEnv.getApplication().printHelpHeader(helpStream);
+        helpStream.println();
         AppEnv.getApplication().printHelpOptions(helpStream);
+        helpStream.println();
         AppEnv.getApplication().printHelpExitCodes(helpStream);
+        helpStream.println();
         AppEnv.getApplication().printHelpCopyright(helpStream);
         txt.setText(helpStream.toString());
 
diff --git a/common/org.eclipse.escet.common.asciidoc/.settings/org.eclipse.jdt.core.prefs b/common/org.eclipse.escet.common.asciidoc/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/common/org.eclipse.escet.common.asciidoc/.settings/org.eclipse.jdt.core.prefs
+++ b/common/org.eclipse.escet.common.asciidoc/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/common/org.eclipse.escet.common.asciidoc/.settings/org.eclipse.jdt.ui.prefs b/common/org.eclipse.escet.common.asciidoc/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/common/org.eclipse.escet.common.asciidoc/.settings/org.eclipse.jdt.ui.prefs
+++ b/common/org.eclipse.escet.common.asciidoc/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/common/org.eclipse.escet.common.asciidoc/.settings/org.eclipse.ltk.core.refactoring.prefs b/common/org.eclipse.escet.common.asciidoc/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/common/org.eclipse.escet.common.asciidoc/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/common/org.eclipse.escet.common.asciidoc/pom.xml b/common/org.eclipse.escet.common.asciidoc/pom.xml
index 558f74f0c86080198d2a8c25370c6364dd2fa3e6..b0291d19dd85909aa54bf9aa83c29e7839123586 100644
--- a/common/org.eclipse.escet.common.asciidoc/pom.xml
+++ b/common/org.eclipse.escet.common.asciidoc/pom.xml
@@ -16,7 +16,7 @@
     <parent>
         <groupId>org.eclipse.escet</groupId>
         <artifactId>org.eclipse.escet.root</artifactId>
-        <version>0.9.0-SNAPSHOT</version>
+        <version>0.10.0-SNAPSHOT</version>
         <relativePath>../../</relativePath>
     </parent>
 
@@ -27,7 +27,7 @@
         <dependency>
             <groupId>com.google.guava</groupId>
             <artifactId>guava</artifactId>
-            <version>30.1-jre</version>
+            <version>31.1-jre</version>
         </dependency>
         <dependency>
             <groupId>commons-io</groupId>
@@ -42,24 +42,56 @@
         <dependency>
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-lang3</artifactId>
-            <version>3.1</version>
+            <version>3.12.0</version>
         </dependency>
         <dependency>
             <groupId>org.apache.maven</groupId>
             <artifactId>maven-plugin-api</artifactId>
-            <version>3.8.5</version>
+            <version>3.8.7</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>org.apache.maven.plugin-tools</groupId>
             <artifactId>maven-plugin-annotations</artifactId>
-            <version>3.6.4</version>
+            <version>3.8.2</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>org.jsoup</groupId>
             <artifactId>jsoup</artifactId>
-            <version>1.8.3</version>
+            <version>1.15.3</version>
         </dependency>
     </dependencies>
+
+    <build>
+        <pluginManagement>
+            <plugins>
+                <!-- Eclipse M2E lifecycle mappings. Does not influence the Maven build itself. -->
+                <plugin>
+                    <groupId>org.eclipse.m2e</groupId>
+                    <artifactId>lifecycle-mapping</artifactId>
+                    <version>1.0.0</version>
+                    <configuration>
+                        <lifecycleMappingMetadata>
+                            <pluginExecutions>
+                                <pluginExecution>
+                                    <pluginExecutionFilter>
+                                        <groupId>org.apache.maven.plugins</groupId>
+                                        <artifactId>maven-checkstyle-plugin</artifactId>
+                                        <versionRange>1.0.0</versionRange>
+                                        <goals>
+                                            <goal>check</goal>
+                                        </goals>
+                                    </pluginExecutionFilter>
+                                    <action>
+                                        <ignore></ignore>
+                                    </action>
+                                </pluginExecution>
+                            </pluginExecutions>
+                        </lifecycleMappingMetadata>
+                    </configuration>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
 </project>
diff --git a/common/org.eclipse.escet.common.box/.settings/org.eclipse.jdt.core.prefs b/common/org.eclipse.escet.common.box/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/common/org.eclipse.escet.common.box/.settings/org.eclipse.jdt.core.prefs
+++ b/common/org.eclipse.escet.common.box/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/common/org.eclipse.escet.common.box/.settings/org.eclipse.jdt.ui.prefs b/common/org.eclipse.escet.common.box/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/common/org.eclipse.escet.common.box/.settings/org.eclipse.jdt.ui.prefs
+++ b/common/org.eclipse.escet.common.box/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/common/org.eclipse.escet.common.box/.settings/org.eclipse.ltk.core.refactoring.prefs b/common/org.eclipse.escet.common.box/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/common/org.eclipse.escet.common.box/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/common/org.eclipse.escet.common.box/META-INF/MANIFEST.MF b/common/org.eclipse.escet.common.box/META-INF/MANIFEST.MF
index 19ce0ae7be3b71c2f086b26e373accf5021f057c..11d476c40c45b14667f573c5714bf9b9c38324d3 100644
--- a/common/org.eclipse.escet.common.box/META-INF/MANIFEST.MF
+++ b/common/org.eclipse.escet.common.box/META-INF/MANIFEST.MF
@@ -2,12 +2,12 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Common Box Language (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.common.box;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
 Export-Package: org.eclipse.escet.common.box
-Require-Bundle: org.eclipse.escet.common.java;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.common.java;bundle-version="0.10.0",
  org.apache.commons.lang3;bundle-version="3.1.0",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0"
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0"
 Automatic-Module-Name: org.eclipse.escet.common.box
diff --git a/common/org.eclipse.escet.common.dsm.app/.settings/org.eclipse.jdt.core.prefs b/common/org.eclipse.escet.common.dsm.app/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/common/org.eclipse.escet.common.dsm.app/.settings/org.eclipse.jdt.core.prefs
+++ b/common/org.eclipse.escet.common.dsm.app/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/common/org.eclipse.escet.common.dsm.app/.settings/org.eclipse.jdt.ui.prefs b/common/org.eclipse.escet.common.dsm.app/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/common/org.eclipse.escet.common.dsm.app/.settings/org.eclipse.jdt.ui.prefs
+++ b/common/org.eclipse.escet.common.dsm.app/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/common/org.eclipse.escet.common.dsm.app/.settings/org.eclipse.ltk.core.refactoring.prefs b/common/org.eclipse.escet.common.dsm.app/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/common/org.eclipse.escet.common.dsm.app/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/common/org.eclipse.escet.common.dsm.app/META-INF/MANIFEST.MF b/common/org.eclipse.escet.common.dsm.app/META-INF/MANIFEST.MF
index ee730274a29142f3f5d47b0d3d895ae3adb082be..ed5c3f8b188e52e0c4ccf3b5875268012244183d 100644
--- a/common/org.eclipse.escet.common.dsm.app/META-INF/MANIFEST.MF
+++ b/common/org.eclipse.escet.common.dsm.app/META-INF/MANIFEST.MF
@@ -2,16 +2,16 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Common Design Structure Matrix Application (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.common.dsm.app;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Automatic-Module-Name: org.eclipse.escet.common.dsm.app
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.common.dsm;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.common.dsm;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
  org.apache.commons.math3;bundle-version="3.6.1",
  org.eclipse.core.resources;bundle-version="3.15.0",
- org.eclipse.escet.common.eclipse.ui;bundle-version="0.9.0",
+ org.eclipse.escet.common.eclipse.ui;bundle-version="0.10.0",
  org.eclipse.ui.editors;bundle-version="3.14.100"
 Export-Package: org.eclipse.escet.common.dsm.app
diff --git a/common/org.eclipse.escet.common.dsm/.settings/org.eclipse.jdt.core.prefs b/common/org.eclipse.escet.common.dsm/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/common/org.eclipse.escet.common.dsm/.settings/org.eclipse.jdt.core.prefs
+++ b/common/org.eclipse.escet.common.dsm/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/common/org.eclipse.escet.common.dsm/.settings/org.eclipse.jdt.ui.prefs b/common/org.eclipse.escet.common.dsm/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/common/org.eclipse.escet.common.dsm/.settings/org.eclipse.jdt.ui.prefs
+++ b/common/org.eclipse.escet.common.dsm/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/common/org.eclipse.escet.common.dsm/.settings/org.eclipse.ltk.core.refactoring.prefs b/common/org.eclipse.escet.common.dsm/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/common/org.eclipse.escet.common.dsm/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/common/org.eclipse.escet.common.dsm/META-INF/MANIFEST.MF b/common/org.eclipse.escet.common.dsm/META-INF/MANIFEST.MF
index 1da02dfdab851f52c733f0d153c89f2a7c46e5e6..3a3bd7cdf044731e027cc08598a04c729f6a9d37 100644
--- a/common/org.eclipse.escet.common.dsm/META-INF/MANIFEST.MF
+++ b/common/org.eclipse.escet.common.dsm/META-INF/MANIFEST.MF
@@ -2,15 +2,15 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Common Design Structure Matrix Functionality (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.common.dsm;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Automatic-Module-Name: org.eclipse.escet.common.dsm
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
 Require-Bundle: org.apache.commons.math3;bundle-version="3.6.1",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.common.box;bundle-version="0.9.0"
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.common.box;bundle-version="0.10.0"
 Export-Package: org.eclipse.escet.common.dsm,
  org.eclipse.escet.common.dsm.io,
  org.eclipse.escet.common.dsm.submatrix
diff --git a/common/org.eclipse.escet.common.eclipse.ui/.settings/org.eclipse.jdt.core.prefs b/common/org.eclipse.escet.common.eclipse.ui/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/common/org.eclipse.escet.common.eclipse.ui/.settings/org.eclipse.jdt.core.prefs
+++ b/common/org.eclipse.escet.common.eclipse.ui/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/common/org.eclipse.escet.common.eclipse.ui/.settings/org.eclipse.jdt.ui.prefs b/common/org.eclipse.escet.common.eclipse.ui/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/common/org.eclipse.escet.common.eclipse.ui/.settings/org.eclipse.jdt.ui.prefs
+++ b/common/org.eclipse.escet.common.eclipse.ui/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/common/org.eclipse.escet.common.eclipse.ui/.settings/org.eclipse.ltk.core.refactoring.prefs b/common/org.eclipse.escet.common.eclipse.ui/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/common/org.eclipse.escet.common.eclipse.ui/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/common/org.eclipse.escet.common.eclipse.ui/META-INF/MANIFEST.MF b/common/org.eclipse.escet.common.eclipse.ui/META-INF/MANIFEST.MF
index a153e422a4259279c273cb54185641dc4bce8fd5..70e89ed56a174c43973ad5abb722079c8bd640ab 100644
--- a/common/org.eclipse.escet.common.eclipse.ui/META-INF/MANIFEST.MF
+++ b/common/org.eclipse.escet.common.eclipse.ui/META-INF/MANIFEST.MF
@@ -2,15 +2,15 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Common Eclipse UI Functionality (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.common.eclipse.ui;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
 Require-Bundle: org.eclipse.ui;bundle-version="3.115.0";visibility:=reexport,
  org.eclipse.core.resources;bundle-version="3.13.600",
  org.eclipse.core.runtime;bundle-version="3.17.0";visibility:=reexport,
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
  org.eclipse.jface.text;bundle-version="3.16.100",
  org.eclipse.ui.ide;bundle-version="3.16.100",
  org.eclipse.ui.console;bundle-version="3.9.0",
diff --git a/common/org.eclipse.escet.common.eclipse.ui/src/org/eclipse/escet/common/eclipse/ui/ControlEditor.java b/common/org.eclipse.escet.common.eclipse.ui/src/org/eclipse/escet/common/eclipse/ui/ControlEditor.java
index 20c7f046c1a7af792d1cdaceca8fdf0c9769d649..0a11f2f1ec1581b759ff9e7b8634f99d203e0048 100644
--- a/common/org.eclipse.escet.common.eclipse.ui/src/org/eclipse/escet/common/eclipse/ui/ControlEditor.java
+++ b/common/org.eclipse.escet.common.eclipse.ui/src/org/eclipse/escet/common/eclipse/ui/ControlEditor.java
@@ -16,6 +16,7 @@ package org.eclipse.escet.common.eclipse.ui;
 import static org.eclipse.escet.common.java.Strings.fmt;
 
 import java.net.URI;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.runtime.IProgressMonitor;
@@ -77,6 +78,9 @@ public abstract class ControlEditor extends EditorPart {
     /** The control that represents the editor's contents. */
     protected Control contents;
 
+    /** Indicates whether the editor has been closed, i.e., its {@link #contents} has been disposed. */
+    private final AtomicBoolean contentsDisposed = new AtomicBoolean(false);
+
     /**
      * Implementation of the {@link EditorPart#init} method.
      *
@@ -122,6 +126,14 @@ public abstract class ControlEditor extends EditorPart {
         // The control editor only contains a single control.
         contents = createContents(parent);
         Assert.check(contents.getParent() == parent);
+
+        contents.addDisposeListener(e -> {
+            // Release all waiting threads.
+            synchronized (contents) {
+                contentsDisposed.set(true);
+                contents.notifyAll();
+            }
+        });
     }
 
     /**
@@ -404,4 +416,22 @@ public abstract class ControlEditor extends EditorPart {
             }
         });
     }
+
+    /** Causes the caller to wait until the editor is closed. */
+    public void waitUntilClosed() {
+        if (contents == null) {
+            return;
+        }
+        synchronized (contents) {
+            if (contentsDisposed.get()) {
+                return;
+            }
+
+            try {
+                contents.wait();
+            } catch (InterruptedException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
 }
diff --git a/common/org.eclipse.escet.common.emf.ecore.codegen/.settings/org.eclipse.jdt.core.prefs b/common/org.eclipse.escet.common.emf.ecore.codegen/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/common/org.eclipse.escet.common.emf.ecore.codegen/.settings/org.eclipse.jdt.core.prefs
+++ b/common/org.eclipse.escet.common.emf.ecore.codegen/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/common/org.eclipse.escet.common.emf.ecore.codegen/.settings/org.eclipse.jdt.ui.prefs b/common/org.eclipse.escet.common.emf.ecore.codegen/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/common/org.eclipse.escet.common.emf.ecore.codegen/.settings/org.eclipse.jdt.ui.prefs
+++ b/common/org.eclipse.escet.common.emf.ecore.codegen/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/common/org.eclipse.escet.common.emf.ecore.codegen/.settings/org.eclipse.ltk.core.refactoring.prefs b/common/org.eclipse.escet.common.emf.ecore.codegen/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/common/org.eclipse.escet.common.emf.ecore.codegen/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/common/org.eclipse.escet.common.emf.ecore.codegen/META-INF/MANIFEST.MF b/common/org.eclipse.escet.common.emf.ecore.codegen/META-INF/MANIFEST.MF
index 6de432d6fb53a76fd18621cdfd13cd0a0094975d..6f229ffe8a4fbfa9b9f50e1ef96888dcc4483e8e 100644
--- a/common/org.eclipse.escet.common.emf.ecore.codegen/META-INF/MANIFEST.MF
+++ b/common/org.eclipse.escet.common.emf.ecore.codegen/META-INF/MANIFEST.MF
@@ -2,14 +2,14 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Common EMF Ecore Code Generators (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.common.emf.ecore.codegen;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
 Require-Bundle: org.eclipse.emf.ecore;bundle-version="2.20.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
  org.apache.commons.lang3;bundle-version="3.1.0",
- org.eclipse.escet.common.box;bundle-version="0.9.0"
+ org.eclipse.escet.common.box;bundle-version="0.10.0"
 Export-Package: org.eclipse.escet.common.emf.ecore.codegen,
  org.eclipse.escet.common.emf.ecore.codegen.java,
  org.eclipse.escet.common.emf.ecore.codegen.latex
diff --git a/common/org.eclipse.escet.common.emf.ecore.validation/.settings/org.eclipse.jdt.core.prefs b/common/org.eclipse.escet.common.emf.ecore.validation/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/common/org.eclipse.escet.common.emf.ecore.validation/.settings/org.eclipse.jdt.core.prefs
+++ b/common/org.eclipse.escet.common.emf.ecore.validation/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/common/org.eclipse.escet.common.emf.ecore.validation/.settings/org.eclipse.jdt.ui.prefs b/common/org.eclipse.escet.common.emf.ecore.validation/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/common/org.eclipse.escet.common.emf.ecore.validation/.settings/org.eclipse.jdt.ui.prefs
+++ b/common/org.eclipse.escet.common.emf.ecore.validation/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/common/org.eclipse.escet.common.emf.ecore.validation/.settings/org.eclipse.ltk.core.refactoring.prefs b/common/org.eclipse.escet.common.emf.ecore.validation/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/common/org.eclipse.escet.common.emf.ecore.validation/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/common/org.eclipse.escet.common.emf.ecore.validation/META-INF/MANIFEST.MF b/common/org.eclipse.escet.common.emf.ecore.validation/META-INF/MANIFEST.MF
index 9b9146927efe2cbeccf01b917ff7555ac748cd50..8cbe6abad36494a7ad4dc9d23a0d6205c98f4a05 100644
--- a/common/org.eclipse.escet.common.emf.ecore.validation/META-INF/MANIFEST.MF
+++ b/common/org.eclipse.escet.common.emf.ecore.validation/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Common EMF EValidator Adapter (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.common.emf.ecore.validation;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Export-Package: org.eclipse.escet.common.emf.ecore.validation
 Bundle-ActivationPolicy: lazy
diff --git a/common/org.eclipse.escet.common.emf.ecore.xmi/.settings/org.eclipse.jdt.core.prefs b/common/org.eclipse.escet.common.emf.ecore.xmi/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/common/org.eclipse.escet.common.emf.ecore.xmi/.settings/org.eclipse.jdt.core.prefs
+++ b/common/org.eclipse.escet.common.emf.ecore.xmi/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/common/org.eclipse.escet.common.emf.ecore.xmi/.settings/org.eclipse.jdt.ui.prefs b/common/org.eclipse.escet.common.emf.ecore.xmi/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/common/org.eclipse.escet.common.emf.ecore.xmi/.settings/org.eclipse.jdt.ui.prefs
+++ b/common/org.eclipse.escet.common.emf.ecore.xmi/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/common/org.eclipse.escet.common.emf.ecore.xmi/.settings/org.eclipse.ltk.core.refactoring.prefs b/common/org.eclipse.escet.common.emf.ecore.xmi/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/common/org.eclipse.escet.common.emf.ecore.xmi/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/common/org.eclipse.escet.common.emf.ecore.xmi/META-INF/MANIFEST.MF b/common/org.eclipse.escet.common.emf.ecore.xmi/META-INF/MANIFEST.MF
index fee84994ea9f389509f30cd4c3368452f10747e6..4012324c22c4d5df1b92e99acd13507e3d42e15d 100644
--- a/common/org.eclipse.escet.common.emf.ecore.xmi/META-INF/MANIFEST.MF
+++ b/common/org.eclipse.escet.common.emf.ecore.xmi/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Common EMF Ecore XMI Resource Factory (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.common.emf.ecore.xmi;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
diff --git a/common/org.eclipse.escet.common.emf.tests/.settings/org.eclipse.jdt.core.prefs b/common/org.eclipse.escet.common.emf.tests/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/common/org.eclipse.escet.common.emf.tests/.settings/org.eclipse.jdt.core.prefs
+++ b/common/org.eclipse.escet.common.emf.tests/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/common/org.eclipse.escet.common.emf.tests/.settings/org.eclipse.jdt.ui.prefs b/common/org.eclipse.escet.common.emf.tests/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/common/org.eclipse.escet.common.emf.tests/.settings/org.eclipse.jdt.ui.prefs
+++ b/common/org.eclipse.escet.common.emf.tests/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/common/org.eclipse.escet.common.emf.tests/.settings/org.eclipse.ltk.core.refactoring.prefs b/common/org.eclipse.escet.common.emf.tests/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/common/org.eclipse.escet.common.emf.tests/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/common/org.eclipse.escet.common.emf.tests/META-INF/MANIFEST.MF b/common/org.eclipse.escet.common.emf.tests/META-INF/MANIFEST.MF
index 863331d69cc5c108ff1e6cfdada867e10e763b3e..91f17fbc77259941859cf9155db13b29122d4a7c 100644
--- a/common/org.eclipse.escet.common.emf.tests/META-INF/MANIFEST.MF
+++ b/common/org.eclipse.escet.common.emf.tests/META-INF/MANIFEST.MF
@@ -2,14 +2,14 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Common EMF Functionality Tests (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.common.emf.tests;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
  org.junit;bundle-version="4.12.0",
- org.eclipse.escet.common.emf;bundle-version="0.9.0",
+ org.eclipse.escet.common.emf;bundle-version="0.10.0",
  org.eclipse.emf.ecore;bundle-version="2.20.0"
 Automatic-Module-Name: org.eclipse.escet.common.emf.tests
 Export-Package: org.eclipse.escet.common.emf.tests;x-internal:=true
diff --git a/common/org.eclipse.escet.common.emf/.settings/org.eclipse.jdt.core.prefs b/common/org.eclipse.escet.common.emf/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/common/org.eclipse.escet.common.emf/.settings/org.eclipse.jdt.core.prefs
+++ b/common/org.eclipse.escet.common.emf/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/common/org.eclipse.escet.common.emf/.settings/org.eclipse.jdt.ui.prefs b/common/org.eclipse.escet.common.emf/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/common/org.eclipse.escet.common.emf/.settings/org.eclipse.jdt.ui.prefs
+++ b/common/org.eclipse.escet.common.emf/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/common/org.eclipse.escet.common.emf/.settings/org.eclipse.ltk.core.refactoring.prefs b/common/org.eclipse.escet.common.emf/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/common/org.eclipse.escet.common.emf/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/common/org.eclipse.escet.common.emf/META-INF/MANIFEST.MF b/common/org.eclipse.escet.common.emf/META-INF/MANIFEST.MF
index 03e38f2305bcf3fa64bfaaa9048ecffc66bf079c..fef42efc993adc040d9bf232caf3477ef3a2c2b1 100644
--- a/common/org.eclipse.escet.common.emf/META-INF/MANIFEST.MF
+++ b/common/org.eclipse.escet.common.emf/META-INF/MANIFEST.MF
@@ -2,14 +2,14 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Common EMF Functionality (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.common.emf;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
 Require-Bundle: org.eclipse.emf.ecore;bundle-version="2.20.0",
  org.eclipse.emf.ecore.xmi;bundle-version="2.16.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.common.emf.ecore.xmi;bundle-version="0.9.0"
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.common.emf.ecore.xmi;bundle-version="0.10.0"
 Export-Package: org.eclipse.escet.common.emf
 Automatic-Module-Name: org.eclipse.escet.common.emf
diff --git a/common/org.eclipse.escet.common.feature/feature.xml b/common/org.eclipse.escet.common.feature/feature.xml
index a1aa4ba816c273fa80c7dbe7e4a32a64ea68b0cd..0b30da2d264588fe51ad30797c69c1ae1cf2ea77 100644
--- a/common/org.eclipse.escet.common.feature/feature.xml
+++ b/common/org.eclipse.escet.common.feature/feature.xml
@@ -13,11 +13,11 @@
 <feature
       id="org.eclipse.escet.common.feature"
       label="ESCET Common (Incubation)"
-      version="0.9.0.qualifier"
+      version="0.10.0.qualifier"
       provider-name="Eclipse ESCET"
       plugin="org.eclipse.escet.product.branding"
       license-feature="org.eclipse.escet.releng.license.mit"
-      license-feature-version="0.9.0.qualifier">
+      license-feature-version="0.10.0.qualifier">
 
    <description>
       Eclipse ESCET common components.
@@ -33,9 +33,7 @@
 
    <requires>
       <import plugin="org.apache.commons.io"/>
-      <import plugin="org.apache.xalan"/>
       <import feature="org.eclipse.jdt"/>
-      <import plugin="org.apache.xml.serializer"/>
    </requires>
 
    <plugin
diff --git a/common/org.eclipse.escet.common.java/.settings/org.eclipse.jdt.core.prefs b/common/org.eclipse.escet.common.java/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/common/org.eclipse.escet.common.java/.settings/org.eclipse.jdt.core.prefs
+++ b/common/org.eclipse.escet.common.java/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/common/org.eclipse.escet.common.java/.settings/org.eclipse.jdt.ui.prefs b/common/org.eclipse.escet.common.java/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/common/org.eclipse.escet.common.java/.settings/org.eclipse.jdt.ui.prefs
+++ b/common/org.eclipse.escet.common.java/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/common/org.eclipse.escet.common.java/.settings/org.eclipse.ltk.core.refactoring.prefs b/common/org.eclipse.escet.common.java/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/common/org.eclipse.escet.common.java/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/common/org.eclipse.escet.common.java/META-INF/MANIFEST.MF b/common/org.eclipse.escet.common.java/META-INF/MANIFEST.MF
index c8e648a211a7652cc8102f5c304091ade1478430..0eb924a2ccad35bb77ae03be7ca3ac80177ec4c1 100644
--- a/common/org.eclipse.escet.common.java/META-INF/MANIFEST.MF
+++ b/common/org.eclipse.escet.common.java/META-INF/MANIFEST.MF
@@ -2,11 +2,12 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Common Java Functionality (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.common.java;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Export-Package: org.eclipse.escet.common.java,
  org.eclipse.escet.common.java.removablelist
-Require-Bundle: org.apache.commons.lang3;bundle-version="3.1.0"
+Require-Bundle: org.apache.commons.lang3;bundle-version="3.1.0",
+ org.apache.commons.commons-text;bundle-version="1.10.0"
 Bundle-ActivationPolicy: lazy
 Bundle-Vendor: Eclipse ESCET
 Automatic-Module-Name: org.eclipse.escet.common.java
diff --git a/common/org.eclipse.escet.common.java/src/org/eclipse/escet/common/java/DirectedGraphCycleFinder.java b/common/org.eclipse.escet.common.java/src/org/eclipse/escet/common/java/DirectedGraphCycleFinder.java
new file mode 100644
index 0000000000000000000000000000000000000000..f603d60b5677505a1a6e49c6e7d8c09f5de14871
--- /dev/null
+++ b/common/org.eclipse.escet.common.java/src/org/eclipse/escet/common/java/DirectedGraphCycleFinder.java
@@ -0,0 +1,194 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2021, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.common.java;
+
+import static org.eclipse.escet.common.java.Lists.listc;
+import static org.eclipse.escet.common.java.Maps.mapc;
+import static org.eclipse.escet.common.java.Sets.set;
+import static org.eclipse.escet.common.java.Sets.setc;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.BooleanSupplier;
+
+/**
+ * Class for finding simple cycles in a directed graph using depth-first search.
+ *
+ * <P>
+ * A simple cycle is a sequence of edges where each non-last edge arrives at the vertex that is used as starting vertex
+ * for the next edge and the last edge arrives at the starting vertex of the first edge, and every edge in the cycle
+ * starts from a different vertex.
+ * </p>
+ *
+ * @param <G> Graph class being searched.
+ * @param <V> Vertex class in the graph.
+ * @param <E> Edge class in the graph.
+ * @param <C> Class that stores a found cycle. This class should implement hashing and equality under rotation of its
+ *     edges. For example, cycle {@code abc} may again be found as cycle {@code bca} or {@code cab}.
+ */
+public abstract class DirectedGraphCycleFinder<G, V, E extends DirectedGraphCycleFinder.GraphEdge<V>, C> {
+    /** Edges currently being searched. */
+    private List<E> stack;
+
+    /** Starting vertex of the edges at the {@link #stack} to their index at the {@link #stack}. */
+    private Map<V, Integer> stackIndex;
+
+    /** Vertices that are or were being searched for cycles. */
+    private Set<V> visitedVertices;
+
+    /** Found cycles in the graph. */
+    private Set<C> foundCycles;
+
+    /** Test function to detect a user abort request. */
+    private final BooleanSupplier isTerminationRequested;
+
+    /**
+     * Constructor of the {@link DirectedGraphCycleFinder} class.
+     *
+     * @param isTerminationRequested Test function to detect a user abort request. If {@code null}, termination
+     *     detection is disabled.
+     */
+    public DirectedGraphCycleFinder(BooleanSupplier isTerminationRequested) {
+        this.isTerminationRequested = isTerminationRequested;
+    }
+
+    /**
+     * Find all simple cycles in the provided graph.
+     *
+     * @param graph Graph being searched.
+     * @return The found simple cycles in the graph.
+     */
+    public Set<C> findSimpleCycles(G graph) {
+        // Initialize data fields for the search.
+        List<V> vertices = getVertices(graph);
+        stack = listc(vertices.size() + 1);
+        stackIndex = mapc(vertices.size());
+        visitedVertices = setc(vertices.size());
+
+        Set<C> foundCycles = set();
+        this.foundCycles = foundCycles;
+
+        // Examine all vertices of the graph. Due to directed edges or limited edges that can be traversed it is
+        // possible that some vertices are not always reachable.
+        for (V vertex: vertices) {
+            if (visitedVertices.contains(vertex)) {
+                continue;
+            }
+            expandVertexPath(vertex);
+
+            if (isTerminationRequested != null && isTerminationRequested.getAsBoolean()) {
+                return null;
+            }
+        }
+
+        // Cleanup and return the found cycles.
+        visitedVertices = null;
+        stackIndex = null;
+        stack = null;
+        this.foundCycles = null;
+        return foundCycles;
+    }
+
+    /**
+     * Expand the vertex path being searched by the given vertex.
+     *
+     * @param vertex Next vertex to search.
+     */
+    private void expandVertexPath(V vertex) {
+        if (isTerminationRequested != null && isTerminationRequested.getAsBoolean()) {
+            return;
+        }
+
+        // Expand the path by the new vertex.
+        visitedVertices.add(vertex);
+        int vertexStackPos = stack.size();
+        stackIndex.put(vertex, vertexStackPos);
+        stack.add(null); // Is replaced with proper edges below.
+
+        // Explore the edges from the new vertex for further expansion.
+        for (E edge: getOutgoingEdges(vertex)) {
+            V edgeTargetVertex = edge.destinationVertex;
+            Integer cycleStartIndex = stackIndex.get(edgeTargetVertex);
+
+            if (cycleStartIndex == null) {
+                // New vertex in this search, explore it. Note that this ignores the visitedVertices set, so
+                // multiple graph traversals over the same vertex in different searches are possible.
+                stack.set(vertexStackPos, edge);
+                expandVertexPath(edgeTargetVertex);
+            } else {
+                // A simple cycle was detected, add it to the collection.
+                stack.set(vertexStackPos, edge);
+                addCycle(stack.subList(cycleStartIndex, vertexStackPos + 1), foundCycles);
+            }
+
+            if (isTerminationRequested != null && isTerminationRequested.getAsBoolean()) {
+                return;
+            }
+        }
+
+        // Done with the vertex, cleanup.
+        stack.remove(vertexStackPos);
+        stackIndex.remove(vertex);
+    }
+
+    /**
+     * Get all the vertices of the graph.
+     *
+     * @param graph Graph to use.
+     * @return All the vertices of the graph.
+     */
+    protected abstract List<V> getVertices(G graph);
+
+    /**
+     * Obtain the edges that leave from the provided vertex in the graph.
+     *
+     * @param vertex Starting vertex of all returned edges.
+     * @return The returned edges.
+     */
+    protected abstract List<E> getOutgoingEdges(V vertex);
+
+    /**
+     * Add a cycle to the collection of found cycles.
+     *
+     * @param edges Edges that form a new cycle. The supplied list is not stable, it must be copied to preserve the
+     *     result.
+     * @param foundCycles Previously found cycles.
+     */
+    protected abstract void addCycle(List<E> edges, Set<C> foundCycles);
+
+    /**
+     * An edge in the graph.
+     *
+     * @param <V> Vertex class in the graph.
+     */
+    public static class GraphEdge<V> {
+        /** Vertex where the edge leaves. */
+        public final V startVertex;
+
+        /** Vertex where the edge arrives. */
+        public final V destinationVertex;
+
+        /**
+         * Constructor of the {@link GraphEdge} class.
+         *
+         * @param startVertex Vertex where the edge leaves.
+         * @param destinationVertex Vertex where the edge arrives.
+         */
+        public GraphEdge(V startVertex, V destinationVertex) {
+            this.startVertex = startVertex;
+            this.destinationVertex = destinationVertex;
+        }
+    }
+}
diff --git a/common/org.eclipse.escet.common.java/src/org/eclipse/escet/common/java/ListProductIterator.java b/common/org.eclipse.escet.common.java/src/org/eclipse/escet/common/java/ListProductIterator.java
index 3f938b05b517fc9e0eb30e3b58518f27ea826c06..b25f2c1f56e2cb92da3a0464fb7d7bfefe0dfa67 100644
--- a/common/org.eclipse.escet.common.java/src/org/eclipse/escet/common/java/ListProductIterator.java
+++ b/common/org.eclipse.escet.common.java/src/org/eclipse/escet/common/java/ListProductIterator.java
@@ -43,11 +43,12 @@ import java.util.NoSuchElementException;
  *
  * <pre>[[1, 2, 3], [4], [5, 6]]</pre>
  *
- * It is transformed to:
+ * It is transformed to the sequence:
  *
- * <pre>[[1, 4, 5], [1, 4, 6], [2, 4, 5], [2, 4, 6], [3, 4, 5], [3, 4, 6]]</pre>
+ * <pre>[1, 4, 5], [1, 4, 6], [2, 4, 5], [2, 4, 6], [3, 4, 5], [3, 4, 6]</pre>
  *
- * The resulting sub-lists are returned one by one.
+ * The resulting lists are created one by one with the original elements. It is safe to take ownership of a resulting
+ * list.
  * </p>
  *
  * @param <T> The elements of the lists of lists (for both the input and the output).
diff --git a/common/org.eclipse.escet.common.java/src/org/eclipse/escet/common/java/Strings.java b/common/org.eclipse.escet.common.java/src/org/eclipse/escet/common/java/Strings.java
index 5521ae670226461724f259b41692e4a802790a93..7c28e3ec96bd7c4bd827686f35ce11651d74b268 100644
--- a/common/org.eclipse.escet.common.java/src/org/eclipse/escet/common/java/Strings.java
+++ b/common/org.eclipse.escet.common.java/src/org/eclipse/escet/common/java/Strings.java
@@ -26,8 +26,8 @@ import java.util.function.Function;
 import java.util.regex.Pattern;
 import java.util.stream.Stream;
 
-import org.apache.commons.lang3.StringEscapeUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.text.StringEscapeUtils;
 
 /** Helper methods for working with strings. */
 public final class Strings {
diff --git a/common/org.eclipse.escet.common.multivaluetrees/.settings/org.eclipse.jdt.core.prefs b/common/org.eclipse.escet.common.multivaluetrees/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/common/org.eclipse.escet.common.multivaluetrees/.settings/org.eclipse.jdt.core.prefs
+++ b/common/org.eclipse.escet.common.multivaluetrees/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/common/org.eclipse.escet.common.multivaluetrees/.settings/org.eclipse.jdt.ui.prefs b/common/org.eclipse.escet.common.multivaluetrees/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/common/org.eclipse.escet.common.multivaluetrees/.settings/org.eclipse.jdt.ui.prefs
+++ b/common/org.eclipse.escet.common.multivaluetrees/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/common/org.eclipse.escet.common.multivaluetrees/.settings/org.eclipse.ltk.core.refactoring.prefs b/common/org.eclipse.escet.common.multivaluetrees/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/common/org.eclipse.escet.common.multivaluetrees/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/common/org.eclipse.escet.common.multivaluetrees/META-INF/MANIFEST.MF b/common/org.eclipse.escet.common.multivaluetrees/META-INF/MANIFEST.MF
index 9c5439738f70140aa7444ca360795b3c7a7e0dd4..244e900d69d9532b66d86109c52facdbbc6d18e7 100644
--- a/common/org.eclipse.escet.common.multivaluetrees/META-INF/MANIFEST.MF
+++ b/common/org.eclipse.escet.common.multivaluetrees/META-INF/MANIFEST.MF
@@ -2,11 +2,11 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Common Multivalue Trees (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.common.multivaluetrees;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
 Bundle-Vendor: Eclipse ESCET
-Require-Bundle: org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0"
+Require-Bundle: org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0"
 Export-Package: org.eclipse.escet.common.multivaluetrees
 Automatic-Module-Name: org.eclipse.escet.common.multivaluetrees
diff --git a/common/org.eclipse.escet.common.position.common/.settings/org.eclipse.jdt.core.prefs b/common/org.eclipse.escet.common.position.common/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/common/org.eclipse.escet.common.position.common/.settings/org.eclipse.jdt.core.prefs
+++ b/common/org.eclipse.escet.common.position.common/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/common/org.eclipse.escet.common.position.common/.settings/org.eclipse.jdt.ui.prefs b/common/org.eclipse.escet.common.position.common/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/common/org.eclipse.escet.common.position.common/.settings/org.eclipse.jdt.ui.prefs
+++ b/common/org.eclipse.escet.common.position.common/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/common/org.eclipse.escet.common.position.common/.settings/org.eclipse.ltk.core.refactoring.prefs b/common/org.eclipse.escet.common.position.common/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/common/org.eclipse.escet.common.position.common/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/common/org.eclipse.escet.common.position.common/META-INF/MANIFEST.MF b/common/org.eclipse.escet.common.position.common/META-INF/MANIFEST.MF
index 93459b8e4a228dcaa501274b22d8208cf8da3caa..698a1288341b83b1ee37458b1ada88a5da538da1 100644
--- a/common/org.eclipse.escet.common.position.common/META-INF/MANIFEST.MF
+++ b/common/org.eclipse.escet.common.position.common/META-INF/MANIFEST.MF
@@ -2,11 +2,11 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Common Position Functionality (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.common.position.common;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.common.position.metamodel;bundle-version="0.9.0"
+Require-Bundle: org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.common.position.metamodel;bundle-version="0.10.0"
 Export-Package: org.eclipse.escet.common.position.common
 Bundle-Vendor: Eclipse ESCET
 Automatic-Module-Name: org.eclipse.escet.common.position.common
diff --git a/common/org.eclipse.escet.common.position.metamodel/.settings/org.eclipse.jdt.core.prefs b/common/org.eclipse.escet.common.position.metamodel/.settings/org.eclipse.jdt.core.prefs
index a39882dc615f390c7a829a2c18eb7f17ffd8668b..eabbae9d848583c4a9412f97a7c7b9c9b344ef90 100644
--- a/common/org.eclipse.escet.common.position.metamodel/.settings/org.eclipse.jdt.core.prefs
+++ b/common/org.eclipse.escet.common.position.metamodel/.settings/org.eclipse.jdt.core.prefs
@@ -126,6 +126,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/common/org.eclipse.escet.common.position.metamodel/.settings/org.eclipse.ltk.core.refactoring.prefs b/common/org.eclipse.escet.common.position.metamodel/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/common/org.eclipse.escet.common.position.metamodel/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/common/org.eclipse.escet.common.position.metamodel/META-INF/MANIFEST.MF b/common/org.eclipse.escet.common.position.metamodel/META-INF/MANIFEST.MF
index e950c4db7e552699c28bd470c8d6eed1f20937ff..ea1308659d8301b6a5d7bc599bad34963e8978bd 100644
--- a/common/org.eclipse.escet.common.position.metamodel/META-INF/MANIFEST.MF
+++ b/common/org.eclipse.escet.common.position.metamodel/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.escet.common.position.metamodel;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-ClassPath: .
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
@@ -12,6 +12,6 @@ Export-Package: org.eclipse.escet.common.position.metamodel.position,
  org.eclipse.escet.common.position.metamodel.position.util
 Require-Bundle: org.eclipse.core.runtime;bundle-version="3.17.0",
  org.eclipse.emf.ecore;bundle-version="2.20.0";visibility:=reexport,
- org.eclipse.escet.common.emf.ecore.xmi;bundle-version="0.9.0"
+ org.eclipse.escet.common.emf.ecore.xmi;bundle-version="0.10.0"
 Bundle-ActivationPolicy: lazy
 Automatic-Module-Name: org.eclipse.escet.common.position.metamodel
diff --git a/common/org.eclipse.escet.common.position.metamodel/docs/position_ecore_doc.bib b/common/org.eclipse.escet.common.position.metamodel/docs/position_ecore_doc.bib
index 989f27cf7fdbb2a215e52b369bd1a98a27049586..47489aff11f33b0c760460fcdb4d1b576d8fb40a 100644
--- a/common/org.eclipse.escet.common.position.metamodel/docs/position_ecore_doc.bib
+++ b/common/org.eclipse.escet.common.position.metamodel/docs/position_ecore_doc.bib
@@ -1,7 +1,7 @@
 @misc{Eclipse:ESCET,
   author = {Contributors to the Eclipse Foundation},
   title = {{Eclipse Supervisory Control Engineering Toolkit (Eclipse ESCET)}},
-  howpublished = {\url{https://eclipse.org/escet}}
+  howpublished = {\url{https://eclipse.dev/escet}}
 }
 
 @misc{Eclipse:Incubation,
diff --git a/common/org.eclipse.escet.common.position.metamodel/docs/position_ecore_doc.pdf b/common/org.eclipse.escet.common.position.metamodel/docs/position_ecore_doc.pdf
index 05b56f78bf030745528172a4c5daae2acba401b4..f0d221601d7218a75a2043cccad5921ae910960c 100644
Binary files a/common/org.eclipse.escet.common.position.metamodel/docs/position_ecore_doc.pdf and b/common/org.eclipse.escet.common.position.metamodel/docs/position_ecore_doc.pdf differ
diff --git a/common/org.eclipse.escet.common.position.metamodel/docs/position_ecore_doc.tex b/common/org.eclipse.escet.common.position.metamodel/docs/position_ecore_doc.tex
index 5ccaec6d2eb6e27b73700558b8c5c28bc1753093..576f02295ca91aaac74784355166a0e2f6c4e66f 100644
--- a/common/org.eclipse.escet.common.position.metamodel/docs/position_ecore_doc.tex
+++ b/common/org.eclipse.escet.common.position.metamodel/docs/position_ecore_doc.tex
@@ -71,7 +71,7 @@
 % Document settings.
 \title{Position Metamodel Reference Documentation (Incubation)}
 \author{Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation}
-\date{Version 2022-12-30}
+\date{Version 2023-05-05}
 \titlepic{\includegraphics[width=0.5\textwidth]{figures/eclipse-incubation.png}}
 
 % Start of document.
diff --git a/common/org.eclipse.escet.common.raildiagrams/.settings/org.eclipse.jdt.core.prefs b/common/org.eclipse.escet.common.raildiagrams/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/common/org.eclipse.escet.common.raildiagrams/.settings/org.eclipse.jdt.core.prefs
+++ b/common/org.eclipse.escet.common.raildiagrams/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/common/org.eclipse.escet.common.raildiagrams/.settings/org.eclipse.jdt.ui.prefs b/common/org.eclipse.escet.common.raildiagrams/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/common/org.eclipse.escet.common.raildiagrams/.settings/org.eclipse.jdt.ui.prefs
+++ b/common/org.eclipse.escet.common.raildiagrams/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/common/org.eclipse.escet.common.raildiagrams/.settings/org.eclipse.ltk.core.refactoring.prefs b/common/org.eclipse.escet.common.raildiagrams/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/common/org.eclipse.escet.common.raildiagrams/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/common/org.eclipse.escet.common.raildiagrams/META-INF/MANIFEST.MF b/common/org.eclipse.escet.common.raildiagrams/META-INF/MANIFEST.MF
index b6b6adbde3351c8ce86165b56dc2f30d75eee3bd..c75ee87a118cad1d1a26fe9418b581307f5e7e64 100644
--- a/common/org.eclipse.escet.common.raildiagrams/META-INF/MANIFEST.MF
+++ b/common/org.eclipse.escet.common.raildiagrams/META-INF/MANIFEST.MF
@@ -2,13 +2,13 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Common Rail Diagram Generator (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.common.raildiagrams;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Automatic-Module-Name: org.eclipse.escet.common.raildiagrams
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
 Bundle-Vendor: Eclipse ESCET
-Require-Bundle: org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
  org.eclipse.jface.text;bundle-version="3.17.0"
 Export-Package: org.eclipse.escet.common.raildiagrams,
  org.eclipse.escet.common.raildiagrams.config,
diff --git a/common/org.eclipse.escet.common.svg/.settings/org.eclipse.jdt.core.prefs b/common/org.eclipse.escet.common.svg/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/common/org.eclipse.escet.common.svg/.settings/org.eclipse.jdt.core.prefs
+++ b/common/org.eclipse.escet.common.svg/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/common/org.eclipse.escet.common.svg/.settings/org.eclipse.jdt.ui.prefs b/common/org.eclipse.escet.common.svg/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/common/org.eclipse.escet.common.svg/.settings/org.eclipse.jdt.ui.prefs
+++ b/common/org.eclipse.escet.common.svg/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/common/org.eclipse.escet.common.svg/.settings/org.eclipse.ltk.core.refactoring.prefs b/common/org.eclipse.escet.common.svg/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/common/org.eclipse.escet.common.svg/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/common/org.eclipse.escet.common.svg/META-INF/MANIFEST.MF b/common/org.eclipse.escet.common.svg/META-INF/MANIFEST.MF
index bf8c58d5b890bf367d727fb82bdb45bad233de82..a648f41a5f7b9ae8ca94631301a6be276a036cd5 100644
--- a/common/org.eclipse.escet.common.svg/META-INF/MANIFEST.MF
+++ b/common/org.eclipse.escet.common.svg/META-INF/MANIFEST.MF
@@ -2,26 +2,24 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Common SVG Functionality (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.common.svg;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.common.eclipse.ui;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.common.eclipse.ui;bundle-version="0.10.0",
  org.apache.batik.bridge;bundle-version="1.14.0",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
  org.apache.batik.dom.svg;bundle-version="1.14.0",
  org.apache.batik.util;bundle-version="1.14.0",
  org.apache.batik.dom;bundle-version="1.14.0",
  org.w3c.dom.svg;bundle-version="1.1.0",
- org.apache.xalan;bundle-version="2.7.1",
  org.eclipse.core.resources;bundle-version="3.13.600",
  org.apache.batik.awt.util;bundle-version="1.14.0",
  org.apache.batik.css;bundle-version="1.14.0",
  org.eclipse.emf.ecore;bundle-version="2.20.0",
  org.apache.batik.gvt;bundle-version="1.14.0",
  org.apache.batik.anim;bundle-version="1.14.0",
- org.apache.xerces;bundle-version="2.9.0",
  org.apache.batik.ext;bundle-version="1.14.0",
  org.apache.commons.io;bundle-version="2.8.0"
 Export-Package: org.eclipse.escet.common.svg,
diff --git a/common/org.eclipse.escet.common.svg/src/org/eclipse/escet/common/svg/SvgViewer.java b/common/org.eclipse.escet.common.svg/src/org/eclipse/escet/common/svg/SvgViewer.java
index 8d3f5dbd29744660a9d3499eac9ec3ffff9f68ff..f54c34df3c09c052d39194e5ccc7562fc24c8b6c 100644
--- a/common/org.eclipse.escet.common.svg/src/org/eclipse/escet/common/svg/SvgViewer.java
+++ b/common/org.eclipse.escet.common.svg/src/org/eclipse/escet/common/svg/SvgViewer.java
@@ -400,9 +400,8 @@ public class SvgViewer extends ControlEditor {
 
         // Save image.
         if (savePath.endsWith(".svg")) {
-            // Get transformer from Apache Xalan.
-            TransformerFactory factory = TransformerFactory
-                    .newInstance("org.apache.xalan.processor.TransformerFactoryImpl", null);
+            // Get transformer.
+            TransformerFactory factory = TransformerFactory.newInstance();
 
             Transformer transformer;
             try {
@@ -424,33 +423,6 @@ public class SvgViewer extends ControlEditor {
             tgtStream = new BufferedOutputStream(tgtStream);
 
             // Set source and target of transformation.
-            //
-            // Note that the target has no 'system id'; setting it is
-            // problematic (see below). Not setting it could
-            // potentially also lead to problems in the future.
-            // However, we'll let it become a problem before
-            // attempting to solve it.
-            //
-            // Problem:
-            // Assume we want to save the contents of the
-            // SVG viewer/visualizer to "/home/some/path/a b/c.svg".
-            // This absolute file path is converted to URI
-            // "file:/home/some/path/a%20b/c.svg" as a URI is required
-            // by the javax.xml.transform.stream.StreamResult
-            // constructor. The space is URL encoded to '%20'. The
-            // Apache Xalan implementation simply strips the prefix to
-            // get the absolute path. It does not decode the URI. The
-            // result is that the directory can not be found, and we
-            // thus get "Failed to save image." as error:
-            // "ERROR: java.io.FileNotFoundException:
-            // /home/some/path/a%20b/c.svg (No such file or directory)
-            // CAUSE: /home/some/path/a%20b/c.svg (No such file or
-            // directory)"
-            // This is a known bug in Apache Xalan, see
-            // https://issues.apache.org/jira/browse/XALANJ-2511 and
-            // https://issues.apache.org/jira/browse/XALANJ-2461.
-            // Once that bug is fixed, we can upgrade to the new
-            // version, and saving SVG images is fixed as well.
             DOMSource src = new DOMSource(document);
             StreamResult tgt = new StreamResult(tgtStream);
 
diff --git a/common/org.eclipse.escet.common.tests/.settings/org.eclipse.jdt.core.prefs b/common/org.eclipse.escet.common.tests/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/common/org.eclipse.escet.common.tests/.settings/org.eclipse.jdt.core.prefs
+++ b/common/org.eclipse.escet.common.tests/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/common/org.eclipse.escet.common.tests/.settings/org.eclipse.jdt.ui.prefs b/common/org.eclipse.escet.common.tests/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/common/org.eclipse.escet.common.tests/.settings/org.eclipse.jdt.ui.prefs
+++ b/common/org.eclipse.escet.common.tests/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/common/org.eclipse.escet.common.tests/.settings/org.eclipse.ltk.core.refactoring.prefs b/common/org.eclipse.escet.common.tests/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/common/org.eclipse.escet.common.tests/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/common/org.eclipse.escet.common.tests/META-INF/MANIFEST.MF b/common/org.eclipse.escet.common.tests/META-INF/MANIFEST.MF
index c5ed7834fb2a291cda7398a7e64dad3349467dda..a7af44e855c3fae12a62453e548e894a990aad60 100644
--- a/common/org.eclipse.escet.common.tests/META-INF/MANIFEST.MF
+++ b/common/org.eclipse.escet.common.tests/META-INF/MANIFEST.MF
@@ -2,13 +2,13 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Common Tests (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.common.tests;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.common.dsm.app;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.common.dsm.app;bundle-version="0.10.0",
  org.junit;bundle-version="4.12.0",
- org.eclipse.escet.tooldef.interpreter;bundle-version="0.9.0",
- org.eclipse.escet.common.tooldefs;bundle-version="0.9.0"
+ org.eclipse.escet.tooldef.interpreter;bundle-version="0.10.0",
+ org.eclipse.escet.common.tooldefs;bundle-version="0.10.0"
 Export-Package: org.eclipse.escet.common.tests
 Automatic-Module-Name: org.eclipse.escet.common.tests
diff --git a/common/org.eclipse.escet.common.tooldefs/.settings/org.eclipse.jdt.core.prefs b/common/org.eclipse.escet.common.tooldefs/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/common/org.eclipse.escet.common.tooldefs/.settings/org.eclipse.jdt.core.prefs
+++ b/common/org.eclipse.escet.common.tooldefs/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/common/org.eclipse.escet.common.tooldefs/.settings/org.eclipse.jdt.ui.prefs b/common/org.eclipse.escet.common.tooldefs/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/common/org.eclipse.escet.common.tooldefs/.settings/org.eclipse.jdt.ui.prefs
+++ b/common/org.eclipse.escet.common.tooldefs/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/common/org.eclipse.escet.common.tooldefs/.settings/org.eclipse.ltk.core.refactoring.prefs b/common/org.eclipse.escet.common.tooldefs/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/common/org.eclipse.escet.common.tooldefs/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/common/org.eclipse.escet.common.tooldefs/META-INF/MANIFEST.MF b/common/org.eclipse.escet.common.tooldefs/META-INF/MANIFEST.MF
index 867e84836b4c338ede520bb1e370b5ccdbb49dec..ab6cabcb81997fbcd528fb56354c7e27dd0dbcda 100644
--- a/common/org.eclipse.escet.common.tooldefs/META-INF/MANIFEST.MF
+++ b/common/org.eclipse.escet.common.tooldefs/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Common ToolDefs (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.common.tooldefs;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
diff --git a/common/org.eclipse.escet.common.typechecker/.settings/org.eclipse.jdt.core.prefs b/common/org.eclipse.escet.common.typechecker/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/common/org.eclipse.escet.common.typechecker/.settings/org.eclipse.jdt.core.prefs
+++ b/common/org.eclipse.escet.common.typechecker/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/common/org.eclipse.escet.common.typechecker/.settings/org.eclipse.jdt.ui.prefs b/common/org.eclipse.escet.common.typechecker/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/common/org.eclipse.escet.common.typechecker/.settings/org.eclipse.jdt.ui.prefs
+++ b/common/org.eclipse.escet.common.typechecker/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/common/org.eclipse.escet.common.typechecker/.settings/org.eclipse.ltk.core.refactoring.prefs b/common/org.eclipse.escet.common.typechecker/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/common/org.eclipse.escet.common.typechecker/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/common/org.eclipse.escet.common.typechecker/META-INF/MANIFEST.MF b/common/org.eclipse.escet.common.typechecker/META-INF/MANIFEST.MF
index 04fff7de1d799e792f57c4c5e32bfdc42df95477..9a4410a545f16a2f773a41d9d8a3a7de7d8afec8 100644
--- a/common/org.eclipse.escet.common.typechecker/META-INF/MANIFEST.MF
+++ b/common/org.eclipse.escet.common.typechecker/META-INF/MANIFEST.MF
@@ -2,13 +2,13 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Common Type Checker Functionality (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.common.typechecker;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
 Export-Package: org.eclipse.escet.common.typechecker
-Require-Bundle: org.eclipse.escet.common.position.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.common.emf;bundle-version="0.9.0",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0"
+Require-Bundle: org.eclipse.escet.common.position.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.common.emf;bundle-version="0.10.0",
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0"
 Automatic-Module-Name: org.eclipse.escet.common.typechecker
diff --git a/misc/java-code-style/.settings/org.eclipse.jdt.core.prefs b/misc/java-code-style/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/misc/java-code-style/.settings/org.eclipse.jdt.core.prefs
+++ b/misc/java-code-style/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/misc/java-code-style/.settings/org.eclipse.jdt.ui.prefs b/misc/java-code-style/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/misc/java-code-style/.settings/org.eclipse.jdt.ui.prefs
+++ b/misc/java-code-style/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/misc/java-code-style/.settings/org.eclipse.ltk.core.refactoring.prefs b/misc/java-code-style/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/misc/java-code-style/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/misc/license-check-dependencies/Jenkinsfile b/misc/license-check-dependencies/Jenkinsfile
index 2cd69c5a51ee67c694c4d9d38d2c86a8c852b77e..12c5fa412316700af2495f2cd3bb37513eb419a1 100644
--- a/misc/license-check-dependencies/Jenkinsfile
+++ b/misc/license-check-dependencies/Jenkinsfile
@@ -20,7 +20,7 @@ pipeline {
 
     tools {
         jdk 'openjdk-jdk17-latest'
-        maven 'apache-maven-3.8.4'
+        maven 'apache-maven-3.8.6'
     }
 
     options {
diff --git a/misc/license-header/license-header-check.bash b/misc/license-header/license-header-check.bash
index 414682e9a69e8d927c06d0d870773d1a86906592..6666afb06ebe2945ea22f6cf79911712b6d1c463 100755
--- a/misc/license-header/license-header-check.bash
+++ b/misc/license-header/license-header-check.bash
@@ -62,6 +62,7 @@ EXCLUDE_ARGS="$EXCLUDE_ARGS --exclude=org.eclipse.core.resources.prefs"
 EXCLUDE_ARGS="$EXCLUDE_ARGS --exclude=org.eclipse.jdt.core.prefs"
 EXCLUDE_ARGS="$EXCLUDE_ARGS --exclude=org.eclipse.jdt.launching.prefs"
 EXCLUDE_ARGS="$EXCLUDE_ARGS --exclude=org.eclipse.jdt.ui.prefs"
+EXCLUDE_ARGS="$EXCLUDE_ARGS --exclude=org.eclipse.ltk.core.refactoring.prefs"
 EXCLUDE_ARGS="$EXCLUDE_ARGS --exclude=org.eclipse.m2e.core.prefs"
 EXCLUDE_ARGS="$EXCLUDE_ARGS --exclude=org.eclipse.pde.core.prefs"
 EXCLUDE_ARGS="$EXCLUDE_ARGS --exclude=org.eclipse.pde.prefs"
@@ -203,6 +204,7 @@ POST_EXCLUDE_PATTERN="$POST_EXCLUDE_PATTERN|^./tooldef/org.eclipse.escet.tooldef
 POST_EXCLUDE_PATTERN="$POST_EXCLUDE_PATTERN|^./tooldef/org.eclipse.escet.tooldef.metamodel/model/autofix.py:2$"
 # Exclude files that have an associated license file.
 POST_EXCLUDE_PATTERN="$POST_EXCLUDE_PATTERN|^./cif/org.eclipse.escet.cif.cif2plc/src/org/eclipse/escet/cif/cif2plc/writers/tc6_xml_v201.xsd:0$"
+POST_EXCLUDE_PATTERN="$POST_EXCLUDE_PATTERN|^./cif/org.eclipse.escet.cif.plcgen/src/org/eclipse/escet/cif/plcgen/writers/tc6_xml_v201.xsd:0$"
 # Exclude files literally included in documentation.
 POST_EXCLUDE_PATTERN="$POST_EXCLUDE_PATTERN|^./cif/org.eclipse.escet.cif.documentation/images/language-reference/syntax/cif.bnf:0$"
 POST_EXCLUDE_PATTERN="$POST_EXCLUDE_PATTERN|^./cif/org.eclipse.escet.cif.documentation/images/tools/cifsim/output/svgviz/buffers_products/buffers_products.svg:0$"
diff --git a/misc/website/remove-website-version.bash b/misc/website/remove-website-version.bash
new file mode 100755
index 0000000000000000000000000000000000000000..3ed88198129e8878bd41a7f14f5ae760c7912a6e
--- /dev/null
+++ b/misc/website/remove-website-version.bash
@@ -0,0 +1,64 @@
+#!/usr/bin/env bash
+
+################################################################################
+# Copyright (c) 2022, 2023 Contributors to the Eclipse Foundation
+#
+# See the NOTICE file(s) distributed with this work for additional
+# information regarding copyright ownership.
+#
+# This program and the accompanying materials are made available under the terms
+# of the MIT License which is available at https://opensource.org/licenses/MIT
+#
+# SPDX-License-Identifier: MIT
+################################################################################
+
+# For usage information, see the Eclipse ESCET developer documentation 'Release process' page.
+
+set -e -u
+#set -x
+
+# Check command line arguments.
+if [ $# -ne 3 ]; then
+    >&2 echo "Usage: $0 <website-version-to-remove> <eclipse-account-full-name> <eclipse-account-email>"
+    exit 1
+fi
+
+# Get arguments. For the website version to remove, remove any trailing '/' if present.
+VERSION_TO_REMOVE=${1%/}
+ECLIPSE_ACCOUNT_FULLNAME=$2
+ECLIPSE_ACCOUNT_EMAIL=$3
+
+# Make sure the website version to remove exists.
+if [ ! -d ${VERSION_TO_REMOVE} ]; then
+    >&2 echo "Website directory \"${VERSION_TO_REMOVE}\" does not exist. Failed to remove it."
+    exit 1
+fi
+
+# Ensure version being removed is not the current standard visible website.
+CUR_VISIBLE_VERSION=$(<.standard_visible_website_version)
+if [ "${VERSION_TO_REMOVE}" == "${CUR_VISIBLE_VERSION}" ]; then
+    >&2 echo "Website directory \"${VERSION_TO_REMOVE}\" is the current standard visible website. It can not be removed."
+    exit 1
+fi
+
+# Ensure version being removed is a milestone or release candidate website.
+if ! [[ "${VERSION_TO_REMOVE}" =~ ^v[0-9]+(\.[0-9]+){1,2}-(M|RC)[0-9]+$ ]]; then
+    >&2 echo "Website directory \"${VERSION_TO_REMOVE}\" can not be removed, as it is not a milestone or release candidate website."
+    exit 1
+fi
+
+# Remove website directory.
+echo "Removing website directory..."
+rm -rf ${VERSION_TO_REMOVE}/
+
+# Stage all changes.
+git add -A
+
+# Commit changes.
+echo "Committing changes..."
+COMMIT_MSG="Removed website version ${VERSION_TO_REMOVE}."
+GIT_COMMITTER_NAME="$ECLIPSE_ACCOUNT_FULLNAME" GIT_COMMITTER_EMAIL="$ECLIPSE_ACCOUNT_EMAIL" \
+        git commit --author="$ECLIPSE_ACCOUNT_FULLNAME <$ECLIPSE_ACCOUNT_EMAIL>" -m "${COMMIT_MSG}"
+echo
+echo ${COMMIT_MSG}
+echo "Review the last commit before pushing it."
diff --git a/misc/website/switch-standard-visible-website.bash b/misc/website/switch-standard-visible-website.bash
index b4b39f1ff60af7bac73b7c3417ab238da4f4b652..43a517dc938094dab17453a599562afef6fdba80 100755
--- a/misc/website/switch-standard-visible-website.bash
+++ b/misc/website/switch-standard-visible-website.bash
@@ -56,7 +56,9 @@ echo ${VERSION_TO_MAKE_DEFAULT} > $FILENAME_VERSION
 echo "Replacing version-specific URLs in HTML files..."
 WEBSITES_FILES_AND_DIRS=$(cat $FILENAME_CONTENTS)
 find $WEBSITES_FILES_AND_DIRS -type f -iname "*.html" -print0 | \
-    xargs -0 sed -i "s@https://eclipse.org/escet/${VERSION_TO_MAKE_DEFAULT}/@https://eclipse.org/escet/@g"
+    xargs -0 sed -i "s@https://eclipse.dev/escet/${VERSION_TO_MAKE_DEFAULT}/@https://eclipse.dev/escet/@g"
+find $WEBSITES_FILES_AND_DIRS -type f -iname "*.html" -print0 | \
+    xargs -0 sed -i "s@https://www.eclipse.dev/escet/${VERSION_TO_MAKE_DEFAULT}/@https://eclipse.dev/escet/@g"
 
 # Remove robots meta tag.
 echo "Removing robots meta tag in HTML files..."
@@ -77,7 +79,8 @@ set -e
 if [ $CHANGES -eq 1 ]; then
     echo "Committing changes..."
     COMMIT_MSG="Set standard visible website to release ${VERSION_TO_MAKE_DEFAULT}."
-    git commit --author="$ECLIPSE_ACCOUNT_FULLNAME <$ECLIPSE_ACCOUNT_EMAIL>" -m "${COMMIT_MSG}"
+    GIT_COMMITTER_NAME="$ECLIPSE_ACCOUNT_FULLNAME" GIT_COMMITTER_EMAIL="$ECLIPSE_ACCOUNT_EMAIL" \
+            git commit --author="$ECLIPSE_ACCOUNT_FULLNAME <$ECLIPSE_ACCOUNT_EMAIL>" -m "${COMMIT_MSG}"
     echo
     echo ${COMMIT_MSG}
     echo "Review the last commit before pushing it."
diff --git a/org.eclipse.escet.setup b/org.eclipse.escet.setup
index 8b21bfdf6111d063909003404d24ec782f2370c3..bb31eeb5d9464881a4a474435d316d5406ab420d 100644
--- a/org.eclipse.escet.setup
+++ b/org.eclipse.escet.setup
@@ -4,23 +4,15 @@
     xmlns:xmi="http://www.omg.org/XMI"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:git="http://www.eclipse.org/oomph/setup/git/1.0"
+    xmlns:pde="http://www.eclipse.org/oomph/setup/pde/1.0"
     xmlns:predicates="http://www.eclipse.org/oomph/predicates/1.0"
     xmlns:projects="http://www.eclipse.org/oomph/setup/projects/1.0"
     xmlns:setup="http://www.eclipse.org/oomph/setup/1.0"
     xmlns:setup.p2="http://www.eclipse.org/oomph/setup/p2/1.0"
-    xmlns:setup.targlets="http://www.eclipse.org/oomph/setup/targlets/1.0"
     xmlns:setup.workingsets="http://www.eclipse.org/oomph/setup/workingsets/1.0"
-    xsi:schemaLocation="http://www.eclipse.org/oomph/setup/git/1.0 http://git.eclipse.org/c/oomph/org.eclipse.oomph.git/plain/setups/models/Git.ecore http://www.eclipse.org/oomph/predicates/1.0 http://git.eclipse.org/c/oomph/org.eclipse.oomph.git/plain/setups/models/Predicates.ecore http://www.eclipse.org/oomph/setup/projects/1.0 http://git.eclipse.org/c/oomph/org.eclipse.oomph.git/plain/setups/models/Projects.ecore http://www.eclipse.org/oomph/setup/targlets/1.0 http://git.eclipse.org/c/oomph/org.eclipse.oomph.git/plain/setups/models/SetupTarglets.ecore http://www.eclipse.org/oomph/setup/workingsets/1.0 http://git.eclipse.org/c/oomph/org.eclipse.oomph.git/plain/setups/models/SetupWorkingSets.ecore"
+    xsi:schemaLocation="http://www.eclipse.org/oomph/setup/git/1.0 http://git.eclipse.org/c/oomph/org.eclipse.oomph.git/plain/setups/models/Git.ecore http://www.eclipse.org/oomph/setup/pde/1.0 http://git.eclipse.org/c/oomph/org.eclipse.oomph.git/plain/setups/models/PDE.ecore http://www.eclipse.org/oomph/predicates/1.0 http://git.eclipse.org/c/oomph/org.eclipse.oomph.git/plain/setups/models/Predicates.ecore http://www.eclipse.org/oomph/setup/projects/1.0 http://git.eclipse.org/c/oomph/org.eclipse.oomph.git/plain/setups/models/Projects.ecore http://www.eclipse.org/oomph/setup/workingsets/1.0 http://git.eclipse.org/c/oomph/org.eclipse.oomph.git/plain/setups/models/SetupWorkingSets.ecore"
     name="escet"
     label="Eclipse ESCET">
-  <setupTask
-      xsi:type="setup:VariableTask"
-      name="eclipse.ide.version"
-      value="2022-06"/>
-  <setupTask
-      xsi:type="setup:VariableTask"
-      name="eclipse.orbit.version"
-      value="R20220531185310"/>
   <setupTask
       xsi:type="setup:VariableTask"
       name="eclipse-checkstyle.version.major"
@@ -29,18 +21,6 @@
       xsi:type="setup:VariableTask"
       name="eclipse-checkstyle.version.minor"
       value="41"/>
-  <setupTask
-      xsi:type="setup:VariableTask"
-      name="eclipse.justj.version.major"
-      value="17"/>
-  <setupTask
-      xsi:type="setup:VariableTask"
-      name="eclipse.justj.version.minor"
-      value="0"/>
-  <setupTask
-      xsi:type="setup:VariableTask"
-      name="eclipse.justj.version.micro"
-      value="5"/>
   <setupTask
       xsi:type="setup:VariableTask"
       name="eclipse.target.platform"
@@ -233,6 +213,14 @@
           key="/instance/org.eclipse.ui.ide/WORKSPACE_NAME"
           value="${scope.project.label} development"/>
     </setupTask>
+    <setupTask
+        xsi:type="setup:CompoundTask"
+        name="org.eclipse.wildwebdeveloper.xml">
+      <setupTask
+          xsi:type="setup:PreferenceTask"
+          key="/instance/org.eclipse.wildwebdeveloper.xml/validation.noGrammar"
+          value="ignore"/>
+    </setupTask>
     <setupTask
         xsi:type="setup:CompoundTask"
         name="org.eclipse.wst.xml.core">
@@ -276,6 +264,8 @@
         name="org.eclipse.emf.sdk.feature.group"/>
     <requirement
         name="org.eclipse.m2e.feature.feature.group"/>
+    <requirement
+        name="org.eclipse.m2e.pde.feature.feature.group"/>
     <requirement
         name="org.eclipse.oomph.setup.sdk.feature.group"/>
     <requirement
@@ -325,136 +315,8 @@
         locateNestedProjects="true"/>
   </setupTask>
   <setupTask
-      xsi:type="setup.targlets:TargletTask">
-    <targlet
-        name="${scope.project.label}"
-        activeRepositoryList="Eclipse ESCET">
-      <annotation
-          source="http:/www.eclipse.org/oomph/targlets/TargetDefinitionGenerator">
-        <detail
-            key="location">
-          <value>${org.eclipse.escet.git.clone.location}/releng/org.eclipse.escet.releng.target/org.eclipse.escet.releng.target.target</value>
-        </detail>
-        <detail
-            key="extraUnits">
-          <value>org.eclipse.equinox.executable.feature.group</value>
-        </detail>
-        <detail
-            key="generateImplicitUnits">
-          <value>true</value>
-        </detail>
-        <detail
-            key="minimizeImplicitUnits">
-          <value>true</value>
-        </detail>
-        <detail
-            key="includeMode">
-          <value>planner</value>
-        </detail>
-        <detail
-            key="generateVersions">
-          <value>false</value>
-        </detail>
-        <detail
-            key="includeAllPlatforms">
-          <value>false</value>
-        </detail>
-        <detail
-            key="includeSource">
-          <value>true</value>
-        </detail>
-      </annotation>
-      <requirement
-          name="com.google.guava"/>
-      <requirement
-          name="io.github.java-diff-utils"/>
-      <requirement
-          name="javax.inject"/>
-      <requirement
-          name="org.apache.batik.anim"/>
-      <requirement
-          name="org.apache.batik.awt.util"/>
-      <requirement
-          name="org.apache.batik.bridge"/>
-      <requirement
-          name="org.apache.batik.codec"/>
-      <requirement
-          name="org.apache.batik.constants"/>
-      <requirement
-          name="org.apache.batik.css"/>
-      <requirement
-          name="org.apache.batik.dom"/>
-      <requirement
-          name="org.apache.batik.dom.svg"/>
-      <requirement
-          name="org.apache.batik.ext"/>
-      <requirement
-          name="org.apache.batik.gvt"/>
-      <requirement
-          name="org.apache.batik.i18n"/>
-      <requirement
-          name="org.apache.batik.parser"/>
-      <requirement
-          name="org.apache.batik.script"/>
-      <requirement
-          name="org.apache.batik.shared.resources"/>
-      <requirement
-          name="org.apache.batik.svggen"/>
-      <requirement
-          name="org.apache.batik.transcoder"/>
-      <requirement
-          name="org.apache.batik.util"/>
-      <requirement
-          name="org.apache.batik.xml"/>
-      <requirement
-          name="org.apache.commons.exec"/>
-      <requirement
-          name="org.apache.commons.io"/>
-      <requirement
-          name="org.apache.commons.lang3"/>
-      <requirement
-          name="org.apache.commons.math3"/>
-      <requirement
-          name="org.apache.xalan"/>
-      <requirement
-          name="org.apache.xerces"/>
-      <requirement
-          name="org.apache.xml.resolver"
-          versionRange="[1.2.0.v201005080400,1.2.0.v201005080400]"/>
-      <requirement
-          name="org.apache.xml.serializer"/>
-      <requirement
-          name="org.eclipse.emf.feature.group"/>
-      <requirement
-          name="org.eclipse.emf.validation"/>
-      <requirement
-          name="org.eclipse.epp.mpc.feature.group"/>
-      <requirement
-          name="org.eclipse.justj.openjdk.hotspot.jre.full.feature.group"/>
-      <requirement
-          name="org.eclipse.sdk.feature.group"/>
-      <requirement
-          name="org.jsoup"/>
-      <requirement
-          name="org.knowm.xchart"/>
-      <requirement
-          name="*"/>
-      <sourceLocator
-          rootFolder="${org.eclipse.escet.git.clone.location}"
-          locateNestedProjects="true"/>
-      <repositoryList
-          name="Eclipse ESCET">
-        <repository
-            url="https://download.eclipse.org/releases/${eclipse.ide.version}"/>
-        <repository
-            url="https://download.eclipse.org/tools/orbit/downloads/drops/${eclipse.orbit.version}/repository"/>
-        <repository
-            url="https://download.eclipse.org/justj/jres/${eclipse.justj.version.major}/updates/release/${eclipse.justj.version.major}.${eclipse.justj.version.minor}.${eclipse.justj.version.micro}"/>
-        <repository
-            url="https://download.eclipse.org/tools/orbit/downloads/drops/R20220302172233/repository"/>
-      </repositoryList>
-    </targlet>
-  </setupTask>
+      xsi:type="pde:TargetPlatformTask"
+      name="Eclipse ESCET Target Platform"/>
   <setupTask
       xsi:type="setup.workingsets:WorkingSetTask">
     <workingSet
diff --git a/pom.xml b/pom.xml
index b7e509c3a2b1caadf009a3c46c1d9e2ac42ce76f..1794b0ae41840e846eda0a28b93ddc9a570431c5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.eclipse.escet</groupId>
         <artifactId>org.eclipse.escet.releng.configuration</artifactId>
-        <version>0.9.0-SNAPSHOT</version>
+        <version>0.10.0-SNAPSHOT</version>
         <relativePath>./releng/org.eclipse.escet.releng.configuration</relativePath>
     </parent>
 
diff --git a/product/org.eclipse.escet.product.branding/META-INF/MANIFEST.MF b/product/org.eclipse.escet.product.branding/META-INF/MANIFEST.MF
index 8b272de517d2a84945eba08759ae2cfae7eac5b7..646aedb91bf74ddc9b8855348d4701f5a58db5f7 100644
--- a/product/org.eclipse.escet.product.branding/META-INF/MANIFEST.MF
+++ b/product/org.eclipse.escet.product.branding/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: Eclipse ESCET (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.product.branding;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-17
diff --git a/product/org.eclipse.escet.product.branding/plugin_customization.ini b/product/org.eclipse.escet.product.branding/plugin_customization.ini
index 462484a8897c258d5a92b771f58219052deeda76..988254c4aacb8d5d477d192a2c47bd2b7225c491 100644
--- a/product/org.eclipse.escet.product.branding/plugin_customization.ini
+++ b/product/org.eclipse.escet.product.branding/plugin_customization.ini
@@ -33,6 +33,9 @@ org.eclipse.ui/DOCK_PERSPECTIVE_BAR=topRight
 # Use UTF-8 encoding.
 org.eclipse.core.resources/encoding=UTF-8
 
+# No warnings for projects that don't specify their own encoding.
+org.eclipse.core.resources/missingEncodingMarkerSeverity=-1
+
 # Lightweight auto-refresh on access by default.
 #org.eclipse.core.resources/refresh.lightweight.enabled=true
 
diff --git a/product/org.eclipse.escet.product.branding/pom.xml b/product/org.eclipse.escet.product.branding/pom.xml
index 1eb610a5583d3b94e23f6fda411a06623f62d098..8b3f4db898c53d187748c203249da5e80b898089 100644
--- a/product/org.eclipse.escet.product.branding/pom.xml
+++ b/product/org.eclipse.escet.product.branding/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.eclipse.escet</groupId>
         <artifactId>org.eclipse.escet.root</artifactId>
-        <version>0.9.0-SNAPSHOT</version>
+        <version>0.10.0-SNAPSHOT</version>
         <relativePath>../../</relativePath>
     </parent>
 
diff --git a/product/org.eclipse.escet.product.feature/feature.xml b/product/org.eclipse.escet.product.feature/feature.xml
index 10cbdfa1a2337a99f232e96a04a549e3b1b80840..ded61796903849a2372d765b2b4933ffd667b2b5 100644
--- a/product/org.eclipse.escet.product.feature/feature.xml
+++ b/product/org.eclipse.escet.product.feature/feature.xml
@@ -13,11 +13,11 @@
 <feature
       id="org.eclipse.escet.product.feature"
       label="Eclipse ESCET (Incubation)"
-      version="0.9.0.qualifier"
+      version="0.10.0.qualifier"
       provider-name="Eclipse ESCET"
       plugin="org.eclipse.escet.product.branding"
       license-feature="org.eclipse.escet.releng.license.mit"
-      license-feature-version="0.9.0.qualifier">
+      license-feature-version="0.10.0.qualifier">
 
    <description>
       Eclipse Supervisory Control Engineering Toolkit (Eclipse ESCET).
@@ -52,9 +52,10 @@
          version="0.0.0"/>
 
    <requires>
-      <import feature="org.eclipse.platform" version="4.24.0" match="compatible"/>
+      <import feature="org.eclipse.platform" version="4.27.0" match="compatible"/>
       <import feature="org.eclipse.justj.openjdk.hotspot.jre.full" version="17.0.5" match="compatible"/>
       <import feature="org.eclipse.epp.mpc"/>
+      <import plugin="org.eclipse.pde.runtime"/>
    </requires>
 
    <plugin
diff --git a/product/org.eclipse.escet.product.headless.feature/build.properties b/product/org.eclipse.escet.product.headless.feature/build.properties
index 9c4a75add19bac2bad2f7fad5ff51469376d83d1..941241e2a67a3666112ccae9d29c22f5e4d838d9 100644
--- a/product/org.eclipse.escet.product.headless.feature/build.properties
+++ b/product/org.eclipse.escet.product.headless.feature/build.properties
@@ -17,4 +17,4 @@ root.win32.win32.x86_64.folder.bin=target/bin/win32.win32.x86_64,legal
 root.linux.gtk.x86_64.folder.bin=target/bin/linux.gtk.x86_64,legal
 
 # Permissions and links works if product is built on Linux (will not work if built on Windows).
-root.linux.gtk.x86_64.permissions.755=bin/chi*,bin/cif*,bin/setext*,bin/tooldef*
+root.linux.gtk.x86_64.permissions.755=bin/chi*,bin/cif*,bin/setext*,bin/tooldef*,bin/dsmclustering
diff --git a/product/org.eclipse.escet.product.headless.feature/feature.xml b/product/org.eclipse.escet.product.headless.feature/feature.xml
index a19b144ec170474fc64c1821fb4183f484aa0914..282fbd09a2a26234644d393a93ae27c5af0003e8 100644
--- a/product/org.eclipse.escet.product.headless.feature/feature.xml
+++ b/product/org.eclipse.escet.product.headless.feature/feature.xml
@@ -13,10 +13,10 @@
 <feature
       id="org.eclipse.escet.product.headless.feature"
       label="ESCET Headless (Incubation)"
-      version="0.9.0.qualifier"
+      version="0.10.0.qualifier"
       provider-name="Eclipse ESCET"
       license-feature="org.eclipse.escet.releng.license.mit"
-      license-feature-version="0.9.0.qualifier">
+      license-feature-version="0.10.0.qualifier">
 
    <description>
       Eclipse ESCET headless execution support.
diff --git a/product/org.eclipse.escet.product.headless.feature/pom.xml b/product/org.eclipse.escet.product.headless.feature/pom.xml
index 5f3bd79923ba5ab4aa306a604c0e1591468e00cb..8008ab375cc54b7c19d29cca13752e96460c92c2 100644
--- a/product/org.eclipse.escet.product.headless.feature/pom.xml
+++ b/product/org.eclipse.escet.product.headless.feature/pom.xml
@@ -17,12 +17,12 @@
     <parent>
         <groupId>org.eclipse.escet</groupId>
         <artifactId>org.eclipse.escet.root</artifactId>
-        <version>0.9.0-SNAPSHOT</version>
+        <version>0.10.0-SNAPSHOT</version>
         <relativePath>../../</relativePath>
     </parent>
 
     <artifactId>org.eclipse.escet.product.headless.feature</artifactId>
-    <version>0.9.0-SNAPSHOT</version>
+    <version>0.10.0-SNAPSHOT</version>
     <packaging>eclipse-feature</packaging>
 
     <!-- Execute Groovy script to generate headless execution scripts for product. -->
diff --git a/product/org.eclipse.escet.product.headless.feature/src/create_scripts.json b/product/org.eclipse.escet.product.headless.feature/src/create_scripts.json
index 11fcbb7e87601de7a2758dd8d952375f72f11cd8..bb5b2c2c84cce129f12b35de0d5b5a92716c297c 100644
--- a/product/org.eclipse.escet.product.headless.feature/src/create_scripts.json
+++ b/product/org.eclipse.escet.product.headless.feature/src/create_scripts.json
@@ -83,22 +83,22 @@
         },
         {
             "script_name": "cifprod",
-            "plugin_name": "org.eclipse.escet.cif.eventbased.apps",
+            "plugin_name": "org.eclipse.escet.cif.eventbased",
             "class_name": "org.eclipse.escet.cif.eventbased.apps.SynchronousProductApplication"
         },
         {
             "script_name": "cifsupsynth",
-            "plugin_name": "org.eclipse.escet.cif.eventbased.apps",
+            "plugin_name": "org.eclipse.escet.cif.eventbased",
             "class_name": "org.eclipse.escet.cif.eventbased.apps.SupervisorSynthesisApplication"
         },
         {
             "script_name": "cifsynthanalys",
-            "plugin_name": "org.eclipse.escet.cif.eventbased.apps",
+            "plugin_name": "org.eclipse.escet.cif.eventbased",
             "class_name": "org.eclipse.escet.cif.eventbased.apps.SynthesisAnalysisApplication"
         },
         {
             "script_name": "cifncchk",
-            "plugin_name": "org.eclipse.escet.cif.eventbased.apps",
+            "plugin_name": "org.eclipse.escet.cif.eventbased",
             "class_name": "org.eclipse.escet.cif.eventbased.apps.NonconflictingCheckApplication"
         },
         {
@@ -108,47 +108,47 @@
         },
         {
             "script_name": "cifctrlchk",
-            "plugin_name": "org.eclipse.escet.cif.eventbased.apps",
+            "plugin_name": "org.eclipse.escet.cif.eventbased",
             "class_name": "org.eclipse.escet.cif.eventbased.apps.ControllabilityCheckApplication"
         },
         {
             "script_name": "ciflngeqv",
-            "plugin_name": "org.eclipse.escet.cif.eventbased.apps",
+            "plugin_name": "org.eclipse.escet.cif.eventbased",
             "class_name": "org.eclipse.escet.cif.eventbased.apps.LanguageEquivalenceCheckApplication"
         },
         {
             "script_name": "cifnfadfa",
-            "plugin_name": "org.eclipse.escet.cif.eventbased.apps",
+            "plugin_name": "org.eclipse.escet.cif.eventbased",
             "class_name": "org.eclipse.escet.cif.eventbased.apps.NfaToDfaApplication"
         },
         {
             "script_name": "cifdfamin",
-            "plugin_name": "org.eclipse.escet.cif.eventbased.apps",
+            "plugin_name": "org.eclipse.escet.cif.eventbased",
             "class_name": "org.eclipse.escet.cif.eventbased.apps.DfaMinimizationApplication"
         },
         {
             "script_name": "cifproj",
-            "plugin_name": "org.eclipse.escet.cif.eventbased.apps",
+            "plugin_name": "org.eclipse.escet.cif.eventbased",
             "class_name": "org.eclipse.escet.cif.eventbased.apps.ProjectionApplication"
         },
         {
             "script_name": "cifobschk",
-            "plugin_name": "org.eclipse.escet.cif.eventbased.apps",
+            "plugin_name": "org.eclipse.escet.cif.eventbased",
             "class_name": "org.eclipse.escet.cif.eventbased.apps.ObserverCheckApplication"
         },
         {
             "script_name": "cifabstr",
-            "plugin_name": "org.eclipse.escet.cif.eventbased.apps",
+            "plugin_name": "org.eclipse.escet.cif.eventbased",
             "class_name": "org.eclipse.escet.cif.eventbased.apps.AutomatonAbstractionApplication"
         },
         {
             "script_name": "ciftrimchk",
-            "plugin_name": "org.eclipse.escet.cif.eventbased.apps",
+            "plugin_name": "org.eclipse.escet.cif.eventbased",
             "class_name": "org.eclipse.escet.cif.eventbased.apps.TrimCheckApplication"
         },
         {
             "script_name": "ciftrim",
-            "plugin_name": "org.eclipse.escet.cif.eventbased.apps",
+            "plugin_name": "org.eclipse.escet.cif.eventbased",
             "class_name": "org.eclipse.escet.cif.eventbased.apps.TrimApplication"
         }
     ],
diff --git a/product/org.eclipse.escet.product.perspective/.settings/org.eclipse.jdt.core.prefs b/product/org.eclipse.escet.product.perspective/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/product/org.eclipse.escet.product.perspective/.settings/org.eclipse.jdt.core.prefs
+++ b/product/org.eclipse.escet.product.perspective/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/product/org.eclipse.escet.product.perspective/.settings/org.eclipse.jdt.ui.prefs b/product/org.eclipse.escet.product.perspective/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/product/org.eclipse.escet.product.perspective/.settings/org.eclipse.jdt.ui.prefs
+++ b/product/org.eclipse.escet.product.perspective/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/product/org.eclipse.escet.product.perspective/.settings/org.eclipse.ltk.core.refactoring.prefs b/product/org.eclipse.escet.product.perspective/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/product/org.eclipse.escet.product.perspective/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/product/org.eclipse.escet.product.perspective/META-INF/MANIFEST.MF b/product/org.eclipse.escet.product.perspective/META-INF/MANIFEST.MF
index 0855f9499cb0e4cfa3f084809315c70d8d71a9d4..51fd2d5280d67849dd97514d50ef0c73717d79bb 100644
--- a/product/org.eclipse.escet.product.perspective/META-INF/MANIFEST.MF
+++ b/product/org.eclipse.escet.product.perspective/META-INF/MANIFEST.MF
@@ -2,12 +2,12 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Perspective (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.product.perspective;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Require-Bundle: org.eclipse.ui;bundle-version="3.115.0",
  org.eclipse.core.runtime;bundle-version="3.17.0",
  org.eclipse.core.resources;bundle-version="3.13.600",
  org.eclipse.ui.console;bundle-version="3.9.0",
- org.eclipse.escet.common.app.framework.appsview.ui;bundle-version="0.9.0"
+ org.eclipse.escet.common.app.framework.appsview.ui;bundle-version="0.10.0"
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
 Bundle-Vendor: Eclipse ESCET
diff --git a/product/org.eclipse.escet.product/category.xml b/product/org.eclipse.escet.product/category.xml
index 1f8f96c5505f17efb118509763da1ef4e944e65d..f4a08a6d3fe3595a99e76c8f225638a79ec4a055 100644
--- a/product/org.eclipse.escet.product/category.xml
+++ b/product/org.eclipse.escet.product/category.xml
@@ -11,12 +11,6 @@
  -->
 
 <site>
-   <feature id="com.github.javabdd.feature">
-      <category name="org.eclipse.escet.thirdparty.category"/>
-   </feature>
-   <feature id="com.github.javabdd.feature.source">
-      <category name="org.eclipse.escet.thirdparty.category"/>
-   </feature>
    <feature id="org.eclipse.escet.chi.feature">
       <category name="org.eclipse.escet.chi.category"/>
    </feature>
@@ -41,6 +35,12 @@
    <feature id="org.eclipse.escet.setext.feature.source">
       <category name="org.eclipse.escet.setext.category"/>
    </feature>
+   <feature id="org.eclipse.escet.thirdparty.feature">
+      <category name="org.eclipse.escet.thirdparty.category"/>
+   </feature>
+   <feature id="org.eclipse.escet.thirdparty.feature.source">
+      <category name="org.eclipse.escet.thirdparty.category"/>
+   </feature>
    <feature id="org.eclipse.escet.tooldef.feature">
       <category name="org.eclipse.escet.tooldef.category"/>
    </feature>
@@ -79,7 +79,7 @@
    <category-def name="org.eclipse.escet.thirdparty.category" label="Eclipse ESCET Third Party (Incubation)">
       <category name="org.eclipse.escet.category"/>
       <description>
-         Eclipse ESCET third party dependencies that are distributed by the Eclipse ESCET project itself.
+         Eclipse ESCET third party dependencies that are redistributed by the Eclipse ESCET project.
       </description>
    </category-def>
    <category-def name="org.eclipse.escet.tooldef.category" label="Eclipse ESCET ToolDef (Incubation)">
@@ -88,6 +88,6 @@
          Eclipse ESCET tooling for the ToolDef scripting language.
       </description>
    </category-def>
-   <repository-reference location="https://download.eclipse.org/releases/2022-06" enabled="true" />
-   <repository-reference location="https://download.eclipse.org/tools/orbit/downloads/drops/R20220531185310/repository" enabled="true" />
+   <repository-reference location="https://download.eclipse.org/releases/2023-03" enabled="true" />
+   <repository-reference location="https://download.eclipse.org/tools/orbit/downloads/drops/R20230302014618/repository" enabled="true" />
 </site>
diff --git a/product/org.eclipse.escet.product/escet-dev-runtime.launch b/product/org.eclipse.escet.product/escet-dev-runtime.launch
index d8ee893e35d05b1354e72f141ff5e71a65abe848..1d09c76f39e285539c3a7a1897e574cb3f2d7a9f 100644
--- a/product/org.eclipse.escet.product/escet-dev-runtime.launch
+++ b/product/org.eclipse.escet.product/escet-dev-runtime.launch
@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <launchConfiguration type="org.eclipse.pde.ui.RuntimeWorkbench">
     <setAttribute key="additional_plugins">
-        <setEntry value="org.apache.felix.scr:2.1.24.v20200924-1939:default:true:2:true"/>
-        <setEntry value="org.eclipse.core.runtime:3.25.0.v20220506-1157:default:true:default:true"/>
-        <setEntry value="org.eclipse.equinox.common:3.16.100.v20220315-2327:default:true:2:true"/>
-        <setEntry value="org.eclipse.equinox.event:1.6.100.v20211021-1418:default:true:2:true"/>
-        <setEntry value="org.eclipse.equinox.simpleconfigurator:1.4.0.v20210315-2228:default:true:1:true"/>
+        <setEntry value="org.apache.felix.scr:2.2.6:default:true:2:true"/>
+        <setEntry value="org.eclipse.core.runtime:3.26.100.v20221021-0005:default:true:default:true"/>
+        <setEntry value="org.eclipse.equinox.common:3.17.100.v20230202-1341:default:true:2:true"/>
+        <setEntry value="org.eclipse.equinox.event:1.6.200.v20230120-0604:default:true:2:true"/>
+        <setEntry value="org.eclipse.equinox.simpleconfigurator:1.4.200.v20221111-1340:default:true:1:true"/>
     </setAttribute>
     <booleanAttribute key="append.args" value="true"/>
     <booleanAttribute key="askclear" value="true"/>
@@ -22,6 +22,7 @@
     <stringAttribute key="featurePluginResolution" value="workspace"/>
     <booleanAttribute key="includeOptional" value="true"/>
     <stringAttribute key="location" value="${workspace_loc}/../runtime-escet-dev"/>
+    <booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
     <booleanAttribute key="org.eclipse.jdt.launching.ATTR_ATTR_USE_ARGFILE" value="false"/>
     <booleanAttribute key="org.eclipse.jdt.launching.ATTR_SHOW_CODEDETAILS_IN_EXCEPTION_MESSAGES" value="true"/>
     <stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17"/>
diff --git a/product/org.eclipse.escet.product/escet-product.launch b/product/org.eclipse.escet.product/escet-product.launch
index 4e59d11b88b24b3387f78d70121623b2ce1a31db..a83c79fba99e83a4d934968ba1b0fe3e8d2839d0 100644
--- a/product/org.eclipse.escet.product/escet-product.launch
+++ b/product/org.eclipse.escet.product/escet-product.launch
@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <launchConfiguration type="org.eclipse.pde.ui.RuntimeWorkbench">
     <setAttribute key="additional_plugins">
-        <setEntry value="org.apache.felix.scr:2.1.24.v20200924-1939:default:false:2:true"/>
-        <setEntry value="org.eclipse.core.runtime:3.25.0.v20220506-1157:default:false:default:true"/>
-        <setEntry value="org.eclipse.equinox.common:3.16.100.v20220315-2327:default:false:2:true"/>
-        <setEntry value="org.eclipse.equinox.event:1.6.100.v20211021-1418:default:false:2:true"/>
-        <setEntry value="org.eclipse.equinox.simpleconfigurator:1.4.0.v20210315-2228:default:false:1:true"/>
+        <setEntry value="org.apache.felix.scr:2.2.6:default:true:2:true"/>
+        <setEntry value="org.eclipse.core.runtime:3.26.100.v20221021-0005:default:true:default:true"/>
+        <setEntry value="org.eclipse.equinox.common:3.17.100.v20230202-1341:default:true:2:true"/>
+        <setEntry value="org.eclipse.equinox.event:1.6.200.v20230120-0604:default:true:2:true"/>
+        <setEntry value="org.eclipse.equinox.simpleconfigurator:1.4.200.v20221111-1340:default:true:1:true"/>
     </setAttribute>
     <booleanAttribute key="append.args" value="true"/>
     <booleanAttribute key="askclear" value="true"/>
@@ -22,6 +22,7 @@
     <stringAttribute key="featurePluginResolution" value="workspace"/>
     <booleanAttribute key="includeOptional" value="true"/>
     <stringAttribute key="location" value="${workspace_loc}/../runtime-escet-product"/>
+    <booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
     <booleanAttribute key="org.eclipse.jdt.launching.ATTR_ATTR_USE_ARGFILE" value="false"/>
     <booleanAttribute key="org.eclipse.jdt.launching.ATTR_SHOW_CODEDETAILS_IN_EXCEPTION_MESSAGES" value="true"/>
     <stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17"/>
diff --git a/product/org.eclipse.escet.product/escet.product b/product/org.eclipse.escet.product/escet.product
index 098e1b51ea38a90fb1a546b6bbe4e006f4b38a46..c907069de3f0c3d933a4c8c4506690455ed18ba4 100644
--- a/product/org.eclipse.escet.product/escet.product
+++ b/product/org.eclipse.escet.product/escet.product
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <?pde version="3.5"?>
 
-<product name="Eclipse ESCET (Incubation)" uid="org.eclipse.escet.product" id="org.eclipse.escet.product.branding.product" application="org.eclipse.ui.ide.workbench" version="0.9.0.qualifier" useFeatures="true" includeLaunchers="true">
+<product name="Eclipse ESCET (Incubation)" uid="org.eclipse.escet.product" id="org.eclipse.escet.product.branding.product" application="org.eclipse.ui.ide.workbench" version="0.10.0.qualifier" useFeatures="true" includeLaunchers="true" autoIncludeRequirements="true">
 
    <aboutInfo>
       <image path="/org.eclipse.escet.product.branding/images/escet_about.png"/>
@@ -66,7 +66,7 @@ IN THE SOFTWARE.
    </plugins>
 
    <features>
-      <feature id="org.eclipse.escet.product.feature" version="0.9.0.qualifier"/>
+      <feature id="org.eclipse.escet.product.feature" version="0.10.0.qualifier"/>
    </features>
 
    <configurations>
@@ -78,8 +78,8 @@ IN THE SOFTWARE.
    </configurations>
 
    <repositories>
-      <repository location="https://download.eclipse.org/releases/2022-06" enabled="true" />
-      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20220531185310/repository" enabled="true" />
+      <repository location="https://download.eclipse.org/releases/2023-03" enabled="true" />
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20230302014618/repository" enabled="true" />
    </repositories>
 
    <preferencesInfo>
diff --git a/product/org.eclipse.escet.product/pom.xml b/product/org.eclipse.escet.product/pom.xml
index 75f42a5439a8bf2d7ba569c4fde8b12a17ff7ac6..62272150ae104b2eeb2daf0a1d07e6bcd0b2783f 100644
--- a/product/org.eclipse.escet.product/pom.xml
+++ b/product/org.eclipse.escet.product/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.eclipse.escet</groupId>
         <artifactId>org.eclipse.escet.root</artifactId>
-        <version>0.9.0-SNAPSHOT</version>
+        <version>0.10.0-SNAPSHOT</version>
         <relativePath>../../</relativePath>
     </parent>
 
@@ -106,6 +106,36 @@
             </plugin>
 
         </plugins>
+
+        <pluginManagement>
+            <plugins>
+                <!-- Eclipse M2E lifecycle mappings. Does not influence the Maven build itself. -->
+                <plugin>
+                    <groupId>org.eclipse.m2e</groupId>
+                    <artifactId>lifecycle-mapping</artifactId>
+                    <version>1.0.0</version>
+                    <configuration>
+                        <lifecycleMappingMetadata>
+                            <pluginExecutions>
+                                <pluginExecution>
+                                    <pluginExecutionFilter>
+                                        <groupId>org.apache.maven.plugins</groupId>
+                                        <artifactId>maven-clean-plugin</artifactId>
+                                        <versionRange>[2.5,)</versionRange>
+                                        <goals>
+                                            <goal>clean</goal>
+                                        </goals>
+                                    </pluginExecutionFilter>
+                                    <action>
+                                        <ignore></ignore>
+                                    </action>
+                                </pluginExecution>
+                            </pluginExecutions>
+                        </lifecycleMappingMetadata>
+                    </configuration>
+                </plugin>
+            </plugins>
+        </pluginManagement>
     </build>
 
     <profiles>
@@ -153,6 +183,25 @@
             <id>sign</id>
             <build>
                 <plugins>
+                    <!-- Sign third party dependencies obtained from Maven central, using GPG signing. -->
+                    <plugin>
+                        <groupId>org.eclipse.tycho</groupId>
+                        <artifactId>tycho-gpg-plugin</artifactId>
+                        <version>${tycho.version}</version>
+                        <executions>
+                            <execution>
+                                <id>sign-gpg</id>
+                                <goals>
+                                    <goal>sign-p2-artifacts</goal>
+                                </goals>
+                                <configuration>
+                                    <keyname>0C60515FCC4D6E5A</keyname> <!-- Eclipse ESCET public key. -->
+                                    <skipIfJarsigned>true</skipIfJarsigned> <!-- Sign if not already JAR-signed. -->
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+
                     <!-- Sign Windows executables. -->
                     <plugin>
                         <groupId>org.eclipse.cbi.maven.plugins</groupId>
diff --git a/releng/org.eclipse.escet.releng.configuration/pom.xml b/releng/org.eclipse.escet.releng.configuration/pom.xml
index 1814c5d5e689aae8cad6b2f7fc116a73b59c2106..0fb806bd890c8d4ce7e6957abfceaa7ca0d4e486 100644
--- a/releng/org.eclipse.escet.releng.configuration/pom.xml
+++ b/releng/org.eclipse.escet.releng.configuration/pom.xml
@@ -16,7 +16,7 @@ SPDX-License-Identifier: MIT
     <modelVersion>4.0.0</modelVersion>
     <groupId>org.eclipse.escet</groupId>
     <artifactId>org.eclipse.escet.releng.configuration</artifactId>
-    <version>0.9.0-SNAPSHOT</version>
+    <version>0.10.0-SNAPSHOT</version>
     <packaging>pom</packaging>
 
     <properties>
@@ -25,9 +25,9 @@ SPDX-License-Identifier: MIT
         <escet.version.enduser>dev</escet.version.enduser>
 
         <!-- The version to use for referring across-docset to web pages of other docsets.  -->
-        <!-- For instance, in AsciiDoc, use 'http://eclipse.org/escet/{escet-website-version}/...'. -->
-        <!-- By default, this is replaced by nothing, to for instance 'http://eclipse.org/escet//...'.  -->
-        <!-- The Jenkinsfile overrides this for releases only, to for instance 'http://eclipse.org/escet/v0.1/...'. -->
+        <!-- For instance, in AsciiDoc, use 'http://eclipse.dev/escet/{escet-website-version}/...'. -->
+        <!-- By default, this is replaced by nothing, to for instance 'http://eclipse.dev/escet//...'.  -->
+        <!-- The Jenkinsfile overrides this for releases only, to for instance 'http://eclipse.dev/escet/v0.1/...'. -->
         <escet.website.version></escet.website.version>
 
         <!-- The version qualifier to use for all plugins/features/etc. -->
@@ -175,17 +175,6 @@ SPDX-License-Identifier: MIT
                     <!-- See https://www.eclipse.org/justj/?page=documentation for more information. -->
                     <executionEnvironment>org.eclipse.justj.openjdk.hotspot.jre.full-17</executionEnvironment>
 
-                    <!-- Special dependency for Eclipse JDT compiler tool fragment. -->
-                    <dependency-resolution>
-                        <extraRequirements>
-                            <requirement>
-                                <type>eclipse-plugin</type>
-                                <id>org.eclipse.jdt.compiler.tool</id>
-                                <versionRange>1.0.0</versionRange>
-                            </requirement>
-                        </extraRequirements>
-                    </dependency-resolution>
-
                     <!-- Configure environments. -->
                     <!-- Determines which environment specific bundles will be in target platform. -->
                     <!-- Also determines the products to build. -->
@@ -221,12 +210,12 @@ SPDX-License-Identifier: MIT
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-surefire-plugin</artifactId>
-                <version>3.0.0-M5</version>
+                <version>3.0.0</version>
                 <dependencies>
                     <dependency>
                         <groupId>org.apache.maven.surefire</groupId>
                         <artifactId>surefire-junit47</artifactId>
-                        <version>3.0.0-M5</version>
+                        <version>3.0.0</version>
                     </dependency>
                 </dependencies>
                 <configuration>
@@ -380,7 +369,7 @@ SPDX-License-Identifier: MIT
                 <plugin>
                     <groupId>org.apache.maven.plugins</groupId>
                     <artifactId>maven-plugin-plugin</artifactId>
-                    <version>3.6.4</version>
+                    <version>3.8.2</version>
                 </plugin>
             </plugins>
         </pluginManagement>
@@ -478,14 +467,15 @@ SPDX-License-Identifier: MIT
             <id>sign</id>
             <build>
                 <plugins>
-                    <!-- Sign JARs. -->
+                    <!-- JAR signing, for JARs that are created from sources in our own repo. -->
+                    <!-- GPG signing, for third party dependencies is configured in org.eclipse.escet.product. -->
                     <plugin>
                         <groupId>org.eclipse.cbi.maven.plugins</groupId>
                         <artifactId>eclipse-jarsigner-plugin</artifactId>
                         <version>${eclipse.cbi.version}</version>
                         <executions>
                             <execution>
-                                <id>sign</id>
+                                <id>sign-jar</id>
                                 <phase>verify</phase>
                                 <goals>
                                     <goal>sign</goal>
diff --git a/releng/org.eclipse.escet.releng.dev.documentation/META-INF/MANIFEST.MF b/releng/org.eclipse.escet.releng.dev.documentation/META-INF/MANIFEST.MF
index 94cc8b8a9d23f40ff08771d3fa9e2da94e8f7f8f..41cb17960130d4af846cf4f75fbc6759df814e01 100644
--- a/releng/org.eclipse.escet.releng.dev.documentation/META-INF/MANIFEST.MF
+++ b/releng/org.eclipse.escet.releng.dev.documentation/META-INF/MANIFEST.MF
@@ -2,6 +2,6 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Development Documentation (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.releng.dev.documentation;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Require-Bundle: org.eclipse.help
diff --git a/releng/org.eclipse.escet.releng.dev.documentation/asciidoc/app-framework/standalone-vs-eclipse.asciidoc b/releng/org.eclipse.escet.releng.dev.documentation/asciidoc/app-framework/standalone-vs-eclipse.asciidoc
index 3082c5113245f48534fdd573d22f668a361c8ad9..79a3806aa4ef8b7bda94b05b829f61895d1b1c21 100644
--- a/releng/org.eclipse.escet.releng.dev.documentation/asciidoc/app-framework/standalone-vs-eclipse.asciidoc
+++ b/releng/org.eclipse.escet.releng.dev.documentation/asciidoc/app-framework/standalone-vs-eclipse.asciidoc
@@ -109,7 +109,7 @@ To remedy this situation, application framework applications running within Ecli
 Furthermore, the application framework allows termination requests via the `AppEnv.terminate` method.
 Application framework applications and threads should regularly call the `AppEnv.isTerminationRequested` method to see whether they should terminate.
 
-See also the termination features of the link:https://eclipse.org/escet/{escet-website-version}/use/apps-view.html[Applications] view.
+See also the termination features of the link:https://eclipse.dev/escet/{escet-website-version}/use/apps-view.html[Applications] view.
 
 indexterm:[application, exceptions]
 
diff --git a/releng/org.eclipse.escet.releng.dev.documentation/asciidoc/development/dependency-upgrades.asciidoc b/releng/org.eclipse.escet.releng.dev.documentation/asciidoc/development/dependency-upgrades.asciidoc
index 139e063f86b9ec22e8d696459e2badf13ef78a1f..fc1fbb5dc84d061072d9793714774acc4d1eda18 100644
--- a/releng/org.eclipse.escet.releng.dev.documentation/asciidoc/development/dependency-upgrades.asciidoc
+++ b/releng/org.eclipse.escet.releng.dev.documentation/asciidoc/development/dependency-upgrades.asciidoc
@@ -48,23 +48,59 @@ To upgrade to a new Eclipse Platform/IDE version:
 ** Check the link:https://eclipseide.org/release/noteworthy/[New & Noteworthy] page for the new release and all intermediate releases since the previous version.
 Note that you can switch to the New & Noteworthy pages of previous releases using the dropdown at the bottom of the page.
 
-* New development environment
-** <<development-dev-env-setup-chapter-index,Set up a new development environment>> for the new Eclipse IDE version.
+* Upgrade the development environment
+** Alternative 1: set up a fresh new development environment.
+*** The benefit of this alternative is that you get a clean new environment, and can use it side-by-side with existing development environments.
+The downside is that you have to manually configure the new environment, or manually migrate your workspace and settings.
+You also have to cleanup or remove your old development environments, in case you don't use them anymore.
+*** <<development-dev-env-setup-chapter-index,Set up a new development environment>> for the new Eclipse IDE version.
+** Alternative 2: in-place upgrade of an existing development environment.
+*** The benefit of this alternative is that you can keep your existing environment, preventing multiple such environments as well as manual migrations.
+The downside is that you run the risk of older things remaining in your development environment, requiring manual cleanup.
+*** Update the _P2 Director_ section of the Oomph setup, if needed.
+Especially, consider what is no longer compatible with the new Eclipse version and remove it, or replace it by an alternative.
+*** If you removed anything from the _P2 Director_ section of the Oomph setup, also remove it manually from your development environment:
+**** Click menu:Help[About Eclipse Platform].
+**** Click the btn:[Installation Details] button.
+**** Select on the _Installed Software_ tab the item to remove and click the btn:[Uninstall...] button.
+**** On the _Uninstall_ dialog, click the btn:[Finish] button.
+**** When asked to restart the Eclipse Platform, click btn:[Restart Now] (newer Eclipse versions) or btn:[Yes] (older Eclipse versions).
+**** Repeat these steps for each item that was removed from the _P2 Director_ section of the Oomph setup.
+*** Update your installation profile for the new Eclipse version, and apply it:
+**** From the toolbar, select the dropdown menu of the menu:Open User[] item and choose menu:Open Installation[].
+**** Select the _Installation file:..._ node.
+**** In the _Properties_ view, change the _Product Version_ to the _Eclipse Platform_ edition of the new Eclipse version.
+**** Save the `installation.setup` file.
+**** Click menu:File[Restart].
+**** Once Eclipse restarts, you may see some initialization progress at the bottom right corner of the development environment window.
+**** Wait for the _Eclipse Update_ dialog to appear, indicating that _The installation does not satisfy the requirements listed below_.
+**** Click the btn:[Install] button to update Eclipse.
+**** Wait for the update to complete, while observing the progress at the bottom right corner of the development environment window.
+**** If a _Trust_ dialog appears, click btn:[Select All] and then btn:[Trust Selected].
+**** After some time, notice the Oomph icon with the flashing warning sign (image:{development-imgsdir}/oomph-icon-warning.png[]) at the bottom right corner of the development environment window.
+**** Click it to open the _Eclipse Updater_ window.
+**** Click btn:[Finish] to restart Eclipse, completing the update.
+**** Once Eclipse restarts, you may see a _Older Workspace Version_ popup.
+**** If so, click btn:[Continue] to update your workspace to the new Eclipse version.
 
 * Version updates
-** Look up Orbit version for the new Eclipse Platform/IDE release, see https://download.eclipse.org/tools/orbit/downloads/.
-** Update Oomph setup (`org.eclipse.escet.setup`), configuring new Eclipse IDE and Orbit versions.
-** Update `dev-env-setup.asciidoc` to match new Eclipse version.
+** Look up the Orbit version for the new Eclipse Platform/IDE release, see https://download.eclipse.org/tools/orbit/downloads/.
+** Update the target platform (`org.eclipse.escet.releng.target/org.eclipse.escet.releng.target.target`), configuring new versions for the Eclipse IDE and Orbit update sites.
+** Update `dev-env-setup.asciidoc` to match the new Eclipse version.
 ** Update `org.eclipse.platform` version for the product feature (`org.eclipse.escet.product.feature/feature.xml`).
-** Update Eclipse and Orbit update site URLs in product (`org.eclipse.escet.product/escet.product`).
-** Update Eclipse and Orbit update site URLs in update site (`org.eclipse.escet.product/category.xml`).
-** Update Maven plugin third party dependency versions to match Orbit versions (`org.eclipse.escet.common.asciidoc/pom.xml`).
-
-* Update target platform and address any issues
-** Let Oomph regenerate the target platform, and commit any changes.
+** Update Eclipse and Orbit update site URLs in the product (`org.eclipse.escet.product/escet.product`).
+** Update Eclipse and Orbit update site URLs in the update site (`org.eclipse.escet.product/category.xml`).
+** Update Maven plugin third party dependency versions to match the versions of these plugins from Orbit (`org.eclipse.escet.common.asciidoc/pom.xml`).
+** Commit any changes.
+
+* Update target platform and adapt to the new Eclipse version
+** Let Oomph reactivate the target platform, and address any issues.
+** Commit any changes.
 ** Force a rebuild in Eclipse (menu:Project[Clean...]).
-** Check workspace for any errors/warnings and address them if any.
+** Check the workspace for any errors/warnings and address them if any.
+** Commit any changes.
 ** Check _New and Noteworthy_ (release notes) of the new Eclipse version and relevant intermediate versions for changes and adapt as necessary.
+** Commit any changes.
 
 * Java formatter profile
 ** Right click the `org.eclipse.escet.common.java` project in the _Package Explorer_ view and choose menu:Properties[].
@@ -192,8 +228,8 @@ Update the keywords themselves and the field's JavaDoc, including the link to th
 ** Search for the current Java version to find other references (e.g., search for `17`).
 
 * For any Java versions (e.g. 17 to 18, or 17.0.1 to 17.0.2):
-** Update the JustJ version (`eclipse.justj.version.*` variables) in the Oomph setup (`org.eclipse.escet.setup`).
-** Regenerate the target platform file using Oomph.
+** Update the JustJ update site URL in the target platform (`org.eclipse.escet.releng.target/org.eclipse.escet.releng.target.target`).
+** Re-activate the target platform using Oomph.
 ** Update JustJ version for the product feature (`org.eclipse.escet.product.feature/feature.xml`).
 ** Force a rebuild in Eclipse (menu:Project[Clean...]) and check for any warnings/errors, addressing them if any.
 ** Run a <<development-building-and-testing-chapter-index,Maven build>>.
diff --git a/releng/org.eclipse.escet.releng.dev.documentation/asciidoc/development/dev-env-setup.asciidoc b/releng/org.eclipse.escet.releng.dev.documentation/asciidoc/development/dev-env-setup.asciidoc
index 4974eebee6e92f60ec780c61d69589deecb16fa6..6e9a7fb970f70c9d3c9a927dd5bbf401c214fdaa 100644
--- a/releng/org.eclipse.escet.releng.dev.documentation/asciidoc/development/dev-env-setup.asciidoc
+++ b/releng/org.eclipse.escet.releng.dev.documentation/asciidoc/development/dev-env-setup.asciidoc
@@ -50,8 +50,8 @@ Wait for the update to complete and the Eclipse Installer to restart.
 If the button is disabled (grey), you are already using the latest version.
 * In the first wizard window:
 ** Select _Eclipse Platform_ from the big list at the top.
-** Select _2022-06_ for _Product Version_.
-** For _Java 11+ VM_ select _JRE 17.x.x - \https://download.eclipse.org/justj/jres/17/updates/release/latest_.
+** Select _2023-03_ for _Product Version_.
+** For _Java 17+ VM_ select _JRE 17.x.x - \https://download.eclipse.org/justj/jres/17/updates/release/latest_.
 ** Choose whether you want a P2 bundle pool (recommended).
 ** Click btn:[Next].
 * In the second wizard window:
diff --git a/releng/org.eclipse.escet.releng.dev.documentation/asciidoc/development/dev-list.asciidoc b/releng/org.eclipse.escet.releng.dev.documentation/asciidoc/development/dev-list.asciidoc
index e53104b97ba1c4d60ebdbe6d1c06c8b2204e7ab0..077fb768c9b2f87473dd07bc4a9e23731fbe373f 100644
--- a/releng/org.eclipse.escet.releng.dev.documentation/asciidoc/development/dev-list.asciidoc
+++ b/releng/org.eclipse.escet.releng.dev.documentation/asciidoc/development/dev-list.asciidoc
@@ -22,4 +22,4 @@ You can contact the Eclipse ESCET developers via the project's 'dev' list.
 
 For other means to interact with the Eclipse ESCET community and its developers, see:
 
-* link:https://eclipse.org/escet/{escet-website-version}/contact-and-support.html[Eclipse ESCET contact information]
+* link:https://eclipse.dev/escet/{escet-website-version}/contact-and-support.html[Eclipse ESCET contact information]
diff --git a/releng/org.eclipse.escet.releng.dev.documentation/asciidoc/development/development-process.asciidoc b/releng/org.eclipse.escet.releng.dev.documentation/asciidoc/development/development-process.asciidoc
index bed492ebdd524bc299ab4ea0b517f8524493243e..a887501b8084268486eede3846d761cc47342af7 100644
--- a/releng/org.eclipse.escet.releng.dev.documentation/asciidoc/development/development-process.asciidoc
+++ b/releng/org.eclipse.escet.releng.dev.documentation/asciidoc/development/development-process.asciidoc
@@ -165,7 +165,7 @@ However, this should be carefully considered, taking into account Git's well-kno
 Only perform a rebase if you understand the potential pitfalls of rewriting history.
 Never rebase a branch that is shared with others that have been given 'permission' to work on the branch as well.
 Never rebase a branch when other branches are based on it.
-Never rebase a branch once a merge request is created for it, e.g. to avoid confusion for reviewers, and to prevent rewriting history in case a snapshot of the merge request is submitted to the Eclipse Foundation IP team as part of a Contribution Questionnaire (CQ).
+Never rebase a branch once a merge request is created for it, e.g. to avoid confusion for reviewers, and to prevent rewriting history in case a snapshot of the merge request is submitted to the Eclipse Foundation IP team via link:https://gitlab.eclipse.org/eclipsefdn/emo-team/iplab[IPLab].
 A safer alternative to rebasing is merging, which leads to an extra merge commit and a more complicated history.
 If you fully understand rebasing and employ it carefully, it can be a powerful to maintain a simpler and cleaner history.
 Rebasing local commits that have not yet been pushed to the remote public repository is always at your own discretion.
diff --git a/releng/org.eclipse.escet.releng.dev.documentation/asciidoc/development/git-repo.asciidoc b/releng/org.eclipse.escet.releng.dev.documentation/asciidoc/development/git-repo.asciidoc
index 03d1f160ce9cbc9986dc5f0bf1ba8b9013ff8db3..f90acff7693c45f8a35b9a58d341803716892624 100644
--- a/releng/org.eclipse.escet.releng.dev.documentation/asciidoc/development/git-repo.asciidoc
+++ b/releng/org.eclipse.escet.releng.dev.documentation/asciidoc/development/git-repo.asciidoc
@@ -43,9 +43,9 @@ The way we work with our Git repository is explained as part of our <<developmen
 In the Eclipse ESCET source code repository (Git repository), three layers are distinguished:
 
 * The top layer contains user-oriented languages for designing controllers.
-Currently there are two modeling languages in this layer, link:https://eclipse.org/escet/{escet-website-version}/cif[CIF] and link:https://eclipse.org/escet/{escet-website-version}/chi[Chi].
+Currently there are two modeling languages in this layer, link:https://eclipse.dev/escet/{escet-website-version}/cif[CIF] and link:https://eclipse.dev/escet/{escet-website-version}/chi[Chi].
 +
-The third language in the top layer is link:https://eclipse.org/escet/{escet-website-version}/tooldef[ToolDef], a cross-platform scripting language to run tests, and to automate the various tools that need to be executed while designing a controller.
+The third language in the top layer is link:https://eclipse.dev/escet/{escet-website-version}/tooldef[ToolDef], a cross-platform scripting language to run tests, and to automate the various tools that need to be executed while designing a controller.
 
 * The middle layer contains developer oriented support code.
 It has a language of its own, named <<setext-chapter-index,SeText>>.
diff --git a/releng/org.eclipse.escet.releng.dev.documentation/asciidoc/development/release-process.asciidoc b/releng/org.eclipse.escet.releng.dev.documentation/asciidoc/development/release-process.asciidoc
index 6e697e20e3b0720f5ccfb85b5a1cc43dd8f0f4c3..722fbbe83fa05ddce671ce0f355d2b4abfbe4f2d 100644
--- a/releng/org.eclipse.escet.releng.dev.documentation/asciidoc/development/release-process.asciidoc
+++ b/releng/org.eclipse.escet.releng.dev.documentation/asciidoc/development/release-process.asciidoc
@@ -186,7 +186,7 @@ Once the work on `develop` is done for a release (milestone, release candidate,
 
 * For a final release ensure the `TBD` indication is removed in the release notes of all documentation sets.
 
-* For a final release ensure that all IP is accounted for and all relevant CQs and IP Team GitLab issues have been approved by the Eclipse Foundation IP team.
+* For a final release ensure that all IP is accounted for and all relevant Eclipse Foundation IP team issues in link:https://gitlab.eclipse.org/eclipsefdn/emo-team/iplab[IPLab] have been approved by the Eclipse Foundation IP team.
 
 * For a final release ensure that a <<development-release-process-prepare-release-review,release review>> has been successfully completed no more than one year ago.
 
@@ -221,10 +221,10 @@ Replace `N.N` by the actual release record version, e.g. `0.1`, `0.1.1` or `1.0`
 <ul>
     <li>Eclipse ESCET vN.N-NNN release notes
     <ul>
-        <li><a href="https://www.eclipse.org/escet/vN.N-NNN/release-notes.html">ESCET toolkit release notes</a></li>
-        <li><a href="https://www.eclipse.org/escet/vN.N-NNN/chi/release-notes.html">Chi release notes</a></li>
-        <li><a href="https://www.eclipse.org/escet/vN.N-NNN/cif/release-notes.html">CIF release notes</a></li>
-        <li><a href="https://www.eclipse.org/escet/vN.N-NNN/tooldef/release-notes.html">ToolDef release notes</a></li>
+        <li><a href="https://eclipse.dev/escet/vN.N-NNN/release-notes.html">ESCET toolkit release notes</a></li>
+        <li><a href="https://eclipse.dev/escet/vN.N-NNN/chi/release-notes.html">Chi release notes</a></li>
+        <li><a href="https://eclipse.dev/escet/vN.N-NNN/cif/release-notes.html">CIF release notes</a></li>
+        <li><a href="https://eclipse.dev/escet/vN.N-NNN/tooldef/release-notes.html">ToolDef release notes</a></li>
     </ul>
     </li>
     <li><a href="https://gitlab.eclipse.org/eclipse/escet/escet/-/milestones/NN">Eclipse ESCET GitLab vN.N issues</a></li>
@@ -237,26 +237,6 @@ Replace `N.N` by the final release version, e.g. `0.1`, `0.1.1` or `1.0`.
 
 ** Click _Save_.
 
-* Submit the IP Log:
-
-** Go to https://projects.eclipse.org/projects/technology.escet.
-
-** Ensure you're logged in, as an ESCET project committer.
-
-** In the right sidebar, click _Generate IP Log_.
-
-** For _Respin_, select _None, this is a new IP Log review request_.
-
-** For _Required by date_, select the date one week before the review conclusion date.
-
-** For _Release_ select the relevant release.
-
-** It is not necessary to write any _Comments_.
-
-** Click _Submit for review_.
-
-** Note the message at the top of the page, indicating that a CQ was created, to track the approval of the IP Log by the Eclipse Foundation IP team.
-
 * Request PMC approval:
 
 ** Go to https://accounts.eclipse.org/mailing-list/technology-pmc and subscribe to the Technology PMC mailing list, if not yet subscribed.
@@ -325,16 +305,14 @@ Replace `<your role`> by either `project lead` or `project committer`.
 ----
 See the following pages for submitted materials and approval:
 * Release record and review materials: https://projects.eclipse.org/projects/technology.escet/releases/N.N
-* IP Log approval issue: https://dev.eclipse.org/ipzilla/show_bug.cgi?id=NNN
-* PMC approval request: https://www.eclipse.org/lists/technology-pmc/msgNNNN.html
-* PMC approval: https://www.eclipse.org/lists/technology-pmc/msgNNNNN.html
-* EMO release review scheduling request: https://www.eclipse.org/lists/escet-dev/msgNNNNNN.html
+* PMC approval request: https://www.eclipse.org/lists/technology-pmc/msgNNN.html
+* PMC approval: https://www.eclipse.org/lists/technology-pmc/msgNNNN.html
+* EMO release review scheduling request: https://www.eclipse.org/lists/escet-dev/msgNNNNN.html
 * EMO release review tracking issue: https://gitlab.eclipse.org/eclipsefdn/emo-team/emo/-/issues/NN
 ----
 +
 Replace `N.N` by the release version, e.g. `0.1`, `0.1.1` or `1.0`.
-Replace `NNN` by the IP Log CQ issue number.
-Replace `NNNN`, `NNNNN`, and `NNNNNN` by the corresponding mailing list message numbers.
+Replace `NNN`, `NNNN`, and `NNNNN` by the corresponding mailing list message numbers.
 Consult the http://www.eclipse.org/lists/technology-pmc[Technology PMC mailing list archive] and the http://www.eclipse.org/lists/escet-dev[Eclipse ESCET dev mailing list archive] to find the messages and their message numbers.
 Replace `NN` by the GitLab issue number of the issue that will be created by the EMO to track the release review.
 
@@ -393,7 +371,7 @@ Jenkins will then automatically build and release a new version from that tag.
 * All releases are available at https://download.eclipse.org/escet/.
 For a version `v0.1`, the downloads will be located at `\https://download.eclipse.org/escet/v0.1`.
 
-** End users should however be referred to https://eclipse.org/escet/download.html instead of `download.eclipse.org`.
+** End users should however be referred to https://eclipse.dev/escet/download.html instead of `download.eclipse.org`.
 The buttons on this web page serve downloads via a mirror script.
 This ensures that a nearby mirror is selected, for faster downloads.
 It also ensures that downloads are counted in the download statistics.
@@ -405,10 +383,10 @@ It typically takes a day or two for all the mirror sites to synchronize with us
 Immediately after the downloads being available, downloading them may thus be slower, even if the mirror script is used.
 
 * Jenkins will automatically push the website for the new release to the website Git repository, in a directory for the specific release.
-For a version `v0.1`, the website can be accessed at `\https://eclipse.org/escet/v0.1`.
+For a version `v0.1`, the website can be accessed at `\https://eclipse.dev/escet/v0.1`.
 It may take a few minutes for the Git repository to be synced to the webserver and for the website for the new version to become available.
 
-* If the website for the new release is to be the standard visible website for the project (at `https://eclipse.org/escet`), it has to be manually replaced.
+* If the website for the new release is to be the standard visible website for the project (at `https://eclipse.dev/escet`), it has to be manually replaced.
 This is to ensure that a bugfix release for an older version doesn't override the standard visible website.
 The following steps explain how to 'promote' a website for a specific version to become the standard visible website:
 
@@ -438,7 +416,7 @@ If it is OK, push it by executing `git push`.
 ** Remove the website repository clone, by executing `cd ..` and `rm -rf escet-website`.
 
 ** It may take a few minutes for the Git repository to be synced to the webserver, and for the new standard visible website to become available.
-The standard visible website can be accessed at `https://eclipse.org/escet`.
+The standard visible website can be accessed at `https://eclipse.dev/escet`.
 Depending on browser cache settings and other factors, it may be necessary to force refresh your browser for it to pick up the changes on the server.
 
 * Inform others about the new release:
@@ -449,15 +427,15 @@ Depending on browser cache settings and other factors, it may be necessary to fo
 ----
 I just released vN.N:
 
-- https://eclipse.org/escet/
-- https://eclipse.org/escet/download.html
-- https://eclipse.org/escet/release-notes.html
+- https://eclipse.dev/escet/
+- https://eclipse.dev/escet/download.html
+- https://eclipse.dev/escet/release-notes.html
 
 And here are the permalinks:
 
-- https://eclipse.org/escet/vN.N
-- https://eclipse.org/escet/vN.N/download.html
-- https://eclipse.org/escet/vN.N/release-notes.html
+- https://eclipse.dev/escet/vN.N
+- https://eclipse.dev/escet/vN.N/download.html
+- https://eclipse.dev/escet/vN.N/release-notes.html
 
 Note that mirrors may still need to sync, so downloads may be a bit slower until then.
 ----
@@ -468,9 +446,9 @@ Note that mirrors may still need to sync, so downloads may be a bit slower until
 ----
 I just released vN.N-NNN:
 
-- https://eclipse.org/escet/vN.N-NNN
-- https://eclipse.org/escet/vN.N-NNN/download.html
-- https://eclipse.org/escet/vN.N-NNN/release-notes.html
+- https://eclipse.dev/escet/vN.N-NNN
+- https://eclipse.dev/escet/vN.N-NNN/download.html
+- https://eclipse.dev/escet/vN.N-NNN/release-notes.html
 
 Note that mirrors may still need to sync, so downloads may be a bit slower until then.
 ----
@@ -520,27 +498,36 @@ E.g. for `v0.3` we archive `v0.1` and older, but keep `v0.2`.
 
 * Remove the websites of the identified milestone and release candidate versions:
 
-** Clone the Eclipse ESCET website Git repository using `git clone https://gitlab.eclipse.org/eclipse/escet/escet-website.git`.
+** These steps assume that you've set up an Eclipse ESCET development environment, using the <<development-dev-env-setup-chapter-index,standard instructions>>, at `<path-to-dev-env>`.
+
+** Open a terminal.
+
+** Execute `cd <path-to-dev-env>/git` to go to the directory of your development environment with Git repositories.
+
+** Clone the Eclipse ESCET website Git repository by executing `git clone https://gitlab.eclipse.org/eclipse/escet/escet-website.git`.
 
-** In the cloned repository, remove the folders corresponding to the milestone and release candidate versions.
+** Execute `cd escet-website` to enter the directory that contains the new clone.
 
-** Add all changes to be committed, e.g. by using `git add -A`.
+** For each website version to remove:
 
-** Commit the changes.
+*** Execute `../escet/misc/website/remove-website-version.bash vN.N "Full Name" "\some@example.com"`, with appropriate substitutions, to remove the website:
 
-*** Use as commit message `Removed milestone and RC websites of release vN.N.`, replacing `vN.N` by the release version, e.g., `v1.0` when removing versions `v1.0-M1` and `v1.0-RC1`.
+**** Replace `vN.N` with the website milestone or release candidate version to remove, e.g.,`v0.9-M1` or `v1.1.0-RC1`.
 
-*** Use the `--author` option to specify your full name (first name and last name) and email address as registered in your Eclipse Foundation account.
-Make sure to use double quotes around the entire argument, and `<` and `>` around the email address.
+**** Replace `Full Name` by your full name (first name and last name) as registered in your Eclipse Foundation account, e.g., `John Smith`.
 
-*** E.g. use the following to commit the changes:
-`git commit --author "Full Name <\some@example.org>" -m "Removed milestone and RC websites of release v1.0."`.
+**** Replace `some@example.com` by your email address as registered in your Eclipse Foundation account.
 
-** Push the changes to the Git server.
-E.g. use `git push`.
+*** As indicated, review the new commit.
+If it is OK, push it by executing `git push`.
 
 ** If successful you should see the changes on GitLab, at https://gitlab.eclipse.org/eclipse/escet/escet-website/-/commits/master.
 
+** Remove the website repository clone, by executing `cd ..` and `rm -rf escet-website`.
+
+** It may take a few minutes for the Git repository to be synced to the webserver, and for the removed websites to no longer be available online.
+Depending on browser cache settings and other factors, it may be necessary to force refresh your browser for it to pick up the changes on the server.
+
 * Remove the downloads of the identified milestone and release candidate versions:
 
 ** Go to https://download.eclipse.org/escet/.
diff --git a/releng/org.eclipse.escet.releng.dev.documentation/build-docs-escet-dev.launch b/releng/org.eclipse.escet.releng.dev.documentation/build-docs-escet-dev.launch
index a7cc1bb20354a0f5c98361680056e985d6dd3554..782ae13518e1672c465dd3d5ae517dbf5ed75477 100644
--- a/releng/org.eclipse.escet.releng.dev.documentation/build-docs-escet-dev.launch
+++ b/releng/org.eclipse.escet.releng.dev.documentation/build-docs-escet-dev.launch
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <launchConfiguration type="org.eclipse.m2e.Maven2LaunchConfigurationType">
+    <intAttribute key="M2_COLORS" value="0"/>
     <booleanAttribute key="M2_DEBUG_OUTPUT" value="false"/>
     <stringAttribute key="M2_GOALS" value="clean package --projects releng/org.eclipse.escet.releng.target,releng/org.eclipse.escet.releng.dev.documentation --also-make"/>
     <booleanAttribute key="M2_NON_RECURSIVE" value="false"/>
@@ -15,6 +16,7 @@
     <booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="true"/>
     <stringAttribute key="M2_USER_SETTINGS" value=""/>
     <booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="false"/>
+    <booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
     <stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${workspace}"/>
     <mapAttribute key="org.eclipse.debug.core.environmentVariables">
         <mapEntry key="JAVA_HOME" value="${system_property:java.home}"/>
diff --git a/releng/org.eclipse.escet.releng.dev.documentation/images/development/oomph-icon-warning.png b/releng/org.eclipse.escet.releng.dev.documentation/images/development/oomph-icon-warning.png
new file mode 100644
index 0000000000000000000000000000000000000000..61342bbbef67949c385e8b860d11c8a7f2ca136a
--- /dev/null
+++ b/releng/org.eclipse.escet.releng.dev.documentation/images/development/oomph-icon-warning.png
@@ -0,0 +1,4 @@
+‰PNG
+
+���
IHDR���������´Э���gAMA��±üa���	pHYs��Â��Â(J€���tEXtSoftware�Paint.NET v3.5.9@<°Ë��7IDAT8Ocø@:@×stªùá	:.oƒòàù‰·§£Þßžå"ëyý䯋ûg÷µJþ|óÔÇ;G¡ŠÞ]¬yuÉësÅ^ß…ˆ@õ\\“~ KþØã½-bÿ?_ýõöÌ‘	:÷N-|÷øä³Ã±.BK{ýÞžoƒ(é¹¶£öì<‡ßOÖþ½ýï‹M@ˆ¾Þž{°GõõŒw{Ò¼ÅW÷û|8šþîée¨žÝ­
+_¯¶ý½?ÝÚvr¢Ö§C	ÿ.̪6¾¹!ìï¹Ì»R z¶T‰ü8÷|»÷-ûüÓý½¦×Eü=•üfoT¤ߢÓÿgSŸ¯rƒêÙѬuyåöFÕw®/>Ø«sdfà›žì~»ÎéëÈãó½^ìŽûz0öñb¨žS+Kv´›=¾qÈ>¹<ç캪÷ïÞ�Ù돜޶°ìñ¦‚[ks6NŒØ7'ùÍÝSP=˜àõÛ·“7ž¶ýHêĵço=(ž³yòÞÝ…³6Ad±èyøìeþìmkO_|÷óc@ëŠè¾5óÎ8øú
Q€®çÕ›·A]kªÖm=úúüÑ7ç€J!hûãã®
Ë jÐõ¼|ýÖ²riÛÖ]‹Ï\zîÐÂÓW]>¼ì¡ÀÞÕ-«CÔ`qÛš#×´òæÌÜX¿l»XÒlí‚EŠ™óc'nóîDö0X¸ç¢Bæü°Î5¢I³/Þyrãás¨`×;ÏÞÖÌ[¤]°ÊG8õà>��ö>ªñ——Â����IEND®B`‚
\ No newline at end of file
diff --git a/releng/org.eclipse.escet.releng.dev.documentation/pom.xml b/releng/org.eclipse.escet.releng.dev.documentation/pom.xml
index 96be047532b74422a601382075cf277a824bd566..5c372fec74f057b3096705301b501711cb841d99 100644
--- a/releng/org.eclipse.escet.releng.dev.documentation/pom.xml
+++ b/releng/org.eclipse.escet.releng.dev.documentation/pom.xml
@@ -16,7 +16,7 @@
     <parent>
         <groupId>org.eclipse.escet</groupId>
         <artifactId>org.eclipse.escet.root</artifactId>
-        <version>0.9.0-SNAPSHOT</version>
+        <version>0.10.0-SNAPSHOT</version>
         <relativePath>../../</relativePath>
     </parent>
 
diff --git a/releng/org.eclipse.escet.releng.license.mit/feature.xml b/releng/org.eclipse.escet.releng.license.mit/feature.xml
index db811368eded0ed4967880a73fb44decb6381adc..d79bee01a750871a925ebec23f742dcad894ac88 100644
--- a/releng/org.eclipse.escet.releng.license.mit/feature.xml
+++ b/releng/org.eclipse.escet.releng.license.mit/feature.xml
@@ -13,7 +13,7 @@
 <feature
       id="org.eclipse.escet.releng.license.mit"
       label="ESCET License (Incubation)"
-      version="0.9.0.qualifier"
+      version="0.10.0.qualifier"
       provider-name="Eclipse ESCET">
 
    <copyright>
diff --git a/releng/org.eclipse.escet.releng.project.documentation/META-INF/MANIFEST.MF b/releng/org.eclipse.escet.releng.project.documentation/META-INF/MANIFEST.MF
index f86852746b3ecda1cd25128d3f3ae09c9940709b..eafbbe324de3ed0e7ae686562006ed827dba0584 100644
--- a/releng/org.eclipse.escet.releng.project.documentation/META-INF/MANIFEST.MF
+++ b/releng/org.eclipse.escet.releng.project.documentation/META-INF/MANIFEST.MF
@@ -2,6 +2,6 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET Project Documentation (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.releng.project.documentation;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Require-Bundle: org.eclipse.help
diff --git a/releng/org.eclipse.escet.releng.project.documentation/asciidoc/documentation.asciidoc b/releng/org.eclipse.escet.releng.project.documentation/asciidoc/documentation.asciidoc
index 206fb91da2cba4f97fd49f33afc8e36c12bfa40b..c180b8870ef785dae58989774b2097d05a631764 100644
--- a/releng/org.eclipse.escet.releng.project.documentation/asciidoc/documentation.asciidoc
+++ b/releng/org.eclipse.escet.releng.project.documentation/asciidoc/documentation.asciidoc
@@ -52,9 +52,9 @@ The following information is available:
 The Eclipse ESCET toolkit features multiple languages and associated tools.
 Check the website for each of these languages for more specific information, including separate documentation for each of them:
 
-* link:https://eclipse.org/escet/{escet-website-version}/cif[CIF]
-* link:https://eclipse.org/escet/{escet-website-version}/chi[Chi]
-* link:https://eclipse.org/escet/{escet-website-version}/tooldef[ToolDef]
+* link:https://eclipse.dev/escet/{escet-website-version}/cif[CIF]
+* link:https://eclipse.dev/escet/{escet-website-version}/chi[Chi]
+* link:https://eclipse.dev/escet/{escet-website-version}/tooldef[ToolDef]
 
 // Use
 
diff --git a/releng/org.eclipse.escet.releng.project.documentation/asciidoc/release-notes.asciidoc b/releng/org.eclipse.escet.releng.project.documentation/asciidoc/release-notes.asciidoc
index dc8892c5d223a72eefe9a2c7782e0368d6504388..471c7a01ece5eb57b193fcabd70f963336ad3d48 100644
--- a/releng/org.eclipse.escet.releng.project.documentation/asciidoc/release-notes.asciidoc
+++ b/releng/org.eclipse.escet.releng.project.documentation/asciidoc/release-notes.asciidoc
@@ -22,9 +22,23 @@ The release notes for the versions of the Eclipse ESCET tools, as part of the Ec
 
 See also the release notes for the specific tools for more information:
 
-* link:https://eclipse.org/escet/{escet-website-version}/cif/release-notes.html[CIF release notes]
-* link:https://eclipse.org/escet/{escet-website-version}/chi/release-notes.html[Chi release notes]
-* link:https://eclipse.org/escet/{escet-website-version}/tooldef/release-notes.html[ToolDef release notes]
+* link:https://eclipse.dev/escet/{escet-website-version}/cif/release-notes.html[CIF release notes]
+* link:https://eclipse.dev/escet/{escet-website-version}/chi/release-notes.html[Chi release notes]
+* link:https://eclipse.dev/escet/{escet-website-version}/tooldef/release-notes.html[ToolDef release notes]
+
+=== Version 0.10
+
+TBD
+
+Improvements and fixes:
+
+* The Eclipse ESCET website has moved from `www.eclipse.org/escet` to `eclipse.dev/escet`.
+Redirects from the old URLs to the new ones are in place (issue {escet-issue}577[#577]).
+* This release is based on Eclipse 2023-03, rather than Eclipse 2022-06 (issue {escet-issue}399[#399]).
+* The Eclipse ESCET IDE no longer gives warnings for projects without an explicit encoding (issue {escet-issue}399[#399]).
+* The DSM clustering tool's command line script for Linux is now executable (issue {escet-issue}570[#570]).
+* The SVG viewer's _Save as_ dialog now properly starts in the directory that contains the SVG file, also on Windows.
+And it now properly handles paths with spaces and other special characters in them (issue {escet-issue}221[#221]).
 
 === Version 0.9 (2023-03-31)
 
diff --git a/releng/org.eclipse.escet.releng.project.documentation/build-docs-escet-project.launch b/releng/org.eclipse.escet.releng.project.documentation/build-docs-escet-project.launch
index 358040c35fb3915c4a5bf14efc593c605b5be54f..d08f3edd870c5f03e2e92a6ed497d6ed4c0e98c4 100644
--- a/releng/org.eclipse.escet.releng.project.documentation/build-docs-escet-project.launch
+++ b/releng/org.eclipse.escet.releng.project.documentation/build-docs-escet-project.launch
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <launchConfiguration type="org.eclipse.m2e.Maven2LaunchConfigurationType">
+    <intAttribute key="M2_COLORS" value="0"/>
     <booleanAttribute key="M2_DEBUG_OUTPUT" value="false"/>
     <stringAttribute key="M2_GOALS" value="clean package --projects releng/org.eclipse.escet.releng.target,releng/org.eclipse.escet.releng.project.documentation --also-make"/>
     <booleanAttribute key="M2_NON_RECURSIVE" value="false"/>
@@ -15,6 +16,7 @@
     <booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="true"/>
     <stringAttribute key="M2_USER_SETTINGS" value=""/>
     <booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="false"/>
+    <booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
     <stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${workspace}"/>
     <mapAttribute key="org.eclipse.debug.core.environmentVariables">
         <mapEntry key="JAVA_HOME" value="${system_property:java.home}"/>
diff --git a/releng/org.eclipse.escet.releng.project.documentation/pom.xml b/releng/org.eclipse.escet.releng.project.documentation/pom.xml
index 5299c76c014bd48278dfceb489ab15cd5bd9edaa..68bd6995b5d796f56bdb1c0cf9aa1563da41bf14 100644
--- a/releng/org.eclipse.escet.releng.project.documentation/pom.xml
+++ b/releng/org.eclipse.escet.releng.project.documentation/pom.xml
@@ -16,7 +16,7 @@
     <parent>
         <groupId>org.eclipse.escet</groupId>
         <artifactId>org.eclipse.escet.root</artifactId>
-        <version>0.9.0-SNAPSHOT</version>
+        <version>0.10.0-SNAPSHOT</version>
         <relativePath>../../</relativePath>
     </parent>
 
diff --git a/releng/org.eclipse.escet.releng.target/org.eclipse.escet.releng.target.target b/releng/org.eclipse.escet.releng.target/org.eclipse.escet.releng.target.target
index be1cefdea2c286e4512149cb90cb45b6c352ca62..52d974e9bc24dc689be85228a7890cbe4d2e14a5 100644
--- a/releng/org.eclipse.escet.releng.target/org.eclipse.escet.releng.target.target
+++ b/releng/org.eclipse.escet.releng.target/org.eclipse.escet.releng.target.target
@@ -1,61 +1,59 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde version="3.8"?>
-<target name="Generated from Eclipse ESCET" sequenceNumber="40">
-  <locations>
-    <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
-      <unit id="com.google.guava" version="0.0.0"/>
-      <unit id="org.apache.batik.anim" version="0.0.0"/>
-      <unit id="org.apache.batik.awt.util" version="0.0.0"/>
-      <unit id="org.apache.batik.bridge" version="0.0.0"/>
-      <unit id="org.apache.batik.codec" version="0.0.0"/>
-      <unit id="org.apache.batik.dom" version="0.0.0"/>
-      <unit id="org.apache.batik.dom.svg" version="0.0.0"/>
-      <unit id="org.apache.batik.ext" version="0.0.0"/>
-      <unit id="org.apache.batik.gvt" version="0.0.0"/>
-      <unit id="org.apache.batik.parser" version="0.0.0"/>
-      <unit id="org.apache.batik.script" version="0.0.0"/>
-      <unit id="org.apache.batik.svggen" version="0.0.0"/>
-      <unit id="org.apache.batik.transcoder" version="0.0.0"/>
-      <unit id="org.apache.batik.xml" version="0.0.0"/>
-      <unit id="org.apache.commons.exec" version="0.0.0"/>
-      <unit id="org.apache.commons.lang3" version="0.0.0"/>
-      <unit id="org.apache.httpcomponents.httpclient" version="0.0.0"/>
-      <unit id="org.apache.httpcomponents.httpcore" version="0.0.0"/>
-      <unit id="org.apache.xalan" version="0.0.0"/>
-      <unit id="org.apache.xerces" version="0.0.0"/>
-      <unit id="org.apache.xml.resolver" version="0.0.0"/>
-      <unit id="org.eclipse.e4.tools.emf.ui" version="0.0.0"/>
-      <unit id="org.eclipse.e4.tools.services" version="0.0.0"/>
-      <unit id="org.eclipse.ecf.core.feature.feature.group" version="0.0.0"/>
-      <unit id="org.eclipse.ecf.core.ssl.feature.feature.group" version="0.0.0"/>
-      <unit id="org.eclipse.ecf.filetransfer.feature.feature.group" version="0.0.0"/>
-      <unit id="org.eclipse.ecf.filetransfer.httpclient5.feature.feature.group" version="0.0.0"/>
-      <unit id="org.eclipse.ecf.filetransfer.ssl.feature.feature.group" version="0.0.0"/>
-      <unit id="org.eclipse.emf.feature.group" version="0.0.0"/>
-      <unit id="org.eclipse.emf.validation" version="0.0.0"/>
-      <unit id="org.eclipse.epp.mpc.feature.group" version="0.0.0"/>
-      <unit id="org.eclipse.equinox.executable.feature.group" version="0.0.0"/>
-      <unit id="org.eclipse.equinox.p2.discovery.feature.feature.group" version="0.0.0"/>
-      <unit id="org.eclipse.sdk.feature.group" version="0.0.0"/>
-      <unit id="org.eclipse.userstorage.feature.group" version="0.0.0"/>
-      <unit id="org.jsoup" version="0.0.0"/>
-      <unit id="org.objectweb.asm" version="0.0.0"/>
-      <unit id="org.objectweb.asm.tree" version="0.0.0"/>
-      <unit id="org.sat4j.core" version="0.0.0"/>
-      <unit id="org.sat4j.pb" version="0.0.0"/>
-      <repository location="https://download.eclipse.org/releases/2022-06"/>
-    </location>
-    <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
-      <unit id="io.github.java-diff-utils" version="0.0.0"/>
-      <unit id="org.apache.batik.shared.resources" version="0.0.0"/>
-      <unit id="org.apache.commons.math3" version="0.0.0"/>
-      <unit id="org.apache.xml.serializer" version="0.0.0"/>
-      <unit id="org.knowm.xchart" version="0.0.0"/>
-      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20220531185310/repository"/>
-    </location>
-    <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
-      <unit id="org.eclipse.justj.openjdk.hotspot.jre.full.feature.group" version="0.0.0"/>
-      <repository location="https://download.eclipse.org/justj/jres/17/updates/release/17.0.5"/>
-    </location>
-  </locations>
-</target>
+<target name="Eclipse ESCET Target Platform">
+    <locations>
+        <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
+            <unit id="org.apache.commons.exec" version="0.0.0"/>
+            <unit id="org.eclipse.emf.feature.group" version="0.0.0"/>
+            <unit id="org.eclipse.emf.validation" version="0.0.0"/>
+            <unit id="org.eclipse.equinox.executable.feature.group" version="0.0.0"/>
+            <unit id="org.eclipse.epp.mpc.feature.group" version="0.0.0"/>
+            <unit id="org.eclipse.sdk.feature.group" version="0.0.0"/>
+            <repository location="https://download.eclipse.org/releases/2023-03"/>
+        </location>
+        <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
+            <unit id="com.google.guava" version="0.0.0"/>
+            <unit id="io.github.java-diff-utils" version="0.0.0"/>
+            <unit id="org.apache.batik.anim" version="0.0.0"/>
+            <unit id="org.apache.batik.awt.util" version="0.0.0"/>
+            <unit id="org.apache.batik.bridge" version="0.0.0"/>
+            <unit id="org.apache.batik.codec" version="0.0.0"/>
+            <unit id="org.apache.batik.dom" version="0.0.0"/>
+            <unit id="org.apache.batik.dom.svg" version="0.0.0"/>
+            <unit id="org.apache.batik.ext" version="0.0.0"/>
+            <unit id="org.apache.batik.gvt" version="0.0.0"/>
+            <unit id="org.apache.batik.parser" version="0.0.0"/>
+            <unit id="org.apache.batik.script" version="0.0.0"/>
+            <unit id="org.apache.batik.shared.resources" version="0.0.0"/>
+            <unit id="org.apache.batik.svggen" version="0.0.0"/>
+            <unit id="org.apache.batik.transcoder" version="0.0.0"/>
+            <unit id="org.apache.batik.xml" version="0.0.0"/>
+            <unit id="org.apache.commons.io" version="0.0.0"/>
+            <unit id="org.apache.commons.lang3" version="0.0.0"/>
+            <unit id="org.apache.commons.math3" version="0.0.0"/>
+            <unit id="org.jsoup" version="0.0.0"/>
+            <unit id="org.knowm.xchart" version="0.0.0"/>
+            <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20230302014618/repository"/>
+        </location>
+        <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
+            <unit id="org.eclipse.justj.openjdk.hotspot.jre.full.feature.group" version="0.0.0"/>
+            <repository location="https://download.eclipse.org/justj/jres/17/updates/release/17.0.5"/>
+        </location>
+        <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven">
+            <dependencies>
+                <dependency>
+                    <groupId>com.github.com-github-javabdd</groupId>
+                    <artifactId>com.github.javabdd</artifactId>
+                    <version>5.0.0</version>
+                    <type>jar</type>
+                </dependency>
+                <dependency>
+                    <groupId>org.apache.commons</groupId>
+                    <artifactId>commons-text</artifactId>
+                    <version>1.10.0</version>
+                    <type>jar</type>
+                </dependency>
+            </dependencies>
+        </location>
+    </locations>
+</target>
\ No newline at end of file
diff --git a/releng/org.eclipse.escet.releng.target/pom.xml b/releng/org.eclipse.escet.releng.target/pom.xml
index 34d97b5e9645f37a3f13ea7ac56828f7704a8bf3..4baa49f30ec8527d7da7e03f6f874564b17bdaeb 100644
--- a/releng/org.eclipse.escet.releng.target/pom.xml
+++ b/releng/org.eclipse.escet.releng.target/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.eclipse.escet</groupId>
         <artifactId>org.eclipse.escet.root</artifactId>
-        <version>0.9.0-SNAPSHOT</version>
+        <version>0.10.0-SNAPSHOT</version>
         <relativePath>../../</relativePath>
     </parent>
 
diff --git a/releng/org.eclipse.escet.releng.tests/META-INF/MANIFEST.MF b/releng/org.eclipse.escet.releng.tests/META-INF/MANIFEST.MF
index 2f2b2f6336d9aaf66ffecefff9a1d82e9c96441a..e0bb002bdb0c5e059523b49516a7bbf05538d26c 100644
--- a/releng/org.eclipse.escet.releng.tests/META-INF/MANIFEST.MF
+++ b/releng/org.eclipse.escet.releng.tests/META-INF/MANIFEST.MF
@@ -2,36 +2,36 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: Eclipse ESCET Tests (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.releng.tests;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Automatic-Module-Name: org.eclipse.escet.releng.tests
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.chi.codegen;bundle-version="0.9.0",
- org.eclipse.escet.chi.runtime;bundle-version="0.9.0",
- org.eclipse.escet.chi.tests;bundle-version="0.9.0",
- org.eclipse.escet.cif.cif2mcrl2;bundle-version="0.9.0",
- org.eclipse.escet.cif.cif2plc;bundle-version="0.9.0",
- org.eclipse.escet.cif.codegen;bundle-version="0.9.0",
- org.eclipse.escet.cif.common;bundle-version="0.9.0",
- org.eclipse.escet.cif.controllercheck;bundle-version="0.9.0",
- org.eclipse.escet.cif.datasynth;bundle-version="0.9.0",
- org.eclipse.escet.cif.eventbased;bundle-version="0.9.0",
- org.eclipse.escet.cif.io;bundle-version="0.9.0",
- org.eclipse.escet.cif.simulator;bundle-version="0.9.0",
- org.eclipse.escet.cif.tests;bundle-version="0.9.0",
- org.eclipse.escet.cif.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.common.app.framework.tests;bundle-version="0.9.0",
- org.eclipse.escet.common.box;bundle-version="0.9.0",
- org.eclipse.escet.common.dsm;bundle-version="0.9.0",
- org.eclipse.escet.common.emf.tests;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.common.multivaluetrees;bundle-version="0.9.0",
- org.eclipse.escet.common.raildiagrams;bundle-version="0.9.0",
- org.eclipse.escet.common.tests;bundle-version="0.9.0",
- org.eclipse.escet.setext.generator;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
- org.eclipse.escet.setext.tests;bundle-version="0.9.0",
- org.eclipse.escet.setext.texteditor;bundle-version="0.9.0",
- org.eclipse.escet.tooldef.common;bundle-version="0.9.0",
- org.eclipse.escet.tooldef.runtime;bundle-version="0.9.0",
- org.eclipse.escet.tooldef.tests;bundle-version="0.9.0"
+Require-Bundle: org.eclipse.escet.chi.codegen;bundle-version="0.10.0",
+ org.eclipse.escet.chi.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.chi.tests;bundle-version="0.10.0",
+ org.eclipse.escet.cif.cif2mcrl2;bundle-version="0.10.0",
+ org.eclipse.escet.cif.cif2plc;bundle-version="0.10.0",
+ org.eclipse.escet.cif.codegen;bundle-version="0.10.0",
+ org.eclipse.escet.cif.common;bundle-version="0.10.0",
+ org.eclipse.escet.cif.controllercheck;bundle-version="0.10.0",
+ org.eclipse.escet.cif.datasynth;bundle-version="0.10.0",
+ org.eclipse.escet.cif.eventbased;bundle-version="0.10.0",
+ org.eclipse.escet.cif.io;bundle-version="0.10.0",
+ org.eclipse.escet.cif.simulator;bundle-version="0.10.0",
+ org.eclipse.escet.cif.tests;bundle-version="0.10.0",
+ org.eclipse.escet.cif.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.common.app.framework.tests;bundle-version="0.10.0",
+ org.eclipse.escet.common.box;bundle-version="0.10.0",
+ org.eclipse.escet.common.dsm;bundle-version="0.10.0",
+ org.eclipse.escet.common.emf.tests;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.common.multivaluetrees;bundle-version="0.10.0",
+ org.eclipse.escet.common.raildiagrams;bundle-version="0.10.0",
+ org.eclipse.escet.common.tests;bundle-version="0.10.0",
+ org.eclipse.escet.setext.generator;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.setext.tests;bundle-version="0.10.0",
+ org.eclipse.escet.setext.texteditor;bundle-version="0.10.0",
+ org.eclipse.escet.tooldef.common;bundle-version="0.10.0",
+ org.eclipse.escet.tooldef.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.tooldef.tests;bundle-version="0.10.0"
diff --git a/releng/org.eclipse.escet.releng.tests/pom.xml b/releng/org.eclipse.escet.releng.tests/pom.xml
index f4d242abaad8443dbfff8ebff5e10f98614b1f58..e74ca5aa9d67ce3a358d1504e2faf4e56073621f 100644
--- a/releng/org.eclipse.escet.releng.tests/pom.xml
+++ b/releng/org.eclipse.escet.releng.tests/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.eclipse.escet</groupId>
         <artifactId>org.eclipse.escet.root</artifactId>
-        <version>0.9.0-SNAPSHOT</version>
+        <version>0.10.0-SNAPSHOT</version>
         <relativePath>../../</relativePath>
     </parent>
 
diff --git a/releng/org.eclipse.escet.releng.website/META-INF/MANIFEST.MF b/releng/org.eclipse.escet.releng.website/META-INF/MANIFEST.MF
index e9da10d78890c103f5148564aa5074f3e67efca2..f7424c6077d07510d83c579b42c53e6977594d80 100644
--- a/releng/org.eclipse.escet.releng.website/META-INF/MANIFEST.MF
+++ b/releng/org.eclipse.escet.releng.website/META-INF/MANIFEST.MF
@@ -2,12 +2,12 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: Eclipse ESCET Website (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.releng.website;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Automatic-Module-Name: org.eclipse.escet.releng.website
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.chi.documentation;bundle-version="0.9.0",
- org.eclipse.escet.cif.documentation;bundle-version="0.9.0",
- org.eclipse.escet.releng.dev.documentation;bundle-version="0.9.0",
- org.eclipse.escet.releng.project.documentation;bundle-version="0.9.0",
- org.eclipse.escet.tooldef.documentation;bundle-version="0.9.0"
+Require-Bundle: org.eclipse.escet.chi.documentation;bundle-version="0.10.0",
+ org.eclipse.escet.cif.documentation;bundle-version="0.10.0",
+ org.eclipse.escet.releng.dev.documentation;bundle-version="0.10.0",
+ org.eclipse.escet.releng.project.documentation;bundle-version="0.10.0",
+ org.eclipse.escet.tooldef.documentation;bundle-version="0.10.0"
diff --git a/releng/org.eclipse.escet.releng.website/pom.xml b/releng/org.eclipse.escet.releng.website/pom.xml
index 256ad8411ab214d3b6af7d62b017f404e8a8254a..68239c47b65b2cec8ad389cacab304b687b52b72 100644
--- a/releng/org.eclipse.escet.releng.website/pom.xml
+++ b/releng/org.eclipse.escet.releng.website/pom.xml
@@ -16,7 +16,7 @@
     <parent>
         <groupId>org.eclipse.escet</groupId>
         <artifactId>org.eclipse.escet.root</artifactId>
-        <version>0.9.0-SNAPSHOT</version>
+        <version>0.10.0-SNAPSHOT</version>
         <relativePath>../../</relativePath>
     </parent>
 
diff --git a/setext/org.eclipse.escet.setext.feature/feature.xml b/setext/org.eclipse.escet.setext.feature/feature.xml
index c4d651693f7014d54dab6831cd7485e1538bba70..23a1a0018b6100084b6546335e302af879510aa8 100644
--- a/setext/org.eclipse.escet.setext.feature/feature.xml
+++ b/setext/org.eclipse.escet.setext.feature/feature.xml
@@ -13,11 +13,11 @@
 <feature
       id="org.eclipse.escet.setext.feature"
       label="ESCET SeText (Incubation)"
-      version="0.9.0.qualifier"
+      version="0.10.0.qualifier"
       provider-name="Eclipse ESCET"
       plugin="org.eclipse.escet.product.branding"
       license-feature="org.eclipse.escet.releng.license.mit"
-      license-feature-version="0.9.0.qualifier">
+      license-feature-version="0.10.0.qualifier">
 
    <description>
       Eclipse ESCET tooling for the SeText language.
@@ -32,7 +32,7 @@
    </license>
 
    <requires>
-      <import feature="org.eclipse.escet.common.feature" version="0.9.0.qualifier"/>
+      <import feature="org.eclipse.escet.common.feature" version="0.10.0.qualifier"/>
    </requires>
 
    <plugin
diff --git a/setext/org.eclipse.escet.setext.generator/.settings/org.eclipse.jdt.core.prefs b/setext/org.eclipse.escet.setext.generator/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/setext/org.eclipse.escet.setext.generator/.settings/org.eclipse.jdt.core.prefs
+++ b/setext/org.eclipse.escet.setext.generator/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/setext/org.eclipse.escet.setext.generator/.settings/org.eclipse.jdt.ui.prefs b/setext/org.eclipse.escet.setext.generator/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/setext/org.eclipse.escet.setext.generator/.settings/org.eclipse.jdt.ui.prefs
+++ b/setext/org.eclipse.escet.setext.generator/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/setext/org.eclipse.escet.setext.generator/.settings/org.eclipse.ltk.core.refactoring.prefs b/setext/org.eclipse.escet.setext.generator/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/setext/org.eclipse.escet.setext.generator/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/setext/org.eclipse.escet.setext.generator/META-INF/MANIFEST.MF b/setext/org.eclipse.escet.setext.generator/META-INF/MANIFEST.MF
index 7f8c0d55cee5da91145ccb1f012c97ab352a8cbb..0ae15159181b6f793eff256e7d636fb6a067080d 100644
--- a/setext/org.eclipse.escet.setext.generator/META-INF/MANIFEST.MF
+++ b/setext/org.eclipse.escet.setext.generator/META-INF/MANIFEST.MF
@@ -2,23 +2,23 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET SeText Scanner/Parser Generator (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.setext.generator;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.common.eclipse.ui;bundle-version="0.9.0",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.common.eclipse.ui;bundle-version="0.10.0",
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
  org.eclipse.core.resources;bundle-version="3.13.600",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.setext.parser;bundle-version="0.9.0",
- org.eclipse.escet.common.position.metamodel;bundle-version="0.9.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.setext.parser;bundle-version="0.10.0",
+ org.eclipse.escet.common.position.metamodel;bundle-version="0.10.0",
  org.apache.commons.lang3;bundle-version="3.1.0",
- org.eclipse.escet.common.position.common;bundle-version="0.9.0",
- org.eclipse.escet.setext.io;bundle-version="0.9.0",
+ org.eclipse.escet.common.position.common;bundle-version="0.10.0",
+ org.eclipse.escet.setext.io;bundle-version="0.10.0",
  org.apache.commons.io;bundle-version="2.6.0",
- org.eclipse.escet.setext.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
- org.eclipse.escet.common.box;bundle-version="0.9.0"
+ org.eclipse.escet.setext.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.common.box;bundle-version="0.10.0"
 Bundle-Vendor: Eclipse ESCET
 Export-Package: org.eclipse.escet.setext.generator,
  org.eclipse.escet.setext.generator.parser,
diff --git a/setext/org.eclipse.escet.setext.io/.settings/org.eclipse.jdt.core.prefs b/setext/org.eclipse.escet.setext.io/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/setext/org.eclipse.escet.setext.io/.settings/org.eclipse.jdt.core.prefs
+++ b/setext/org.eclipse.escet.setext.io/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/setext/org.eclipse.escet.setext.io/.settings/org.eclipse.jdt.ui.prefs b/setext/org.eclipse.escet.setext.io/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/setext/org.eclipse.escet.setext.io/.settings/org.eclipse.jdt.ui.prefs
+++ b/setext/org.eclipse.escet.setext.io/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/setext/org.eclipse.escet.setext.io/.settings/org.eclipse.ltk.core.refactoring.prefs b/setext/org.eclipse.escet.setext.io/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/setext/org.eclipse.escet.setext.io/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/setext/org.eclipse.escet.setext.io/META-INF/MANIFEST.MF b/setext/org.eclipse.escet.setext.io/META-INF/MANIFEST.MF
index 3ae92a3c5686d56aaff1b72fd19a7ac7776750ee..07abd2bf44928c7f736a52b7fb5d884b44afcdc2 100644
--- a/setext/org.eclipse.escet.setext.io/META-INF/MANIFEST.MF
+++ b/setext/org.eclipse.escet.setext.io/META-INF/MANIFEST.MF
@@ -2,15 +2,15 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET SeText I/O Functionality (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.setext.io;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
 Export-Package: org.eclipse.escet.setext.io
-Require-Bundle: org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.setext.parser;bundle-version="0.9.0",
- org.eclipse.escet.setext.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0"
+Require-Bundle: org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.setext.parser;bundle-version="0.10.0",
+ org.eclipse.escet.setext.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0"
 Bundle-Vendor: Eclipse ESCET
 Automatic-Module-Name: org.eclipse.escet.setext.io
diff --git a/setext/org.eclipse.escet.setext.parser/.settings/org.eclipse.jdt.core.prefs b/setext/org.eclipse.escet.setext.parser/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/setext/org.eclipse.escet.setext.parser/.settings/org.eclipse.jdt.core.prefs
+++ b/setext/org.eclipse.escet.setext.parser/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/setext/org.eclipse.escet.setext.parser/.settings/org.eclipse.jdt.ui.prefs b/setext/org.eclipse.escet.setext.parser/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/setext/org.eclipse.escet.setext.parser/.settings/org.eclipse.jdt.ui.prefs
+++ b/setext/org.eclipse.escet.setext.parser/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/setext/org.eclipse.escet.setext.parser/.settings/org.eclipse.ltk.core.refactoring.prefs b/setext/org.eclipse.escet.setext.parser/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/setext/org.eclipse.escet.setext.parser/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/setext/org.eclipse.escet.setext.parser/META-INF/MANIFEST.MF b/setext/org.eclipse.escet.setext.parser/META-INF/MANIFEST.MF
index 0ae8e506ad900b153d833d14674c8af7fd34553e..382ad45f6e34db7aab80925ea268623878f6b9e4 100644
--- a/setext/org.eclipse.escet.setext.parser/META-INF/MANIFEST.MF
+++ b/setext/org.eclipse.escet.setext.parser/META-INF/MANIFEST.MF
@@ -2,12 +2,12 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET SeText Parser (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.setext.parser;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
  org.eclipse.jface.text;bundle-version="3.16.100"
 Export-Package: org.eclipse.escet.setext.parser,
  org.eclipse.escet.setext.parser.ast,
diff --git a/setext/org.eclipse.escet.setext.runtime/.settings/org.eclipse.jdt.core.prefs b/setext/org.eclipse.escet.setext.runtime/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/setext/org.eclipse.escet.setext.runtime/.settings/org.eclipse.jdt.core.prefs
+++ b/setext/org.eclipse.escet.setext.runtime/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/setext/org.eclipse.escet.setext.runtime/.settings/org.eclipse.jdt.ui.prefs b/setext/org.eclipse.escet.setext.runtime/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/setext/org.eclipse.escet.setext.runtime/.settings/org.eclipse.jdt.ui.prefs
+++ b/setext/org.eclipse.escet.setext.runtime/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/setext/org.eclipse.escet.setext.runtime/.settings/org.eclipse.ltk.core.refactoring.prefs b/setext/org.eclipse.escet.setext.runtime/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/setext/org.eclipse.escet.setext.runtime/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/setext/org.eclipse.escet.setext.runtime/META-INF/MANIFEST.MF b/setext/org.eclipse.escet.setext.runtime/META-INF/MANIFEST.MF
index 0aded9b79e8203321667bbf93cd3c38111befbda..9deb901295614fbae5eb57912a684c8f8818066f 100644
--- a/setext/org.eclipse.escet.setext.runtime/META-INF/MANIFEST.MF
+++ b/setext/org.eclipse.escet.setext.runtime/META-INF/MANIFEST.MF
@@ -2,16 +2,16 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET SeText Runtime (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.setext.runtime;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Export-Package: org.eclipse.escet.setext.runtime,
  org.eclipse.escet.setext.runtime.exceptions,
  org.eclipse.escet.setext.runtime.io
-Require-Bundle: org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
  org.apache.commons.io;bundle-version="2.6.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
  org.eclipse.jface.text;bundle-version="3.16.100"
 Bundle-Vendor: Eclipse ESCET
 Automatic-Module-Name: org.eclipse.escet.setext.runtime
diff --git a/setext/org.eclipse.escet.setext.tests/.settings/org.eclipse.jdt.core.prefs b/setext/org.eclipse.escet.setext.tests/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/setext/org.eclipse.escet.setext.tests/.settings/org.eclipse.jdt.core.prefs
+++ b/setext/org.eclipse.escet.setext.tests/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/setext/org.eclipse.escet.setext.tests/.settings/org.eclipse.jdt.ui.prefs b/setext/org.eclipse.escet.setext.tests/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/setext/org.eclipse.escet.setext.tests/.settings/org.eclipse.jdt.ui.prefs
+++ b/setext/org.eclipse.escet.setext.tests/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/setext/org.eclipse.escet.setext.tests/.settings/org.eclipse.ltk.core.refactoring.prefs b/setext/org.eclipse.escet.setext.tests/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/setext/org.eclipse.escet.setext.tests/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/setext/org.eclipse.escet.setext.tests/META-INF/MANIFEST.MF b/setext/org.eclipse.escet.setext.tests/META-INF/MANIFEST.MF
index 39c4b2cfb64731d92a10dac2c8ab8a34068d55cc..b8c7636957cf775d9e7c2500bce5c17c87cdf206 100644
--- a/setext/org.eclipse.escet.setext.tests/META-INF/MANIFEST.MF
+++ b/setext/org.eclipse.escet.setext.tests/META-INF/MANIFEST.MF
@@ -2,13 +2,13 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET SeText Tests (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.setext.tests;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
 Require-Bundle: org.junit;bundle-version="4.12.0",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.tooldef.interpreter;bundle-version="0.9.0",
- org.eclipse.escet.setext.generator;bundle-version="0.9.0"
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.tooldef.interpreter;bundle-version="0.10.0",
+ org.eclipse.escet.setext.generator;bundle-version="0.10.0"
 Export-Package: org.eclipse.escet.setext.tests
 Automatic-Module-Name: org.eclipse.escet.setext.tests
diff --git a/setext/org.eclipse.escet.setext.texteditor/.settings/org.eclipse.jdt.core.prefs b/setext/org.eclipse.escet.setext.texteditor/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/setext/org.eclipse.escet.setext.texteditor/.settings/org.eclipse.jdt.core.prefs
+++ b/setext/org.eclipse.escet.setext.texteditor/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/setext/org.eclipse.escet.setext.texteditor/.settings/org.eclipse.jdt.ui.prefs b/setext/org.eclipse.escet.setext.texteditor/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/setext/org.eclipse.escet.setext.texteditor/.settings/org.eclipse.jdt.ui.prefs
+++ b/setext/org.eclipse.escet.setext.texteditor/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/setext/org.eclipse.escet.setext.texteditor/.settings/org.eclipse.ltk.core.refactoring.prefs b/setext/org.eclipse.escet.setext.texteditor/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/setext/org.eclipse.escet.setext.texteditor/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/setext/org.eclipse.escet.setext.texteditor/META-INF/MANIFEST.MF b/setext/org.eclipse.escet.setext.texteditor/META-INF/MANIFEST.MF
index 105c2b25f32f794ab42af4038b1915d87abdaade..b5c8d0873fb568585bb20687536e3e351d17eea6 100644
--- a/setext/org.eclipse.escet.setext.texteditor/META-INF/MANIFEST.MF
+++ b/setext/org.eclipse.escet.setext.texteditor/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET SeText Text Editor (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.setext.texteditor;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
@@ -10,15 +10,15 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="3.17.0",
  org.eclipse.ui;bundle-version="3.115.0",
  org.eclipse.ui.editors;bundle-version="3.13.0",
  org.eclipse.jface.text;bundle-version="3.16.100",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.setext.parser;bundle-version="0.9.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.setext.parser;bundle-version="0.10.0",
  org.eclipse.core.resources;bundle-version="3.13.600",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.setext.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
- org.eclipse.escet.setext.texteditorbase;bundle-version="0.9.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.setext.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.setext.texteditorbase;bundle-version="0.10.0",
  org.junit;bundle-version="4.12.0",
  org.eclipse.ui.ide;bundle-version="3.18.200",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0"
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0"
 Export-Package: org.eclipse.escet.setext.texteditor
 Automatic-Module-Name: org.eclipse.escet.setext.texteditor
diff --git a/setext/org.eclipse.escet.setext.texteditorbase/.settings/org.eclipse.jdt.core.prefs b/setext/org.eclipse.escet.setext.texteditorbase/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/setext/org.eclipse.escet.setext.texteditorbase/.settings/org.eclipse.jdt.core.prefs
+++ b/setext/org.eclipse.escet.setext.texteditorbase/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/setext/org.eclipse.escet.setext.texteditorbase/.settings/org.eclipse.jdt.ui.prefs b/setext/org.eclipse.escet.setext.texteditorbase/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/setext/org.eclipse.escet.setext.texteditorbase/.settings/org.eclipse.jdt.ui.prefs
+++ b/setext/org.eclipse.escet.setext.texteditorbase/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/setext/org.eclipse.escet.setext.texteditorbase/.settings/org.eclipse.ltk.core.refactoring.prefs b/setext/org.eclipse.escet.setext.texteditorbase/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/setext/org.eclipse.escet.setext.texteditorbase/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/setext/org.eclipse.escet.setext.texteditorbase/META-INF/MANIFEST.MF b/setext/org.eclipse.escet.setext.texteditorbase/META-INF/MANIFEST.MF
index 96ef09b37d412e888a330b17067a6951d3dfb60b..f5891f04eab8189e8b4972585dc8bc0e224646a5 100644
--- a/setext/org.eclipse.escet.setext.texteditorbase/META-INF/MANIFEST.MF
+++ b/setext/org.eclipse.escet.setext.texteditorbase/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET SeText Generic Text Editor Base (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.setext.texteditorbase;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
@@ -16,17 +16,17 @@ Export-Package: org.eclipse.escet.setext.texteditorbase,
 Require-Bundle: org.eclipse.swt;bundle-version="3.113.0",
  org.eclipse.jface;bundle-version="3.18.0",
  org.eclipse.jface.text;bundle-version="3.16.100",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
  org.eclipse.ui;bundle-version="3.115.0",
  org.eclipse.ui.editors;bundle-version="3.13.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
  org.eclipse.core.resources;bundle-version="3.13.600",
  org.eclipse.core.runtime;bundle-version="3.17.0",
  org.eclipse.ui.ide;bundle-version="3.16.100",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
  org.eclipse.ui.workbench.texteditor;bundle-version="3.14.0",
  org.eclipse.core.commands;bundle-version="3.9.600",
  org.eclipse.ui.workbench;bundle-version="3.117.0",
- org.apache.commons.lang3;bundle-version="3.1.0"
+ org.apache.commons.commons-text;bundle-version="1.10.0"
 Automatic-Module-Name: org.eclipse.escet.setext.texteditorbase
diff --git a/setext/org.eclipse.escet.setext.texteditorbase/src/org/eclipse/escet/setext/texteditorbase/GenericTextEditor.java b/setext/org.eclipse.escet.setext.texteditorbase/src/org/eclipse/escet/setext/texteditorbase/GenericTextEditor.java
index 4db330aca9cd8d7cb2104440b6368316dac382cd..ce06cf3e2899b45f08c30c6047cf175b952186f6 100644
--- a/setext/org.eclipse.escet.setext.texteditorbase/src/org/eclipse/escet/setext/texteditorbase/GenericTextEditor.java
+++ b/setext/org.eclipse.escet.setext.texteditorbase/src/org/eclipse/escet/setext/texteditorbase/GenericTextEditor.java
@@ -500,7 +500,7 @@ public class GenericTextEditor<T1, T2, TT extends Enum<TT>> extends TextEditor
     public String getValidationCrashIssueReportingInstructions() {
         return "Validation crashed. Please report this to the Eclipse ESCET development team at "
                 + "https://gitlab.eclipse.org/eclipse/escet/escet/-/issues. For more information, see "
-                + "https://eclipse.org/escet/contact-and-support.html. We appreciate you "
+                + "https://eclipse.dev/escet/contact-and-support.html. We appreciate you "
                 + "taking the effort to report issues to us!";
     }
 
diff --git a/setext/org.eclipse.escet.setext.texteditorbase/src/org/eclipse/escet/setext/texteditorbase/highlight/CodeHighlighter.java b/setext/org.eclipse.escet.setext.texteditorbase/src/org/eclipse/escet/setext/texteditorbase/highlight/CodeHighlighter.java
index aea37a9f3807e8583500dedf7254054d254524db..c6eb905f5ac9352894f9ae2ffd35585282bf9e68 100644
--- a/setext/org.eclipse.escet.setext.texteditorbase/src/org/eclipse/escet/setext/texteditorbase/highlight/CodeHighlighter.java
+++ b/setext/org.eclipse.escet.setext.texteditorbase/src/org/eclipse/escet/setext/texteditorbase/highlight/CodeHighlighter.java
@@ -17,7 +17,7 @@ import static org.eclipse.escet.common.java.Strings.fmt;
 
 import java.util.Iterator;
 
-import org.apache.commons.lang3.StringEscapeUtils;
+import org.apache.commons.text.StringEscapeUtils;
 import org.eclipse.escet.common.java.Assert;
 import org.eclipse.escet.setext.texteditorbase.ColorManager;
 import org.eclipse.escet.setext.texteditorbase.scanners.GenericPartitionScanner;
diff --git a/setext/org.eclipse.escet.setext.typechecker/.settings/org.eclipse.jdt.core.prefs b/setext/org.eclipse.escet.setext.typechecker/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/setext/org.eclipse.escet.setext.typechecker/.settings/org.eclipse.jdt.core.prefs
+++ b/setext/org.eclipse.escet.setext.typechecker/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/setext/org.eclipse.escet.setext.typechecker/.settings/org.eclipse.jdt.ui.prefs b/setext/org.eclipse.escet.setext.typechecker/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/setext/org.eclipse.escet.setext.typechecker/.settings/org.eclipse.jdt.ui.prefs
+++ b/setext/org.eclipse.escet.setext.typechecker/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/setext/org.eclipse.escet.setext.typechecker/.settings/org.eclipse.ltk.core.refactoring.prefs b/setext/org.eclipse.escet.setext.typechecker/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/setext/org.eclipse.escet.setext.typechecker/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/setext/org.eclipse.escet.setext.typechecker/META-INF/MANIFEST.MF b/setext/org.eclipse.escet.setext.typechecker/META-INF/MANIFEST.MF
index b602d52f5032b526073479378cc7e0b07117edd9..d66993d883c700583d5924f3ef4d7987a0d8b60e 100644
--- a/setext/org.eclipse.escet.setext.typechecker/META-INF/MANIFEST.MF
+++ b/setext/org.eclipse.escet.setext.typechecker/META-INF/MANIFEST.MF
@@ -2,12 +2,12 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET SeText Type Checker (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.setext.typechecker;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
 Export-Package: org.eclipse.escet.setext.typechecker
-Require-Bundle: org.eclipse.escet.setext.parser;bundle-version="0.9.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0"
+Require-Bundle: org.eclipse.escet.setext.parser;bundle-version="0.10.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0"
 Automatic-Module-Name: org.eclipse.escet.setext.typechecker
diff --git a/thirdparty/.project b/thirdparty/.project
new file mode 100644
index 0000000000000000000000000000000000000000..20da8e714e877d589e02ed98b344c41e2e5ef9c0
--- /dev/null
+++ b/thirdparty/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.escet.thirdparty.root</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+	</natures>
+	<filteredResources>
+		<filter>
+			<id>1579098546785</id>
+			<name></name>
+			<type>10</type>
+			<matcher>
+				<id>org.eclipse.ui.ide.multiFilter</id>
+				<arguments>1.0-name-matches-false-false-org.eclipse.escet.*</arguments>
+			</matcher>
+		</filter>
+	</filteredResources>
+</projectDescription>
diff --git a/cif/org.eclipse.escet.cif.examples/benchmarks/.settings/org.eclipse.core.resources.prefs b/thirdparty/.settings/org.eclipse.core.resources.prefs
similarity index 100%
rename from cif/org.eclipse.escet.cif.examples/benchmarks/.settings/org.eclipse.core.resources.prefs
rename to thirdparty/.settings/org.eclipse.core.resources.prefs
diff --git a/thirdparty/com.github.javabdd.feature/.settings/org.eclipse.core.resources.prefs b/thirdparty/com.github.javabdd.feature/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c0203a7844de00dbfc56e6a35d8ed3c022c..0000000000000000000000000000000000000000
--- a/thirdparty/com.github.javabdd.feature/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/<project>=UTF-8
diff --git a/thirdparty/com.github.javabdd.feature/feature.xml b/thirdparty/com.github.javabdd.feature/feature.xml
deleted file mode 100644
index 4801e91c6d85cd224ee3c0f510ae7776e8b3d805..0000000000000000000000000000000000000000
--- a/thirdparty/com.github.javabdd.feature/feature.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<feature
-      id="com.github.javabdd.feature"
-      label="JavaBDD"
-      version="4.0.0.qualifier"
-      provider-name="Eclipse ESCET">
-
-   <description url="https://github.com/com-github-javabdd/com.github.javabdd">
-      JavaBDD is a Java library for manipulating BDDs (Binary Decision Diagrams).
-   </description>
-
-   <copyright>
-      %copyright
-   </copyright>
-
-   <license url="%licenseURL">
-      %license
-   </license>
-
-   <plugin
-         id="com.github.javabdd"
-         download-size="0"
-         install-size="0"
-         version="0.0.0"
-         unpack="false"/>
-
-</feature>
diff --git a/thirdparty/com.github.javabdd.feature/lgpl-2.0-or-later.html b/thirdparty/com.github.javabdd.feature/lgpl-2.0-or-later.html
deleted file mode 100644
index 37456753f66864c66c6a9a9b2b5ca7d8810d9e7a..0000000000000000000000000000000000000000
--- a/thirdparty/com.github.javabdd.feature/lgpl-2.0-or-later.html
+++ /dev/null
@@ -1,513 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-  <head>
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-    <title>LGPL-2.0-or-later License</title>
-    <style type="text/css">
-      body {
-        margin: 1.5em 3em;
-      }
-      h1{
-        font-size:1.5em;
-      }
-      h2{
-        font-size:1em;
-        margin-bottom:0.5em;
-        margin-top:1em;
-      }
-      p {
-        margin-top:  0.5em;
-        margin-bottom: 0.5em;
-      }
-      ul, ol{
-        list-style-type:none;
-      }
-    </style>
-  </head>
-  <body>
-    <h1>LGPL-2.0-or-later License</h1>
-    <pre>
-          GNU LIBRARY GENERAL PUBLIC LICENSE
-                       Version 2, June 1991
-
- Copyright (C) 1991 Free Software Foundation, Inc.
- 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the library GPL.  It is
- numbered 2 because it goes with version 2 of the ordinary GPL.]
-
-                            Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
-  This license, the Library General Public License, applies to some
-specially designated Free Software Foundation software, and to any
-other libraries whose authors decide to use it.  You can use it for
-your libraries, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if
-you distribute copies of the library, or if you modify it.
-
-  For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you.  You must make sure that they, too, receive or can get the source
-code.  If you link a program with the library, you must provide
-complete object files to the recipients so that they can relink them
-with the library, after making changes to the library and recompiling
-it.  And you must show them these terms so they know their rights.
-
-  Our method of protecting your rights has two steps: (1) copyright
-the library, and (2) offer you this license which gives you legal
-permission to copy, distribute and/or modify the library.
-
-  Also, for each distributor&apos;s protection, we want to make certain
-that everyone understands that there is no warranty for this free
-library.  If the library is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original
-version, so that any problems introduced by others will not reflect on
-the original authors&apos; reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that companies distributing free
-software will individually obtain patent licenses, thus in effect
-transforming the program into proprietary software.  To prevent this,
-we have made it clear that any patent must be licensed for everyone&apos;s
-free use or not licensed at all.
-
-  Most GNU software, including some libraries, is covered by the ordinary
-GNU General Public License, which was designed for utility programs.  This
-license, the GNU Library General Public License, applies to certain
-designated libraries.  This license is quite different from the ordinary
-one; be sure to read it in full, and don&apos;t assume that anything in it is
-the same as in the ordinary license.
-
-  The reason we have a separate public license for some libraries is that
-they blur the distinction we usually make between modifying or adding to a
-program and simply using it.  Linking a program with a library, without
-changing the library, is in some sense simply using the library, and is
-analogous to running a utility program or application program.  However, in
-a textual and legal sense, the linked executable is a combined work, a
-derivative of the original library, and the ordinary General Public License
-treats it as such.
-
-  Because of this blurred distinction, using the ordinary General
-Public License for libraries did not effectively promote software
-sharing, because most developers did not use the libraries.  We
-concluded that weaker conditions might promote sharing better.
-
-  However, unrestricted linking of non-free programs would deprive the
-users of those programs of all benefit from the free status of the
-libraries themselves.  This Library General Public License is intended to
-permit developers of non-free programs to use free libraries, while
-preserving your freedom as a user of such programs to change the free
-libraries that are incorporated in them.  (We have not seen how to achieve
-this as regards changes in header files, but we have achieved it as regards
-changes in the actual functions of the Library.)  The hope is that this
-will lead to faster development of free libraries.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.  Pay close attention to the difference between a
-&quot;work based on the library&quot; and a &quot;work that uses the library&quot;.  The
-former contains code derived from the library, while the latter only
-works together with the library.
-
-  Note that it is possible for a library to be covered by the ordinary
-General Public License rather than by this special one.
-
-                  GNU LIBRARY GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License Agreement applies to any software library which
-contains a notice placed by the copyright holder or other authorized
-party saying it may be distributed under the terms of this Library
-General Public License (also called &quot;this License&quot;).  Each licensee is
-addressed as &quot;you&quot;.
-
-  A &quot;library&quot; means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
-  The &quot;Library&quot;, below, refers to any such software library or work
-which has been distributed under these terms.  A &quot;work based on the
-Library&quot; means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language.  (Hereinafter, translation is
-included without limitation in the term &quot;modification&quot;.)
-
-  &quot;Source code&quot; for a work means the preferred form of the work for
-making modifications to it.  For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
-  Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it).  Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-  
-  1. You may copy and distribute verbatim copies of the Library&apos;s
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
-  You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
-  2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) The modified work must itself be a software library.
-
-    b) You must cause the files modified to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    c) You must cause the whole of the work to be licensed at no
-    charge to all third parties under the terms of this License.
-
-    d) If a facility in the modified Library refers to a function or a
-    table of data to be supplied by an application program that uses
-    the facility, other than as an argument passed when the facility
-    is invoked, then you must make a good faith effort to ensure that,
-    in the event an application does not supply such function or
-    table, the facility still operates, and performs whatever part of
-    its purpose remains meaningful.
-
-    (For example, a function in a library to compute square roots has
-    a purpose that is entirely well-defined independent of the
-    application.  Therefore, Subsection 2d requires that any
-    application-supplied function or table used by this function must
-    be optional: if the application does not supply it, the square
-    root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library.  To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License.  (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.)  Do not make any other change in
-these notices.
-
-  Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
-  This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
-  4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
-  If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a &quot;work that uses the Library&quot;.  Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
-  However, linking a &quot;work that uses the Library&quot; with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a &quot;work that uses the
-library&quot;.  The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
-  When a &quot;work that uses the Library&quot; uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library.  The
-threshold for this to be true is not precisely defined by law.
-
-  If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work.  (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
-  Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
-  6. As an exception to the Sections above, you may also compile or
-link a &quot;work that uses the Library&quot; with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer&apos;s own use and reverse
-engineering for debugging such modifications.
-
-  You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License.  You must supply a copy of this License.  If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License.  Also, you must do one
-of these things:
-
-    a) Accompany the work with the complete corresponding
-    machine-readable source code for the Library including whatever
-    changes were used in the work (which must be distributed under
-    Sections 1 and 2 above); and, if the work is an executable linked
-    with the Library, with the complete machine-readable &quot;work that
-    uses the Library&quot;, as object code and/or source code, so that the
-    user can modify the Library and then relink to produce a modified
-    executable containing the modified Library.  (It is understood
-    that the user who changes the contents of definitions files in the
-    Library will not necessarily be able to recompile the application
-    to use the modified definitions.)
-
-    b) Accompany the work with a written offer, valid for at
-    least three years, to give the same user the materials
-    specified in Subsection 6a, above, for a charge no more
-    than the cost of performing this distribution.
-
-    c) If distribution of the work is made by offering access to copy
-    from a designated place, offer equivalent access to copy the above
-    specified materials from the same place.
-
-    d) Verify that the user has already received a copy of these
-    materials or that you have already sent this user a copy.
-
-  For an executable, the required form of the &quot;work that uses the
-Library&quot; must include any data and utility programs needed for
-reproducing the executable from it.  However, as a special exception,
-the source code distributed need not include anything that is normally
-distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
-  It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system.  Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
-  7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
-    a) Accompany the combined library with a copy of the same work
-    based on the Library, uncombined with any other library
-    facilities.  This must be distributed under the terms of the
-    Sections above.
-
-    b) Give prominent notice with the combined library of the fact
-    that part of it is a work based on the Library, and explaining
-    where to find the accompanying uncombined form of the same work.
-
-  8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License.  Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License.  However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
-  9. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Library or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
-  10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions.  You may not impose any further
-restrictions on the recipients&apos; exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded.  In such case, this License incorporates the limitation as if
-written in the body of this License.
-
-  13. The Free Software Foundation may publish revised and/or new
-versions of the Library General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Library
-specifies a version number of this License which applies to it and
-&quot;any later version&quot;, you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation.  If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
-  14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission.  For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this.  Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
-                            NO WARRANTY
-
-  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY &quot;AS IS&quot; WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
-                     END OF TERMS AND CONDITIONS
-
-           How to Apply These Terms to Your New Libraries
-
-  If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change.  You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
-  To apply these terms, attach the following notices to the library.  It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-&quot;copyright&quot; line and a pointer to where the full notice is found.
-
-    &lt;one line to give the library&apos;s name and a brief idea of what it does.&gt;
-    Copyright (C) &lt;year&gt;  &lt;name of author&gt;
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Library General Public
-    License as published by the Free Software Foundation; either
-    version 2 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Library General Public License for more details.
-
-    You should have received a copy of the GNU Library General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a &quot;copyright disclaimer&quot; for the library, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the
-  library `Frob&apos; (a library for tweaking knobs) written by James Random Hacker.
-
-  &lt;signature of Ty Coon&gt;, 1 April 1990
-  Ty Coon, President of Vice
-
-That&apos;s all there is to it!
-    </pre>
-  </body>
-</html>
diff --git a/thirdparty/com.github.javabdd/.classpath b/thirdparty/com.github.javabdd/.classpath
deleted file mode 100644
index c8e514ecc3e27db1027565d17b7a37263326e875..0000000000000000000000000000000000000000
--- a/thirdparty/com.github.javabdd/.classpath
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17">
-		<attributes>
-			<attribute name="module" value="true"/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
-	<classpathentry exported="true" kind="lib" path="lib/com.github.javabdd-4.0.0.jar" sourcepath="lib/com.github.javabdd-4.0.0-sources.jar"/>
-</classpath>
diff --git a/thirdparty/com.github.javabdd/.project b/thirdparty/com.github.javabdd/.project
deleted file mode 100644
index 93f2468398a916ff97f3d5a5f422b69d8e1dbc07..0000000000000000000000000000000000000000
--- a/thirdparty/com.github.javabdd/.project
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>com.github.javabdd</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.pde.ManifestBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.pde.SchemaBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.pde.PluginNature</nature>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
diff --git a/thirdparty/com.github.javabdd/.settings/org.eclipse.core.resources.prefs b/thirdparty/com.github.javabdd/.settings/org.eclipse.core.resources.prefs
deleted file mode 100644
index 99f26c0203a7844de00dbfc56e6a35d8ed3c022c..0000000000000000000000000000000000000000
--- a/thirdparty/com.github.javabdd/.settings/org.eclipse.core.resources.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-encoding/<project>=UTF-8
diff --git a/thirdparty/com.github.javabdd/.settings/org.eclipse.jdt.core.prefs b/thirdparty/com.github.javabdd/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index 1b9068e81f6d83dd7232d0f5332b12c4246e5d06..0000000000000000000000000000000000000000
--- a/thirdparty/com.github.javabdd/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,8 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=17
-org.eclipse.jdt.core.compiler.compliance=17
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.release=disabled
-org.eclipse.jdt.core.compiler.source=17
diff --git a/thirdparty/com.github.javabdd/META-INF/MANIFEST.MF b/thirdparty/com.github.javabdd/META-INF/MANIFEST.MF
deleted file mode 100644
index 626c9deaa9056a61dacb67db0a61d11b66059ec2..0000000000000000000000000000000000000000
--- a/thirdparty/com.github.javabdd/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,11 +0,0 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: JavaBDD
-Bundle-SymbolicName: com.github.javabdd;singleton:=true
-Bundle-Version: 4.0.0.qualifier
-Bundle-Vendor: Eclipse ESCET
-Automatic-Module-Name: com.github.javabdd
-Bundle-RequiredExecutionEnvironment: JavaSE-17
-Bundle-ActivationPolicy: lazy
-Bundle-ClassPath: lib/com.github.javabdd-4.0.0.jar
-Export-Package: com.github.javabdd
diff --git a/thirdparty/com.github.javabdd/about.html b/thirdparty/com.github.javabdd/about.html
deleted file mode 100644
index 406c311fc677390f4721f8641b6547d5b2b73fad..0000000000000000000000000000000000000000
--- a/thirdparty/com.github.javabdd/about.html
+++ /dev/null
@@ -1,67 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
-<title>About</title>
-</head>
-<body lang="EN-US">
-    <h2>About This Content</h2>
-
-    <p>February 16, 2023</p>
-    <h3>License</h3>
-
-    <p>
-        The Eclipse Foundation makes available all content in this plug-in
-        (&quot;Content&quot;). Unless otherwise indicated below, the Content
-        is provided to you under the terms and conditions of the MIT
-        License. A copy of the MIT License is available at
-        <a href="https://opensource.org/licenses/MIT">https://opensource.org/licenses/MIT</a>.
-        For purposes of the MIT License, &quot;Software&quot; will mean the
-        Content.
-    </p>
-
-    <p>
-        If you did not receive this Content directly from the Eclipse
-        Foundation, the Content is being redistributed by another party
-        (&quot;Redistributor&quot;) and different terms and conditions may
-        apply to your use of any object code in the Content. Check the
-        Redistributor's license that was provided with the Content. If no such
-        license exists, contact the Redistributor. Unless otherwise indicated
-        below, the terms and conditions of the MIT License still apply to any 
-        source code in the Content and such source code may be obtained at
-        <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.
-    </p>
-
-    <h3>Third Party Content</h3>
-    <p>
-        The Content includes items that have been sourced from third
-        parties as set out below. If you did not receive this Content directly
-        from the Eclipse Foundation, the following is provided for
-        informational purposes only, and you should look to the
-        Redistributor's license for terms and conditions of use.
-    </p>
-
-    <h4>JavaBDD</h4>
-    <p>
-        The Content includes JavaBDD 4.0.0, distributed by Maven Central
-        (<a href="https://search.maven.org/artifact/com.github.com-github-javabdd/com.github.javabdd/4.0.0/jar"
-        >https://search.maven.org/artifact/com.github.com-github-javabdd/com.github.javabdd/4.0.0/jar</a>).
-        The JavaBDD source code can be found at GitHub
-        (<a href="https://github.com/com-github-javabdd/com.github.javabdd"
-        >https://github.com/com-github-javabdd/com.github.javabdd</a>).
-        The Content includes an unmodified copy of JavaBDD.
-    </p>
-
-    <p>
-        JavaBDD is licensed under the GNU Library General Public License v2 (LGPLv2) or later.
-        See <a href="https://github.com/com-github-javabdd/com.github.javabdd/blob/master/LICENSE.txt"
-        >https://github.com/com-github-javabdd/com.github.javabdd/blob/master/LICENSE.txt</a>.
-    </p>
-
-    <p>
-        SPDX-License-Identifier: LGPL-2.0-or-later
-    </p>
-
-</body>
-</html>
diff --git a/thirdparty/com.github.javabdd/build.properties b/thirdparty/com.github.javabdd/build.properties
deleted file mode 100644
index 2db64ca340663b9bd622cca9a6f9b43931cd4530..0000000000000000000000000000000000000000
--- a/thirdparty/com.github.javabdd/build.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-bin.includes = META-INF/,\
-               lib/com.github.javabdd-4.0.0.jar,\
-               about.html
-src.includes = lib/com.github.javabdd-4.0.0-sources.jar,\
-               about.html
diff --git a/thirdparty/com.github.javabdd/lib/com.github.javabdd-4.0.0-sources.jar b/thirdparty/com.github.javabdd/lib/com.github.javabdd-4.0.0-sources.jar
deleted file mode 100644
index e27ac201acc8d4961ab29a5793907153c65e493c..0000000000000000000000000000000000000000
Binary files a/thirdparty/com.github.javabdd/lib/com.github.javabdd-4.0.0-sources.jar and /dev/null differ
diff --git a/thirdparty/com.github.javabdd/lib/com.github.javabdd-4.0.0.jar b/thirdparty/com.github.javabdd/lib/com.github.javabdd-4.0.0.jar
deleted file mode 100644
index 756cbdf0c1a6df412e613acb0127dfa871d7186d..0000000000000000000000000000000000000000
Binary files a/thirdparty/com.github.javabdd/lib/com.github.javabdd-4.0.0.jar and /dev/null differ
diff --git a/thirdparty/com.github.javabdd.feature/.project b/thirdparty/org.eclipse.escet.thirdparty.feature/.project
similarity index 86%
rename from thirdparty/com.github.javabdd.feature/.project
rename to thirdparty/org.eclipse.escet.thirdparty.feature/.project
index e5d332196714b8c5a49907faed9f178f54ac49ca..507cc24b4cb1fbe0b81ceeed6068a77538552342 100644
--- a/thirdparty/com.github.javabdd.feature/.project
+++ b/thirdparty/org.eclipse.escet.thirdparty.feature/.project
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <projectDescription>
-	<name>com.github.javabdd.feature</name>
+	<name>org.eclipse.escet.thirdparty.feature</name>
 	<comment></comment>
 	<projects>
 	</projects>
diff --git a/cif/org.eclipse.escet.cif.examples/examples/.settings/org.eclipse.core.resources.prefs b/thirdparty/org.eclipse.escet.thirdparty.feature/.settings/org.eclipse.core.resources.prefs
similarity index 100%
rename from cif/org.eclipse.escet.cif.examples/examples/.settings/org.eclipse.core.resources.prefs
rename to thirdparty/org.eclipse.escet.thirdparty.feature/.settings/org.eclipse.core.resources.prefs
diff --git a/thirdparty/com.github.javabdd.feature/build.properties b/thirdparty/org.eclipse.escet.thirdparty.feature/build.properties
similarity index 66%
rename from thirdparty/com.github.javabdd.feature/build.properties
rename to thirdparty/org.eclipse.escet.thirdparty.feature/build.properties
index df8eead974f78b2db20e60f66df2a7b6250c7ac4..a11c96161578d111e9a234eaa6f97521ba9b4358 100644
--- a/thirdparty/com.github.javabdd.feature/build.properties
+++ b/thirdparty/org.eclipse.escet.thirdparty.feature/build.properties
@@ -1,7 +1,5 @@
 bin.includes = feature.xml,\
                license.html,\
-               lgpl-2.0-or-later.html,\
                feature.properties
 src.includes = license.html,\
-               lgpl-2.0-or-later.html,\
                feature.properties
diff --git a/thirdparty/com.github.javabdd.feature/feature.properties b/thirdparty/org.eclipse.escet.thirdparty.feature/feature.properties
similarity index 99%
rename from thirdparty/com.github.javabdd.feature/feature.properties
rename to thirdparty/org.eclipse.escet.thirdparty.feature/feature.properties
index c8a5430c468966c1076011535f2390e8f2cc43eb..97d0e6fdecc8a65e035510d3dbc39487bb18a19e 100644
--- a/thirdparty/com.github.javabdd.feature/feature.properties
+++ b/thirdparty/org.eclipse.escet.thirdparty.feature/feature.properties
@@ -1,4 +1,4 @@
-copyright=Copyright (c) 2001-2022 John Whaley and com.github.javabdd contributors
+copyright=Copyright (c) 2017, 2023 Contributors to the Eclipse Foundation
 
 licenseURL=license.html
 
diff --git a/thirdparty/org.eclipse.escet.thirdparty.feature/feature.xml b/thirdparty/org.eclipse.escet.thirdparty.feature/feature.xml
new file mode 100644
index 0000000000000000000000000000000000000000..57e4148e19b5f802a0a8db20a8af940586d7d9b4
--- /dev/null
+++ b/thirdparty/org.eclipse.escet.thirdparty.feature/feature.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+
+  See the NOTICE file(s) distributed with this work for additional
+  information regarding copyright ownership.
+
+  This program and the accompanying materials are made available under the terms
+  of the MIT License which is available at https://opensource.org/licenses/MIT
+
+  SPDX-License-Identifier: MIT
+-->
+<feature
+      id="org.eclipse.escet.thirdparty.feature"
+      label="ESCET Third Party Dependencies (Incubation)"
+      version="0.10.0.qualifier"
+      provider-name="Eclipse ESCET">
+
+   <description>
+      Eclipse ESCET third party dependencies that are redistributed by the Eclipse ESCET project.
+   </description>
+
+   <copyright>
+      %copyright
+   </copyright>
+
+   <license url="%licenseURL">
+      %license
+   </license>
+
+   <plugin
+         id="com.github.com-github-javabdd.com.github.javabdd"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.apache.commons.commons-text"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+</feature>
diff --git a/thirdparty/com.github.javabdd.feature/license.html b/thirdparty/org.eclipse.escet.thirdparty.feature/license.html
similarity index 100%
rename from thirdparty/com.github.javabdd.feature/license.html
rename to thirdparty/org.eclipse.escet.thirdparty.feature/license.html
diff --git a/tooldef/org.eclipse.escet.tooldef.common/.settings/org.eclipse.jdt.core.prefs b/tooldef/org.eclipse.escet.tooldef.common/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/tooldef/org.eclipse.escet.tooldef.common/.settings/org.eclipse.jdt.core.prefs
+++ b/tooldef/org.eclipse.escet.tooldef.common/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/tooldef/org.eclipse.escet.tooldef.common/.settings/org.eclipse.jdt.ui.prefs b/tooldef/org.eclipse.escet.tooldef.common/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/tooldef/org.eclipse.escet.tooldef.common/.settings/org.eclipse.jdt.ui.prefs
+++ b/tooldef/org.eclipse.escet.tooldef.common/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/tooldef/org.eclipse.escet.tooldef.common/.settings/org.eclipse.ltk.core.refactoring.prefs b/tooldef/org.eclipse.escet.tooldef.common/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/tooldef/org.eclipse.escet.tooldef.common/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/tooldef/org.eclipse.escet.tooldef.common/META-INF/MANIFEST.MF b/tooldef/org.eclipse.escet.tooldef.common/META-INF/MANIFEST.MF
index 8f2c133def2b219d249b7a53652f8ea3f5c1bb9c..49c465673c3d60b5223ca813a776733ea77d8a39 100644
--- a/tooldef/org.eclipse.escet.tooldef.common/META-INF/MANIFEST.MF
+++ b/tooldef/org.eclipse.escet.tooldef.common/META-INF/MANIFEST.MF
@@ -2,15 +2,15 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET ToolDef Common (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.tooldef.common;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
 Export-Package: org.eclipse.escet.tooldef.common
-Require-Bundle: org.eclipse.escet.tooldef.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.tooldef.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
  org.apache.commons.lang3;bundle-version="3.1.0",
- org.eclipse.escet.common.emf;bundle-version="0.9.0",
- org.eclipse.escet.tooldef.metamodel.java;bundle-version="0.9.0",
+ org.eclipse.escet.common.emf;bundle-version="0.10.0",
+ org.eclipse.escet.tooldef.metamodel.java;bundle-version="0.10.0",
  org.eclipse.core.runtime;bundle-version="3.17.0",
  org.eclipse.core.resources;bundle-version="3.13.600",
  org.eclipse.jdt.core;bundle-version="3.20.0",
diff --git a/tooldef/org.eclipse.escet.tooldef.documentation/META-INF/MANIFEST.MF b/tooldef/org.eclipse.escet.tooldef.documentation/META-INF/MANIFEST.MF
index 3aa75f2887a44345dbbcc9fa9dc404c047d9b7c4..37422e8a47f219322f7b4d23671408f7a88538e2 100644
--- a/tooldef/org.eclipse.escet.tooldef.documentation/META-INF/MANIFEST.MF
+++ b/tooldef/org.eclipse.escet.tooldef.documentation/META-INF/MANIFEST.MF
@@ -2,6 +2,6 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET ToolDef Documentation (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.tooldef.documentation;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Require-Bundle: org.eclipse.help
diff --git a/tooldef/org.eclipse.escet.tooldef.documentation/asciidoc/documentation.asciidoc b/tooldef/org.eclipse.escet.tooldef.documentation/asciidoc/documentation.asciidoc
index 5138ba9b152563cf894f15292496c939fa75461e..3a4bcd5d8593f13acb7f907eb532e7fbefa08885 100644
--- a/tooldef/org.eclipse.escet.tooldef.documentation/asciidoc/documentation.asciidoc
+++ b/tooldef/org.eclipse.escet.tooldef.documentation/asciidoc/documentation.asciidoc
@@ -29,7 +29,7 @@ ToolDef is a cross-platform and machine-independent scripting language.
 It supports command line execution, but is also available as plug-in for the link:https://eclipse.org[Eclipse] IDE, providing an integrated development experience.
 
 ToolDef is one of the tools of the Eclipse ESCET(TM) project.
-Visit the link:https://eclipse.org/escet/{escet-website-version}[project website] for downloads, installation instructions, source code, general tool usage information, information on how to contribute, and more.
+Visit the link:https://eclipse.dev/escet/{escet-website-version}[project website] for downloads, installation instructions, source code, general tool usage information, information on how to contribute, and more.
 
 [WARNING]
 ====
diff --git a/tooldef/org.eclipse.escet.tooldef.documentation/asciidoc/language-reference/builtins/file.asciidoc b/tooldef/org.eclipse.escet.tooldef.documentation/asciidoc/language-reference/builtins/file.asciidoc
index d697d7ab9196f2c203c3207141089f851d025f92..b63b9709a8ad57b09875acc08e2a0bacc2cc2999 100644
--- a/tooldef/org.eclipse.escet.tooldef.documentation/asciidoc/language-reference/builtins/file.asciidoc
+++ b/tooldef/org.eclipse.escet.tooldef.documentation/asciidoc/language-reference/builtins/file.asciidoc
@@ -468,6 +468,7 @@ tool list string readlines(string path)
 ----
 
 Read lines of text from a file.
+Uses UTF-8 encoding when reading the file.
 
 _Parameters_
 
@@ -563,11 +564,12 @@ indexterm:[writefile]
 
 [source, tooldef]
 ----
-tool writefile(string path, string text,       bool append = false)
-tool writefile(string path, list string lines, bool append = false)
+tool writefile(string path, string text,       bool append = false, string newline = "platform")
+tool writefile(string path, list string lines, bool append = false, string newline = "platform")
 ----
 
 Writes text to a file.
+Uses UTF-8 encoding when writing the file.
 
 _Parameters_
 
@@ -577,10 +579,34 @@ May contain both `\` and `/` as file separators.
 
 `text`, `lines`::
 The text or lines of text to write to the file.
+In case `lines` are given, a new line will additionally be written after each line of text.
 
 `append`::
 Whether to append the lines text to the file if it already exists (`true`), or overwrite the file if it already exists (`false`).
 
+`newline`::
+Indicates how to handle new lines:
++
+[cols="1,5"]
+|===
+| Value | Effect
+
+| `"platform"`
+| Write the text or lines of text with platform-specific new lines.
+All new lines in the given `text` or `lines` are replaced by the new line of the current platform.
+The new line of the current platform is also written after each of the `lines`.
+
+|`"preserve"`
+| Write the `text` 'as is'.
+The new lines as they are in the given `text` are preserved.
+Using `"preserve"` is not supported when writing `lines`.
+
+| Any other value
+| Write the text or lines of text with the given new line.
+All new lines in the given `text` or `lines` are replaced by the given new line text.
+The given new line text is also written after each of the `lines`.
+|===
+
 _Runtime errors_
 
 * If the path exists but is a directory rather than a regular file.
@@ -588,3 +614,4 @@ _Runtime errors_
 * If the file can not be opened for writing for any other reason.
 * If writing to the file fails due to an I/O error.
 * If closing the file fails.
+* If `"preserve"` is given for `newline` when writing `lines`.
diff --git a/tooldef/org.eclipse.escet.tooldef.documentation/asciidoc/release-notes.asciidoc b/tooldef/org.eclipse.escet.tooldef.documentation/asciidoc/release-notes.asciidoc
index fb5ffb75a26e9af5e9083fde56162fe2120bfc12..bca9967d98ac412df400ded5dc7ce5acd89a28a4 100644
--- a/tooldef/org.eclipse.escet.tooldef.documentation/asciidoc/release-notes.asciidoc
+++ b/tooldef/org.eclipse.escet.tooldef.documentation/asciidoc/release-notes.asciidoc
@@ -20,7 +20,26 @@ indexterm:[release, notes]
 
 The release notes for the versions of ToolDef and the associated tools, as part of the Eclipse ESCET project, are listed below in reverse chronological order.
 
-See also the Eclipse ESCET link:https://eclipse.org/escet/{escet-website-version}/release-notes.html[toolkit release notes] covering those aspects that are common to the various Eclipse ESCET tools.
+See also the Eclipse ESCET link:https://eclipse.dev/escet/{escet-website-version}/release-notes.html[toolkit release notes] covering those aspects that are common to the various Eclipse ESCET tools.
+
+=== Version 0.10
+
+TBD
+
+New features:
+
+* The ToolDef interpreter has a new _Tool invocation_ option to invoke a specific tool with chosen arguments, rather than executing the entire script (issue {escet-issue}578[#578]).
+* The `writefile` built-in tool has a new optional `newline` parameter, allowing to configure new line handling.
+The default is still to use the new lines of the current platform.
+See the documentation for further details (issue {escet-issue}571[#571]).
+
+Improvements and fixes:
+
+* The `readlines` and `writefile` built-in tools have been made more robust with respect to closing file streams in case of I/O errors (issue {escet-issue}571[#571]).
+* The `readlines` built-in tool now uses the UTF-8 encoding when reading files, rather than the platform's default encoding (issue {escet-issue}571[#571]).
+* The `readlines` and `writefile` built-in tools now have improved documentation (issue {escet-issue}571[#571]).
+* The ToolDef interpreter's help text now properly explains the tool's exit codes (issue {escet-issue}573[#573]).
+* The ToolDef interpreter documentation has been slightly improved (issue {escet-issue}578[#578]).
 
 === Version 0.9 (2023-03-31)
 
diff --git a/tooldef/org.eclipse.escet.tooldef.documentation/asciidoc/tools.asciidoc b/tooldef/org.eclipse.escet.tooldef.documentation/asciidoc/tools.asciidoc
index 5d69f745f7a0f86b69bb54d4a2f2213a9a3af532..1c8fa478317bd5c62a4244f73cf1d25abdcbca9d 100644
--- a/tooldef/org.eclipse.escet.tooldef.documentation/asciidoc/tools.asciidoc
+++ b/tooldef/org.eclipse.escet.tooldef.documentation/asciidoc/tools.asciidoc
@@ -46,6 +46,15 @@ For details, execute the ToolDef interpreter with the `--help` or `-h` command l
 tooldef --help
 ----
 
+In particular, consider the following options:
+
+* _Tool invocation_ (`--invoke=INVOCATION` or `-i INVOCATION`)
++
+The tool to invoke, and its arguments, in ToolDef syntax.
+For example: `tooldef some_script.tooldef --invoke='mytool(1, true)'` to invoke the `mytool` tool with arguments `1` and `true`.
+If the option is not used, the entire ToolDef script is executed instead.
+By default, the entire script is executed.
+
 indexterm:[execution,Eclipse IDE]
 indexterm:[Eclipse IDE,execution]
 
@@ -54,9 +63,11 @@ indexterm:[Eclipse IDE,execution]
 indexterm:[options,Eclipse IDE]
 indexterm:[Eclipse IDE,options]
 To execute a ToolDef script in the Eclipse IDE, right click the file or an open text editor for the script, and choose menu:Execute ToolDef[].
-Alternatively, choose menu:Execute ToolDef...[] to first shown an option dialog, where several options that influence how the script is executed, before actually executing the script.
+Alternatively, choose menu:Execute ToolDef...[] to first shown an option dialog.
+The dialog shows several options that influence how the script is executed.
+These options can be configured as desired before executing the script.
 
-It is also possible to start executing a script by pressing kbd:[F10], while a `.tooldef` file is selected or an open text for such a file has the focus.
+It is also possible to start executing a script by pressing kbd:[F10], while a `.tooldef` file is selected or an open text editor for such a file has the focus.
 Finally, clicking the corresponding toolbar icon (image:{imgsdir}/tooldef_icon.png[]) has the same effect.
 
 Execution of ToolDef script can be manually terminated by means of the termination features of the _Applications_ view.
diff --git a/tooldef/org.eclipse.escet.tooldef.documentation/build-docs-tooldef.launch b/tooldef/org.eclipse.escet.tooldef.documentation/build-docs-tooldef.launch
index d4661523c51d522d71278ed1a42f6eae9cba8e38..c24d0a14d5b169701e84fa390814fc1093893dd7 100644
--- a/tooldef/org.eclipse.escet.tooldef.documentation/build-docs-tooldef.launch
+++ b/tooldef/org.eclipse.escet.tooldef.documentation/build-docs-tooldef.launch
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <launchConfiguration type="org.eclipse.m2e.Maven2LaunchConfigurationType">
+    <intAttribute key="M2_COLORS" value="0"/>
     <booleanAttribute key="M2_DEBUG_OUTPUT" value="false"/>
     <stringAttribute key="M2_GOALS" value="clean package --projects releng/org.eclipse.escet.releng.target,tooldef/org.eclipse.escet.tooldef.documentation --also-make"/>
     <booleanAttribute key="M2_NON_RECURSIVE" value="false"/>
@@ -15,6 +16,7 @@
     <booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="true"/>
     <stringAttribute key="M2_USER_SETTINGS" value=""/>
     <booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="false"/>
+    <booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
     <stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${workspace}"/>
     <mapAttribute key="org.eclipse.debug.core.environmentVariables">
         <mapEntry key="JAVA_HOME" value="${system_property:java.home}"/>
diff --git a/tooldef/org.eclipse.escet.tooldef.documentation/pom.xml b/tooldef/org.eclipse.escet.tooldef.documentation/pom.xml
index 20652fd0cdb21233ed061eb8633f6f81836c47ad..220725ddf57a1525130e6c43bdbc587e4d0f754e 100644
--- a/tooldef/org.eclipse.escet.tooldef.documentation/pom.xml
+++ b/tooldef/org.eclipse.escet.tooldef.documentation/pom.xml
@@ -16,7 +16,7 @@
     <parent>
         <groupId>org.eclipse.escet</groupId>
         <artifactId>org.eclipse.escet.root</artifactId>
-        <version>0.9.0-SNAPSHOT</version>
+        <version>0.10.0-SNAPSHOT</version>
         <relativePath>../../</relativePath>
     </parent>
 
diff --git a/tooldef/org.eclipse.escet.tooldef.feature/feature.xml b/tooldef/org.eclipse.escet.tooldef.feature/feature.xml
index 11f2f9d14ce919af7db0c94e0434dc2660281431..3538800498fe4d5f64edfedb1e597604cac68f57 100644
--- a/tooldef/org.eclipse.escet.tooldef.feature/feature.xml
+++ b/tooldef/org.eclipse.escet.tooldef.feature/feature.xml
@@ -13,11 +13,11 @@
 <feature
       id="org.eclipse.escet.tooldef.feature"
       label="ESCET ToolDef (Incubation)"
-      version="0.9.0.qualifier"
+      version="0.10.0.qualifier"
       provider-name="Eclipse ESCET"
       plugin="org.eclipse.escet.product.branding"
       license-feature="org.eclipse.escet.releng.license.mit"
-      license-feature-version="0.9.0.qualifier">
+      license-feature-version="0.10.0.qualifier">
 
    <description>
       Eclipse ESCET tooling for the ToolDef scripting language.
@@ -32,8 +32,8 @@
    </license>
 
    <requires>
-      <import feature="org.eclipse.escet.common.feature" version="0.9.0.qualifier"/>
-      <import feature="org.eclipse.escet.setext.feature" version="0.9.0.qualifier"/>
+      <import feature="org.eclipse.escet.common.feature" version="0.10.0.qualifier"/>
+      <import feature="org.eclipse.escet.setext.feature" version="0.10.0.qualifier"/>
       <import plugin="io.github.java-diff-utils"/>
       <import plugin="org.apache.commons.exec"/>
    </requires>
diff --git a/tooldef/org.eclipse.escet.tooldef.interpreter/.settings/org.eclipse.jdt.core.prefs b/tooldef/org.eclipse.escet.tooldef.interpreter/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/tooldef/org.eclipse.escet.tooldef.interpreter/.settings/org.eclipse.jdt.core.prefs
+++ b/tooldef/org.eclipse.escet.tooldef.interpreter/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/tooldef/org.eclipse.escet.tooldef.interpreter/.settings/org.eclipse.jdt.ui.prefs b/tooldef/org.eclipse.escet.tooldef.interpreter/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/tooldef/org.eclipse.escet.tooldef.interpreter/.settings/org.eclipse.jdt.ui.prefs
+++ b/tooldef/org.eclipse.escet.tooldef.interpreter/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/tooldef/org.eclipse.escet.tooldef.interpreter/.settings/org.eclipse.ltk.core.refactoring.prefs b/tooldef/org.eclipse.escet.tooldef.interpreter/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/tooldef/org.eclipse.escet.tooldef.interpreter/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/tooldef/org.eclipse.escet.tooldef.interpreter/META-INF/MANIFEST.MF b/tooldef/org.eclipse.escet.tooldef.interpreter/META-INF/MANIFEST.MF
index 2af0e8b7555bc9854edce6573d197aea2fd59f77..0a877ccf3d7d90a7658afd0b6fdcc8efc6350b0a 100644
--- a/tooldef/org.eclipse.escet.tooldef.interpreter/META-INF/MANIFEST.MF
+++ b/tooldef/org.eclipse.escet.tooldef.interpreter/META-INF/MANIFEST.MF
@@ -2,22 +2,23 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET ToolDef Interpreter (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.tooldef.interpreter;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.common.eclipse.ui;bundle-version="0.9.0",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.common.eclipse.ui;bundle-version="0.10.0",
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
  org.eclipse.core.resources;bundle-version="3.13.600",
  org.eclipse.jface.text;bundle-version="3.16.100",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.tooldef.io;bundle-version="0.9.0",
- org.eclipse.escet.tooldef.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
- org.eclipse.escet.tooldef.parser;bundle-version="0.9.0",
- org.eclipse.escet.tooldef.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.tooldef.runtime;bundle-version="0.9.0",
- org.eclipse.escet.tooldef.common;bundle-version="0.9.0"
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.tooldef.io;bundle-version="0.10.0",
+ org.eclipse.escet.tooldef.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.tooldef.parser;bundle-version="0.10.0",
+ org.eclipse.escet.tooldef.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.tooldef.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.tooldef.common;bundle-version="0.10.0",
+ org.eclipse.escet.tooldef.metamodel.java;bundle-version="0.10.0"
 Export-Package: org.eclipse.escet.tooldef.interpreter
 Automatic-Module-Name: org.eclipse.escet.tooldef.interpreter
diff --git a/tooldef/org.eclipse.escet.tooldef.interpreter/src/org/eclipse/escet/tooldef/interpreter/ToolDefInterpreter.java b/tooldef/org.eclipse.escet.tooldef.interpreter/src/org/eclipse/escet/tooldef/interpreter/ToolDefInterpreter.java
index 4d4e495501013ce823e9ffea69ca4763e959588b..e4d3acd882d5540ca2f9dbf846aeddb0fecc2ffd 100644
--- a/tooldef/org.eclipse.escet.tooldef.interpreter/src/org/eclipse/escet/tooldef/interpreter/ToolDefInterpreter.java
+++ b/tooldef/org.eclipse.escet.tooldef.interpreter/src/org/eclipse/escet/tooldef/interpreter/ToolDefInterpreter.java
@@ -19,6 +19,7 @@ import org.eclipse.escet.common.app.framework.AppEnv;
 import org.eclipse.escet.common.java.Assert;
 import org.eclipse.escet.tooldef.metamodel.tooldef.Declaration;
 import org.eclipse.escet.tooldef.metamodel.tooldef.Script;
+import org.eclipse.escet.tooldef.metamodel.tooldef.statements.ToolInvokeStatement;
 import org.eclipse.escet.tooldef.runtime.ExitException;
 
 /** ToolDef interpreter. */
@@ -34,10 +35,11 @@ public class ToolDefInterpreter {
      * @param script The ToolDef script to execute.
      * @param path The absolute local file system path to the script. The path contains file separators for the current
      *     platform.
+     * @param invocation The tool invocation to execute, or {@code null} to execute the entire script.
      * @param app The ToolDef interpreter application.
      * @return The exit code.
      */
-    public static int execute(Script script, String path, ToolDefInterpreterApp app) {
+    public static int execute(Script script, String path, ToolInvokeStatement invocation, ToolDefInterpreterApp app) {
         // Store script path. Used by the 'scriptpath' built-in tool.
         final String propName = "org.eclipse.escet.tooldef.interpreter.scriptpath";
         AppEnv.setProperty(propName, path);
@@ -45,12 +47,18 @@ public class ToolDefInterpreter {
         // Create new execution context.
         ExecContext ctxt = new ExecContext(app);
 
-        // Execute statements.
+        // Get statements to execute.
+        List<Declaration> statements = (invocation == null) ? script.getDeclarations() : List.of(invocation);
+
+        // Execute the statements.
         int exitCode;
         try {
-            List<Declaration> statements = script.getDeclarations();
             ToolDefReturnValue retValue = ToolDefExec.execute(statements, ctxt);
-            Assert.check(retValue == null);
+
+            // No return value for a script.
+            Assert.implies(invocation == null, retValue == null);
+
+            // Ignore the return value in case a tool invocation is executed.
             exitCode = 0;
         } catch (ExitException ex) {
             exitCode = ex.exitCode;
diff --git a/tooldef/org.eclipse.escet.tooldef.interpreter/src/org/eclipse/escet/tooldef/interpreter/ToolDefInterpreterApp.java b/tooldef/org.eclipse.escet.tooldef.interpreter/src/org/eclipse/escet/tooldef/interpreter/ToolDefInterpreterApp.java
index 42c8d55b6504ab10878a2a2386ff1cf6e2699f59..325e574980dabd0ce363fab59ef752af18bfc061 100644
--- a/tooldef/org.eclipse.escet.tooldef.interpreter/src/org/eclipse/escet/tooldef/interpreter/ToolDefInterpreterApp.java
+++ b/tooldef/org.eclipse.escet.tooldef.interpreter/src/org/eclipse/escet/tooldef/interpreter/ToolDefInterpreterApp.java
@@ -15,12 +15,17 @@ package org.eclipse.escet.tooldef.interpreter;
 
 import static org.eclipse.escet.common.app.framework.output.OutputProvider.dbg;
 import static org.eclipse.escet.common.java.Lists.list;
+import static org.eclipse.escet.common.java.Strings.fmt;
 
 import java.util.List;
+import java.util.stream.Collectors;
 
 import org.eclipse.escet.common.app.framework.Application;
 import org.eclipse.escet.common.app.framework.Paths;
+import org.eclipse.escet.common.app.framework.exceptions.InvalidOptionException;
+import org.eclipse.escet.common.app.framework.io.AppStream;
 import org.eclipse.escet.common.app.framework.io.AppStreams;
+import org.eclipse.escet.common.app.framework.options.HelpOption;
 import org.eclipse.escet.common.app.framework.options.InputFileOption;
 import org.eclipse.escet.common.app.framework.options.Option;
 import org.eclipse.escet.common.app.framework.options.OptionCategory;
@@ -29,8 +34,19 @@ import org.eclipse.escet.common.app.framework.output.IOutputComponent;
 import org.eclipse.escet.common.app.framework.output.OutputMode;
 import org.eclipse.escet.common.app.framework.output.OutputModeOption;
 import org.eclipse.escet.common.app.framework.output.OutputProvider;
+import org.eclipse.escet.common.java.Assert;
+import org.eclipse.escet.common.typechecker.SemanticProblem;
+import org.eclipse.escet.common.typechecker.SemanticProblemSeverity;
+import org.eclipse.escet.setext.runtime.DebugMode;
+import org.eclipse.escet.setext.runtime.exceptions.SyntaxException;
 import org.eclipse.escet.tooldef.io.ToolDefReader;
+import org.eclipse.escet.tooldef.metamodel.java.ToolDefConstructors;
 import org.eclipse.escet.tooldef.metamodel.tooldef.Script;
+import org.eclipse.escet.tooldef.metamodel.tooldef.expressions.ToolInvokeExpression;
+import org.eclipse.escet.tooldef.metamodel.tooldef.statements.ToolInvokeStatement;
+import org.eclipse.escet.tooldef.parser.ToolDefInvokeParser;
+import org.eclipse.escet.tooldef.typechecker.CheckerContext;
+import org.eclipse.escet.tooldef.typechecker.ToolDefTypeChecker;
 
 /** ToolDef interpreter application. */
 public class ToolDefInterpreterApp extends Application<IOutputComponent> {
@@ -68,6 +84,15 @@ public class ToolDefInterpreterApp extends Application<IOutputComponent> {
         return "The ToolDef interpreter executes ToolDef scripts.";
     }
 
+    @Override
+    public void printHelpExitCodes(AppStream s) {
+        super.printHelpExitCodes(s);
+        HelpOption.outw(s, "In certain cases, the ToolDef script may produce an exit code different from the default "
+                + "exit code. For instance, in case an \"exit\" statement with a custom exit code is successfully "
+                + "executed, or in case the \"tooldef\" tool is used to execute a ToolDef script that produces a "
+                + "non-zero exit code and \"ignoreNonZeroExitCode\" is set to \"false\".");
+    }
+
     @Override
     protected int runInternal() {
         // Initialize debugging.
@@ -87,17 +112,57 @@ public class ToolDefInterpreterApp extends Application<IOutputComponent> {
         // Get script path.
         String scriptPath = Paths.resolve(inputPath);
 
-        // Execute script.
+        // Get tool invocation, if any.
+        String invocationText = ToolDefInvokeOption.getInvocationText();
+        ToolInvokeStatement invocation = invocationText == null ? null
+                : getInvocation(invocationText, reader.getTypeChecker());
+
+        // Execute script or tool invocation.
+        String whatIsExecuted = (invocation == null) ? "script" : "tool";
         if (dbgEnabled) {
-            dbg("Executing ToolDef script.");
+            dbg("Executing ToolDef %s.", whatIsExecuted);
         }
-        int exitCode = ToolDefInterpreter.execute(script, scriptPath, this);
+        int exitCode = ToolDefInterpreter.execute(script, scriptPath, invocation, this);
         if (dbgEnabled) {
-            dbg("Finished executing ToolDef script (exit code %d).", exitCode);
+            dbg("Finished executing ToolDef %s (exit code %d).", whatIsExecuted, exitCode);
         }
         return exitCode;
     }
 
+    /**
+     * Get the tool invocation for the given tool invocation text, by parsing and type checking it.
+     *
+     * @param invocationText The tool invocation text, in ToolDef textual syntax. Maybe
+     * @param tchecker The type checker use to check the ToolDef script.
+     * @return The tool invocation.
+     */
+    private ToolInvokeStatement getInvocation(String invocationText, ToolDefTypeChecker tchecker) {
+        // Parse it.
+        ToolDefInvokeParser parser = new ToolDefInvokeParser();
+        ToolInvokeExpression invocationExpr;
+        try {
+            invocationExpr = parser.parseString(invocationText, CheckerContext.TOOL_INVOCATION_LOCATION, null,
+                    DebugMode.NONE);
+        } catch (SyntaxException e) {
+            String msg = fmt("The tool invocation provided via the 'Tool invocation' option is invalid: \"%s\".",
+                    invocationText);
+            throw new InvalidOptionException(msg, e);
+        }
+        Assert.check(parser.getWarnings().isEmpty());
+
+        // Type check it. Ignore any warnings.
+        ToolInvokeStatement invocationStatement = ToolDefConstructors.newToolInvokeStatement(invocationExpr, null);
+        List<SemanticProblem> problems = tchecker.typeCheck(invocationStatement);
+        List<SemanticProblem> errors = problems.stream().filter(p -> p.severity == SemanticProblemSeverity.ERROR)
+                .toList();
+        if (!errors.isEmpty()) {
+            String msg = fmt("The tool invocation provided via the 'Tool invocation' option is invalid: \"%s\":\n",
+                    invocationText) + errors.stream().map(p -> " - " + p.toString()).collect(Collectors.joining("\n"));
+            throw new InvalidOptionException(msg);
+        }
+        return invocationStatement;
+    }
+
     @Override
     protected OutputProvider<IOutputComponent> getProvider() {
         return new OutputProvider<>();
@@ -108,10 +173,12 @@ public class ToolDefInterpreterApp extends Application<IOutputComponent> {
     protected OptionCategory getAllOptions() {
         OptionCategory generalCat = getGeneralOptionCategory();
 
-        List<Option> transOpts = list();
-        transOpts.add(Options.getInstance(InputFileOption.class));
-        List<OptionCategory> transSubCats = list();
-        OptionCategory transCat = new OptionCategory("Interpreter", "Interpreter options.", transSubCats, transOpts);
+        List<Option> interpreterOpts = list();
+        interpreterOpts.add(Options.getInstance(InputFileOption.class));
+        interpreterOpts.add(Options.getInstance(ToolDefInvokeOption.class));
+        List<OptionCategory> interpreterSubCats = list();
+        OptionCategory transCat = new OptionCategory("Interpreter", "Interpreter options.", interpreterSubCats,
+                interpreterOpts);
 
         List<OptionCategory> cats = list(generalCat, transCat);
         OptionCategory options = new OptionCategory("ToolDef Interpreter Options",
diff --git a/tooldef/org.eclipse.escet.tooldef.interpreter/src/org/eclipse/escet/tooldef/interpreter/ToolDefInvokeOption.java b/tooldef/org.eclipse.escet.tooldef.interpreter/src/org/eclipse/escet/tooldef/interpreter/ToolDefInvokeOption.java
new file mode 100644
index 0000000000000000000000000000000000000000..c7ea3b2a46333a12d1d99e3955ec48b89fbfbaf1
--- /dev/null
+++ b/tooldef/org.eclipse.escet.tooldef.interpreter/src/org/eclipse/escet/tooldef/interpreter/ToolDefInvokeOption.java
@@ -0,0 +1,69 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+package org.eclipse.escet.tooldef.interpreter;
+
+import org.eclipse.escet.common.app.framework.options.Options;
+import org.eclipse.escet.common.app.framework.options.StringOption;
+
+/** ToolDef interpreter option to invoke a specific tool rather than the entire script. */
+public class ToolDefInvokeOption extends StringOption {
+    /** The option description. */
+    private static final String DESCRIPTION = "The tool to invoke, and its arguments, in ToolDef syntax. "
+            + "For example: \"mytool(1, true)\". "
+            + "If the option is not used, the entire ToolDef script is executed instead. "
+            + "By default, the entire script is executed.";
+
+    /** Constructor for the {@link ToolDefInvokeOption} class. */
+    public ToolDefInvokeOption() {
+        super(
+                // name
+                "Tool invocation",
+
+                // description
+                DESCRIPTION,
+
+                // cmdShort
+                'i',
+
+                // cmdLong
+                "invoke",
+
+                // cmdValue
+                "INVOCATION",
+
+                // defaultValue
+                null,
+
+                // emptyAsNull
+                true,
+
+                // showInDialog
+                true,
+
+                // optDialogDescr
+                DESCRIPTION,
+
+                // optDialogLabelText
+                "Invocation:");
+    }
+
+    /**
+     * Returns the value of the {@link ToolDefInvokeOption} option.
+     *
+     * @return The value of the {@link ToolDefInvokeOption} option.
+     */
+    public static String getInvocationText() {
+        return Options.get(ToolDefInvokeOption.class);
+    }
+}
diff --git a/tooldef/org.eclipse.escet.tooldef.io/.settings/org.eclipse.jdt.core.prefs b/tooldef/org.eclipse.escet.tooldef.io/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/tooldef/org.eclipse.escet.tooldef.io/.settings/org.eclipse.jdt.core.prefs
+++ b/tooldef/org.eclipse.escet.tooldef.io/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/tooldef/org.eclipse.escet.tooldef.io/.settings/org.eclipse.jdt.ui.prefs b/tooldef/org.eclipse.escet.tooldef.io/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/tooldef/org.eclipse.escet.tooldef.io/.settings/org.eclipse.jdt.ui.prefs
+++ b/tooldef/org.eclipse.escet.tooldef.io/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/tooldef/org.eclipse.escet.tooldef.io/.settings/org.eclipse.ltk.core.refactoring.prefs b/tooldef/org.eclipse.escet.tooldef.io/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/tooldef/org.eclipse.escet.tooldef.io/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/tooldef/org.eclipse.escet.tooldef.io/META-INF/MANIFEST.MF b/tooldef/org.eclipse.escet.tooldef.io/META-INF/MANIFEST.MF
index 8f86042255a9980c48b69eb03e035f530ab8fdf3..0f33cc81f6f9e267894271bb8d63b5b084cd0bdc 100644
--- a/tooldef/org.eclipse.escet.tooldef.io/META-INF/MANIFEST.MF
+++ b/tooldef/org.eclipse.escet.tooldef.io/META-INF/MANIFEST.MF
@@ -2,14 +2,14 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET ToolDef I/O (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.tooldef.io;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
- org.eclipse.escet.tooldef.parser;bundle-version="0.9.0",
- org.eclipse.escet.tooldef.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.tooldef.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0"
+Require-Bundle: org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.tooldef.parser;bundle-version="0.10.0",
+ org.eclipse.escet.tooldef.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.tooldef.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0"
 Export-Package: org.eclipse.escet.tooldef.io
 Automatic-Module-Name: org.eclipse.escet.tooldef.io
diff --git a/tooldef/org.eclipse.escet.tooldef.metamodel.java/.settings/org.eclipse.jdt.core.prefs b/tooldef/org.eclipse.escet.tooldef.metamodel.java/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/tooldef/org.eclipse.escet.tooldef.metamodel.java/.settings/org.eclipse.jdt.core.prefs
+++ b/tooldef/org.eclipse.escet.tooldef.metamodel.java/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/tooldef/org.eclipse.escet.tooldef.metamodel.java/.settings/org.eclipse.jdt.ui.prefs b/tooldef/org.eclipse.escet.tooldef.metamodel.java/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/tooldef/org.eclipse.escet.tooldef.metamodel.java/.settings/org.eclipse.jdt.ui.prefs
+++ b/tooldef/org.eclipse.escet.tooldef.metamodel.java/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/tooldef/org.eclipse.escet.tooldef.metamodel.java/.settings/org.eclipse.ltk.core.refactoring.prefs b/tooldef/org.eclipse.escet.tooldef.metamodel.java/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/tooldef/org.eclipse.escet.tooldef.metamodel.java/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/tooldef/org.eclipse.escet.tooldef.metamodel.java/META-INF/MANIFEST.MF b/tooldef/org.eclipse.escet.tooldef.metamodel.java/META-INF/MANIFEST.MF
index 326dbad755834aac315aaa6f6f4bee71516cd7c0..46d5ecfb78ad08c5af1fca0e1195257b9e17e366 100644
--- a/tooldef/org.eclipse.escet.tooldef.metamodel.java/META-INF/MANIFEST.MF
+++ b/tooldef/org.eclipse.escet.tooldef.metamodel.java/META-INF/MANIFEST.MF
@@ -2,11 +2,11 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET ToolDef Metamodel Java Support (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.tooldef.metamodel.java;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.tooldef.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0"
+Require-Bundle: org.eclipse.escet.tooldef.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0"
 Export-Package: org.eclipse.escet.tooldef.metamodel.java
 Automatic-Module-Name: org.eclipse.escet.tooldef.metamodel.java
diff --git a/tooldef/org.eclipse.escet.tooldef.metamodel/.settings/org.eclipse.jdt.core.prefs b/tooldef/org.eclipse.escet.tooldef.metamodel/.settings/org.eclipse.jdt.core.prefs
index a39882dc615f390c7a829a2c18eb7f17ffd8668b..eabbae9d848583c4a9412f97a7c7b9c9b344ef90 100644
--- a/tooldef/org.eclipse.escet.tooldef.metamodel/.settings/org.eclipse.jdt.core.prefs
+++ b/tooldef/org.eclipse.escet.tooldef.metamodel/.settings/org.eclipse.jdt.core.prefs
@@ -126,6 +126,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/tooldef/org.eclipse.escet.tooldef.metamodel/.settings/org.eclipse.ltk.core.refactoring.prefs b/tooldef/org.eclipse.escet.tooldef.metamodel/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/tooldef/org.eclipse.escet.tooldef.metamodel/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/tooldef/org.eclipse.escet.tooldef.metamodel/META-INF/MANIFEST.MF b/tooldef/org.eclipse.escet.tooldef.metamodel/META-INF/MANIFEST.MF
index 529106a7a87a5a6008af4f7f22b3bed2eba80a63..1d978c29d67eacb182ff6146dba085095607a915 100644
--- a/tooldef/org.eclipse.escet.tooldef.metamodel/META-INF/MANIFEST.MF
+++ b/tooldef/org.eclipse.escet.tooldef.metamodel/META-INF/MANIFEST.MF
@@ -2,13 +2,13 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.escet.tooldef.metamodel;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-ClassPath: .
 Require-Bundle: org.eclipse.core.runtime;bundle-version="3.17.0",
  org.eclipse.emf.ecore;bundle-version="2.20.0";visibility:=reexport,
- org.eclipse.escet.common.position.metamodel;bundle-version="0.9.0";visibility:=reexport,
- org.eclipse.escet.common.emf.ecore.xmi;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0"
+ org.eclipse.escet.common.position.metamodel;bundle-version="0.10.0";visibility:=reexport,
+ org.eclipse.escet.common.emf.ecore.xmi;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0"
 Bundle-ActivationPolicy: lazy
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
diff --git a/tooldef/org.eclipse.escet.tooldef.parser/.settings/org.eclipse.jdt.core.prefs b/tooldef/org.eclipse.escet.tooldef.parser/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/tooldef/org.eclipse.escet.tooldef.parser/.settings/org.eclipse.jdt.core.prefs
+++ b/tooldef/org.eclipse.escet.tooldef.parser/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/tooldef/org.eclipse.escet.tooldef.parser/.settings/org.eclipse.jdt.ui.prefs b/tooldef/org.eclipse.escet.tooldef.parser/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/tooldef/org.eclipse.escet.tooldef.parser/.settings/org.eclipse.jdt.ui.prefs
+++ b/tooldef/org.eclipse.escet.tooldef.parser/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/tooldef/org.eclipse.escet.tooldef.parser/.settings/org.eclipse.ltk.core.refactoring.prefs b/tooldef/org.eclipse.escet.tooldef.parser/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/tooldef/org.eclipse.escet.tooldef.parser/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/tooldef/org.eclipse.escet.tooldef.parser/META-INF/MANIFEST.MF b/tooldef/org.eclipse.escet.tooldef.parser/META-INF/MANIFEST.MF
index fbb9e9c29dea16385a10498d0fa563ad24c5b140..75e455af8a00dd0ffe94eb50eddc67f866fee49a 100644
--- a/tooldef/org.eclipse.escet.tooldef.parser/META-INF/MANIFEST.MF
+++ b/tooldef/org.eclipse.escet.tooldef.parser/META-INF/MANIFEST.MF
@@ -2,16 +2,16 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET ToolDef Parser (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.tooldef.parser;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
 Export-Package: org.eclipse.escet.tooldef.parser
-Require-Bundle: org.eclipse.escet.tooldef.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.tooldef.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
  org.eclipse.jface.text;bundle-version="3.16.100",
- org.eclipse.escet.tooldef.metamodel.java;bundle-version="0.9.0",
- org.eclipse.escet.common.position.common;bundle-version="0.9.0",
- org.eclipse.escet.common.emf;bundle-version="0.9.0"
+ org.eclipse.escet.tooldef.metamodel.java;bundle-version="0.10.0",
+ org.eclipse.escet.common.position.common;bundle-version="0.10.0",
+ org.eclipse.escet.common.emf;bundle-version="0.10.0"
 Automatic-Module-Name: org.eclipse.escet.tooldef.parser
diff --git a/tooldef/org.eclipse.escet.tooldef.parser/src-gen/org/eclipse/escet/tooldef/parser/ToolDefHooks.skeleton b/tooldef/org.eclipse.escet.tooldef.parser/src-gen/org/eclipse/escet/tooldef/parser/ToolDefHooks.skeleton
index 7761707cd4f7cd712ff5a34714384e656997cdb3..878b3f94c0a8f97310fd597219459aab13a870c0 100644
--- a/tooldef/org.eclipse.escet.tooldef.parser/src-gen/org/eclipse/escet/tooldef/parser/ToolDefHooks.skeleton
+++ b/tooldef/org.eclipse.escet.tooldef.parser/src-gen/org/eclipse/escet/tooldef/parser/ToolDefHooks.skeleton
@@ -37,11 +37,13 @@ import org.eclipse.escet.tooldef.metamodel.tooldef.types.ToolDefType;
  * <ul>
  *  <li>{@link ToolDefScanner}</li>
  *  <li>{@link ToolDefParser}</li>
+ *  <li>{@link ToolDefInvokeParser}</li>
  * </ul>
  */
 public final class ToolDefHooks
 implements ToolDefScanner.Hooks,
-           ToolDefParser.Hooks
+           ToolDefParser.Hooks,
+           ToolDefInvokeParser.Hooks
 {
     @Override
     public void setParser(Parser<?> parser) {
diff --git a/tooldef/org.eclipse.escet.tooldef.parser/src-gen/org/eclipse/escet/tooldef/parser/ToolDefInvokeParser.java b/tooldef/org.eclipse.escet.tooldef.parser/src-gen/org/eclipse/escet/tooldef/parser/ToolDefInvokeParser.java
new file mode 100644
index 0000000000000000000000000000000000000000..22fa5adab3bf20abec06ecd181e36845942e4abf
--- /dev/null
+++ b/tooldef/org.eclipse.escet.tooldef.parser/src-gen/org/eclipse/escet/tooldef/parser/ToolDefInvokeParser.java
@@ -0,0 +1,35590 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2010, 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+// Disable Eclipse Java formatter for generated code file:
+// @formatter:off
+
+package org.eclipse.escet.tooldef.parser;
+
+import static org.eclipse.escet.common.java.Strings.fmt;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.eclipse.escet.setext.runtime.Parser;
+import org.eclipse.escet.setext.runtime.ParserHooksBase;
+import org.eclipse.escet.setext.runtime.Token;
+import org.eclipse.escet.tooldef.metamodel.tooldef.expressions.Expression;
+import org.eclipse.escet.tooldef.metamodel.tooldef.expressions.MapEntry;
+import org.eclipse.escet.tooldef.metamodel.tooldef.expressions.ToolArgument;
+import org.eclipse.escet.tooldef.metamodel.tooldef.expressions.ToolInvokeExpression;
+import org.eclipse.escet.tooldef.metamodel.tooldef.expressions.ToolRef;
+import org.eclipse.escet.tooldef.metamodel.tooldef.types.ToolDefType;
+
+/**
+ * ToolDefInvokeParser.
+ *
+ * <p>This parser is generated by SeText for start symbol
+ * "ToolInvokeExpression".</p>
+ */
+@SuppressWarnings("unchecked")
+public final class ToolDefInvokeParser extends Parser<ToolInvokeExpression> {
+    /** The names of the non-terminals, ordered by their unique ids. */
+    private static final String[] NON_TERMINAL_NAMES = {
+        "BuiltInIoTool",
+        "BuiltInGenericTool",
+        "BuiltInPathTool",
+        "BuiltInFileTool",
+        "BuiltInDataTool",
+        "Types",
+        "Type",
+        "Expressions",
+        "OptExpression",
+        "Expression",
+        "AndExpression",
+        "CompareExpression",
+        "AddExpression",
+        "MulExpression",
+        "UnaryExpression",
+        "ProjExpression",
+        "ExpressionFactor",
+        "MapEntries",
+        "ToolInvokeExpression",
+        "ToolRef",
+        "BuiltInTool",
+        "ToolArgs",
+        "Name",
+        "OptComma",
+    };
+
+    /**
+     * The entry symbol names for each of the parser states, and {@code null}
+     * for the initial state.
+     */
+    private static final String[] ENTRY_SYMBOL_NAMES = new String[] {
+        null,
+        "ERRKW",
+        "ERRLNKW",
+        "OUTKW",
+        "OUTLNKW",
+        "APPKW",
+        "EXECKW",
+        "TOOLDEFKW",
+        "ABSPATHKW",
+        "BASENAMEKW",
+        "CHDIRKW",
+        "CHFILEEXTKW",
+        "CURDIRKW",
+        "DIRNAMEKW",
+        "FILEEXTKW",
+        "HASFILEEXTKW",
+        "PATHJOINKW",
+        "SCRIPTPATHKW",
+        "CPDIRKW",
+        "CPFILEKW",
+        "DIFFKW",
+        "EXISTSKW",
+        "FILENEWERKW",
+        "FILESIZEKW",
+        "FINDKW",
+        "ISDIRKW",
+        "ISFILEKW",
+        "MKDIRKW",
+        "MVDIRKW",
+        "MVFILEKW",
+        "READLINESKW",
+        "RMDIRKW",
+        "RMFILEKW",
+        "WRITEFILEKW",
+        "ABSKW",
+        "CEILKW",
+        "CONTAINSKW",
+        "DELKW",
+        "DELIDXKW",
+        "EMPTYKW",
+        "ENDSWITHKW",
+        "ENTRIESKW",
+        "ENUMERATEKW",
+        "FLOORKW",
+        "FMTKW",
+        "INDEXOFKW",
+        "JOINKW",
+        "KEYSKW",
+        "LASTINDEXOFKW",
+        "LNKW",
+        "LOGKW",
+        "LOWERKW",
+        "LTRIMKW",
+        "MAXKW",
+        "MINKW",
+        "POWKW",
+        "RANGEKW",
+        "REPLACEKW",
+        "REVERSEKW",
+        "ROUNDKW",
+        "RTRIMKW",
+        "SIZEKW",
+        "SORTEDKW",
+        "SPLITKW",
+        "SQRTKW",
+        "STARTSWITHKW",
+        "STRKW",
+        "STRDUPKW",
+        "SUBSETKW",
+        "TRIMKW",
+        "UPPERKW",
+        "VALUESKW",
+        "IDENTIFIERTK",
+        "RELATIVENAMETK",
+        "BuiltInDataTool",
+        "BuiltInFileTool",
+        "BuiltInGenericTool",
+        "BuiltInIoTool",
+        "BuiltInPathTool",
+        "BuiltInTool",
+        "Name",
+        "ToolInvokeExpression",
+        "ToolRef",
+        "PAROPENTK",
+        "FALSEKW",
+        "NULLKW",
+        "TRUEKW",
+        "NOTKW",
+        "CUROPENTK",
+        "LTTK",
+        "MINUSTK",
+        "PARCLOSETK",
+        "PAROPENTK",
+        "PLUSTK",
+        "SQOPENTK",
+        "IDENTIFIERTK",
+        "NUMBERTK",
+        "DOUBLETK",
+        "STRINGTK",
+        "AddExpression",
+        "AndExpression",
+        "CompareExpression",
+        "Expression",
+        "ExpressionFactor",
+        "MulExpression",
+        "Name",
+        "ProjExpression",
+        "ToolArgs",
+        "ToolInvokeExpression",
+        "UnaryExpression",
+        "COMMATK",
+        "OptComma",
+        "PARCLOSETK",
+        "IDENTIFIERTK",
+        "Expression",
+        "ORKW",
+        "AndExpression",
+        "ANDKW",
+        "CompareExpression",
+        "EQEQTK",
+        "GETK",
+        "GTTK",
+        "LETK",
+        "LTTK",
+        "NETK",
+        "AddExpression",
+        "MINUSTK",
+        "PLUSTK",
+        "MulExpression",
+        "DIVKW",
+        "MODKW",
+        "ASTERISKTK",
+        "SLASHTK",
+        "UnaryExpression",
+        "UnaryExpression",
+        "UnaryExpression",
+        "UnaryExpression",
+        "MulExpression",
+        "AddExpression",
+        "AddExpression",
+        "AddExpression",
+        "AddExpression",
+        "AddExpression",
+        "EQTK",
+        "Expression",
+        "SQOPENTK",
+        "Expression",
+        "OptExpression",
+        "COLONTK",
+        "Expression",
+        "OptExpression",
+        "SQCLOSETK",
+        "SQCLOSETK",
+        "EQTK",
+        "Expression",
+        "SQCLOSETK",
+        "Expression",
+        "Expressions",
+        "COMMATK",
+        "OptComma",
+        "SQCLOSETK",
+        "Expression",
+        "UnaryExpression",
+        "Expression",
+        "COMMATK",
+        "PARCLOSETK",
+        "Expressions",
+        "OptComma",
+        "PARCLOSETK",
+        "UnaryExpression",
+        "BOOLKW",
+        "DOUBLEKW",
+        "INTKW",
+        "LISTKW",
+        "LONGKW",
+        "MAPKW",
+        "OBJECTKW",
+        "SETKW",
+        "STRINGKW",
+        "TUPLEKW",
+        "Name",
+        "Type",
+        "GTTK",
+        "ExpressionFactor",
+        "PAROPENTK",
+        "QUESTIONTK",
+        "PAROPENTK",
+        "Type",
+        "COMMATK",
+        "Type",
+        "Types",
+        "COMMATK",
+        "PARCLOSETK",
+        "Type",
+        "Type",
+        "COMMATK",
+        "Types",
+        "PARCLOSETK",
+        "QUESTIONTK",
+        "QUESTIONTK",
+        "Type",
+        "Type",
+        "QUESTIONTK",
+        "PAROPENTK",
+        "QUESTIONTK",
+        "PAROPENTK",
+        "Type",
+        "COLONTK",
+        "Type",
+        "PARCLOSETK",
+        "Type",
+        "COLONTK",
+        "Type",
+        "PARCLOSETK",
+        "QUESTIONTK",
+        "QUESTIONTK",
+        "Type",
+        "Type",
+        "QUESTIONTK",
+        "QUESTIONTK",
+        "QUESTIONTK",
+        "CURCLOSETK",
+        "Expression",
+        "Expressions",
+        "MapEntries",
+        "COMMATK",
+        "OptComma",
+        "CURCLOSETK",
+        "Expression",
+        "COLONTK",
+        "Expression",
+        "OptComma",
+        "CURCLOSETK",
+        "COLONTK",
+        "Expression",
+        "UnaryExpression",
+    };
+
+    /** Parser call back hook methods. */
+    private final ToolDefHooks hooks;
+
+    /** Whether parsing has completed (final result has been accepted). */
+    private boolean accept;
+
+    /** The parse result, but only if {@code #accept} is {@code true}. */
+    private ToolInvokeExpression acceptObject;
+
+    /** The current scanner token to process, if any. */
+    private Token token;
+
+    /** Whether parsing has resulted in a reduce action. */
+    private boolean reduce;
+
+    /** The state from which to reduce, if {@code #reduce} is {@code true}. */
+    private int reduceState;
+
+    /** The non-terminal to reduce, if {@code #reduce} is {@code true}. */
+    private int reduceNonTerminal;
+
+    /** Constructor for the {@link ToolDefInvokeParser} class. */
+    public ToolDefInvokeParser() {
+        super(new ToolDefScanner());
+        entrySymbolNames = ENTRY_SYMBOL_NAMES;
+        firstTerminals = FirstTerminals.FIRST_TERMINALS;
+        firstTerminalsReduced = FirstTerminalsReduced.FIRST_TERMINALS_REDUCED;
+        reducibleNonTerminals = ReducibleNonTerminals.REDUCIBLE_NON_TERMINALS;
+        reducibleNonTerminalsReduced = ReducibleNonTerminalsReduced.REDUCIBLE_NON_TERMINALS_REDUCED;
+        hooks = ((ToolDefScanner)scanner).hooks;
+    }
+
+    @Override
+    public ParserHooksBase getHooks() {
+        return hooks;
+    }
+
+    @Override
+    protected final ToolInvokeExpression parse() throws IOException {
+        token = nextToken();
+        int state;
+
+        accept = false;
+
+        while (true) {
+            // Perform action.
+            state = getCurrentState();
+            reduce = false;
+
+            switch (state) {
+                case 0:
+                    action0();
+                    break;
+                case 1:
+                    action1();
+                    break;
+                case 2:
+                    action2();
+                    break;
+                case 3:
+                    action3();
+                    break;
+                case 4:
+                    action4();
+                    break;
+                case 5:
+                    action5();
+                    break;
+                case 6:
+                    action6();
+                    break;
+                case 7:
+                    action7();
+                    break;
+                case 8:
+                    action8();
+                    break;
+                case 9:
+                    action9();
+                    break;
+                case 10:
+                    action10();
+                    break;
+                case 11:
+                    action11();
+                    break;
+                case 12:
+                    action12();
+                    break;
+                case 13:
+                    action13();
+                    break;
+                case 14:
+                    action14();
+                    break;
+                case 15:
+                    action15();
+                    break;
+                case 16:
+                    action16();
+                    break;
+                case 17:
+                    action17();
+                    break;
+                case 18:
+                    action18();
+                    break;
+                case 19:
+                    action19();
+                    break;
+                case 20:
+                    action20();
+                    break;
+                case 21:
+                    action21();
+                    break;
+                case 22:
+                    action22();
+                    break;
+                case 23:
+                    action23();
+                    break;
+                case 24:
+                    action24();
+                    break;
+                case 25:
+                    action25();
+                    break;
+                case 26:
+                    action26();
+                    break;
+                case 27:
+                    action27();
+                    break;
+                case 28:
+                    action28();
+                    break;
+                case 29:
+                    action29();
+                    break;
+                case 30:
+                    action30();
+                    break;
+                case 31:
+                    action31();
+                    break;
+                case 32:
+                    action32();
+                    break;
+                case 33:
+                    action33();
+                    break;
+                case 34:
+                    action34();
+                    break;
+                case 35:
+                    action35();
+                    break;
+                case 36:
+                    action36();
+                    break;
+                case 37:
+                    action37();
+                    break;
+                case 38:
+                    action38();
+                    break;
+                case 39:
+                    action39();
+                    break;
+                case 40:
+                    action40();
+                    break;
+                case 41:
+                    action41();
+                    break;
+                case 42:
+                    action42();
+                    break;
+                case 43:
+                    action43();
+                    break;
+                case 44:
+                    action44();
+                    break;
+                case 45:
+                    action45();
+                    break;
+                case 46:
+                    action46();
+                    break;
+                case 47:
+                    action47();
+                    break;
+                case 48:
+                    action48();
+                    break;
+                case 49:
+                    action49();
+                    break;
+                case 50:
+                    action50();
+                    break;
+                case 51:
+                    action51();
+                    break;
+                case 52:
+                    action52();
+                    break;
+                case 53:
+                    action53();
+                    break;
+                case 54:
+                    action54();
+                    break;
+                case 55:
+                    action55();
+                    break;
+                case 56:
+                    action56();
+                    break;
+                case 57:
+                    action57();
+                    break;
+                case 58:
+                    action58();
+                    break;
+                case 59:
+                    action59();
+                    break;
+                case 60:
+                    action60();
+                    break;
+                case 61:
+                    action61();
+                    break;
+                case 62:
+                    action62();
+                    break;
+                case 63:
+                    action63();
+                    break;
+                case 64:
+                    action64();
+                    break;
+                case 65:
+                    action65();
+                    break;
+                case 66:
+                    action66();
+                    break;
+                case 67:
+                    action67();
+                    break;
+                case 68:
+                    action68();
+                    break;
+                case 69:
+                    action69();
+                    break;
+                case 70:
+                    action70();
+                    break;
+                case 71:
+                    action71();
+                    break;
+                case 72:
+                    action72();
+                    break;
+                case 73:
+                    action73();
+                    break;
+                case 74:
+                    action74();
+                    break;
+                case 75:
+                    action75();
+                    break;
+                case 76:
+                    action76();
+                    break;
+                case 77:
+                    action77();
+                    break;
+                case 78:
+                    action78();
+                    break;
+                case 79:
+                    action79();
+                    break;
+                case 80:
+                    action80();
+                    break;
+                case 81:
+                    action81();
+                    break;
+                case 82:
+                    action82();
+                    break;
+                case 83:
+                    action83();
+                    break;
+                case 84:
+                    action84();
+                    break;
+                case 85:
+                    action85();
+                    break;
+                case 86:
+                    action86();
+                    break;
+                case 87:
+                    action87();
+                    break;
+                case 88:
+                    action88();
+                    break;
+                case 89:
+                    action89();
+                    break;
+                case 90:
+                    action90();
+                    break;
+                case 91:
+                    action91();
+                    break;
+                case 92:
+                    action92();
+                    break;
+                case 93:
+                    action93();
+                    break;
+                case 94:
+                    action94();
+                    break;
+                case 95:
+                    action95();
+                    break;
+                case 96:
+                    action96();
+                    break;
+                case 97:
+                    action97();
+                    break;
+                case 98:
+                    action98();
+                    break;
+                case 99:
+                    action99();
+                    break;
+                case 100:
+                    action100();
+                    break;
+                case 101:
+                    action101();
+                    break;
+                case 102:
+                    action102();
+                    break;
+                case 103:
+                    action103();
+                    break;
+                case 104:
+                    action104();
+                    break;
+                case 105:
+                    action105();
+                    break;
+                case 106:
+                    action106();
+                    break;
+                case 107:
+                    action107();
+                    break;
+                case 108:
+                    action108();
+                    break;
+                case 109:
+                    action109();
+                    break;
+                case 110:
+                    action110();
+                    break;
+                case 111:
+                    action111();
+                    break;
+                case 112:
+                    action112();
+                    break;
+                case 113:
+                    action113();
+                    break;
+                case 114:
+                    action114();
+                    break;
+                case 115:
+                    action115();
+                    break;
+                case 116:
+                    action116();
+                    break;
+                case 117:
+                    action117();
+                    break;
+                case 118:
+                    action118();
+                    break;
+                case 119:
+                    action119();
+                    break;
+                case 120:
+                    action120();
+                    break;
+                case 121:
+                    action121();
+                    break;
+                case 122:
+                    action122();
+                    break;
+                case 123:
+                    action123();
+                    break;
+                case 124:
+                    action124();
+                    break;
+                case 125:
+                    action125();
+                    break;
+                case 126:
+                    action126();
+                    break;
+                case 127:
+                    action127();
+                    break;
+                case 128:
+                    action128();
+                    break;
+                case 129:
+                    action129();
+                    break;
+                case 130:
+                    action130();
+                    break;
+                case 131:
+                    action131();
+                    break;
+                case 132:
+                    action132();
+                    break;
+                case 133:
+                    action133();
+                    break;
+                case 134:
+                    action134();
+                    break;
+                case 135:
+                    action135();
+                    break;
+                case 136:
+                    action136();
+                    break;
+                case 137:
+                    action137();
+                    break;
+                case 138:
+                    action138();
+                    break;
+                case 139:
+                    action139();
+                    break;
+                case 140:
+                    action140();
+                    break;
+                case 141:
+                    action141();
+                    break;
+                case 142:
+                    action142();
+                    break;
+                case 143:
+                    action143();
+                    break;
+                case 144:
+                    action144();
+                    break;
+                case 145:
+                    action145();
+                    break;
+                case 146:
+                    action146();
+                    break;
+                case 147:
+                    action147();
+                    break;
+                case 148:
+                    action148();
+                    break;
+                case 149:
+                    action149();
+                    break;
+                case 150:
+                    action150();
+                    break;
+                case 151:
+                    action151();
+                    break;
+                case 152:
+                    action152();
+                    break;
+                case 153:
+                    action153();
+                    break;
+                case 154:
+                    action154();
+                    break;
+                case 155:
+                    action155();
+                    break;
+                case 156:
+                    action156();
+                    break;
+                case 157:
+                    action157();
+                    break;
+                case 158:
+                    action158();
+                    break;
+                case 159:
+                    action159();
+                    break;
+                case 160:
+                    action160();
+                    break;
+                case 161:
+                    action161();
+                    break;
+                case 162:
+                    action162();
+                    break;
+                case 163:
+                    action163();
+                    break;
+                case 164:
+                    action164();
+                    break;
+                case 165:
+                    action165();
+                    break;
+                case 166:
+                    action166();
+                    break;
+                case 167:
+                    action167();
+                    break;
+                case 168:
+                    action168();
+                    break;
+                case 169:
+                    action169();
+                    break;
+                case 170:
+                    action170();
+                    break;
+                case 171:
+                    action171();
+                    break;
+                case 172:
+                    action172();
+                    break;
+                case 173:
+                    action173();
+                    break;
+                case 174:
+                    action174();
+                    break;
+                case 175:
+                    action175();
+                    break;
+                case 176:
+                    action176();
+                    break;
+                case 177:
+                    action177();
+                    break;
+                case 178:
+                    action178();
+                    break;
+                case 179:
+                    action179();
+                    break;
+                case 180:
+                    action180();
+                    break;
+                case 181:
+                    action181();
+                    break;
+                case 182:
+                    action182();
+                    break;
+                case 183:
+                    action183();
+                    break;
+                case 184:
+                    action184();
+                    break;
+                case 185:
+                    action185();
+                    break;
+                case 186:
+                    action186();
+                    break;
+                case 187:
+                    action187();
+                    break;
+                case 188:
+                    action188();
+                    break;
+                case 189:
+                    action189();
+                    break;
+                case 190:
+                    action190();
+                    break;
+                case 191:
+                    action191();
+                    break;
+                case 192:
+                    action192();
+                    break;
+                case 193:
+                    action193();
+                    break;
+                case 194:
+                    action194();
+                    break;
+                case 195:
+                    action195();
+                    break;
+                case 196:
+                    action196();
+                    break;
+                case 197:
+                    action197();
+                    break;
+                case 198:
+                    action198();
+                    break;
+                case 199:
+                    action199();
+                    break;
+                case 200:
+                    action200();
+                    break;
+                case 201:
+                    action201();
+                    break;
+                case 202:
+                    action202();
+                    break;
+                case 203:
+                    action203();
+                    break;
+                case 204:
+                    action204();
+                    break;
+                case 205:
+                    action205();
+                    break;
+                case 206:
+                    action206();
+                    break;
+                case 207:
+                    action207();
+                    break;
+                case 208:
+                    action208();
+                    break;
+                case 209:
+                    action209();
+                    break;
+                case 210:
+                    action210();
+                    break;
+                case 211:
+                    action211();
+                    break;
+                case 212:
+                    action212();
+                    break;
+                case 213:
+                    action213();
+                    break;
+                case 214:
+                    action214();
+                    break;
+                case 215:
+                    action215();
+                    break;
+                case 216:
+                    action216();
+                    break;
+                case 217:
+                    action217();
+                    break;
+                case 218:
+                    action218();
+                    break;
+                case 219:
+                    action219();
+                    break;
+                case 220:
+                    action220();
+                    break;
+                case 221:
+                    action221();
+                    break;
+                case 222:
+                    action222();
+                    break;
+                case 223:
+                    action223();
+                    break;
+                case 224:
+                    action224();
+                    break;
+                case 225:
+                    action225();
+                    break;
+                case 226:
+                    action226();
+                    break;
+                case 227:
+                    action227();
+                    break;
+                case 228:
+                    action228();
+                    break;
+                case 229:
+                    action229();
+                    break;
+                case 230:
+                    action230();
+                    break;
+                case 231:
+                    action231();
+                    break;
+                case 232:
+                    action232();
+                    break;
+                case 233:
+                    action233();
+                    break;
+                case 234:
+                    action234();
+                    break;
+                case 235:
+                    action235();
+                    break;
+                default:
+                    String msg = "Unknown parser state: " + state;
+                    throw new RuntimeException(msg);
+            }
+
+            // Accept action.
+            if (accept) {
+                return acceptObject;
+            }
+
+            // Shift action.
+            if (!reduce) {
+                continue;
+            }
+
+            // Perform goto (as part of a reduce action).
+            switch (reduceState) {
+                case 0:
+                    goto0();
+                    break;
+                case 1:
+                    goto1();
+                    break;
+                case 2:
+                    goto2();
+                    break;
+                case 3:
+                    goto3();
+                    break;
+                case 4:
+                    goto4();
+                    break;
+                case 5:
+                    goto5();
+                    break;
+                case 6:
+                    goto6();
+                    break;
+                case 7:
+                    goto7();
+                    break;
+                case 8:
+                    goto8();
+                    break;
+                case 9:
+                    goto9();
+                    break;
+                case 10:
+                    goto10();
+                    break;
+                case 11:
+                    goto11();
+                    break;
+                case 12:
+                    goto12();
+                    break;
+                case 13:
+                    goto13();
+                    break;
+                case 14:
+                    goto14();
+                    break;
+                case 15:
+                    goto15();
+                    break;
+                case 16:
+                    goto16();
+                    break;
+                case 17:
+                    goto17();
+                    break;
+                case 18:
+                    goto18();
+                    break;
+                case 19:
+                    goto19();
+                    break;
+                case 20:
+                    goto20();
+                    break;
+                case 21:
+                    goto21();
+                    break;
+                case 22:
+                    goto22();
+                    break;
+                case 23:
+                    goto23();
+                    break;
+                case 24:
+                    goto24();
+                    break;
+                case 25:
+                    goto25();
+                    break;
+                case 26:
+                    goto26();
+                    break;
+                case 27:
+                    goto27();
+                    break;
+                case 28:
+                    goto28();
+                    break;
+                case 29:
+                    goto29();
+                    break;
+                case 30:
+                    goto30();
+                    break;
+                case 31:
+                    goto31();
+                    break;
+                case 32:
+                    goto32();
+                    break;
+                case 33:
+                    goto33();
+                    break;
+                case 34:
+                    goto34();
+                    break;
+                case 35:
+                    goto35();
+                    break;
+                case 36:
+                    goto36();
+                    break;
+                case 37:
+                    goto37();
+                    break;
+                case 38:
+                    goto38();
+                    break;
+                case 39:
+                    goto39();
+                    break;
+                case 40:
+                    goto40();
+                    break;
+                case 41:
+                    goto41();
+                    break;
+                case 42:
+                    goto42();
+                    break;
+                case 43:
+                    goto43();
+                    break;
+                case 44:
+                    goto44();
+                    break;
+                case 45:
+                    goto45();
+                    break;
+                case 46:
+                    goto46();
+                    break;
+                case 47:
+                    goto47();
+                    break;
+                case 48:
+                    goto48();
+                    break;
+                case 49:
+                    goto49();
+                    break;
+                case 50:
+                    goto50();
+                    break;
+                case 51:
+                    goto51();
+                    break;
+                case 52:
+                    goto52();
+                    break;
+                case 53:
+                    goto53();
+                    break;
+                case 54:
+                    goto54();
+                    break;
+                case 55:
+                    goto55();
+                    break;
+                case 56:
+                    goto56();
+                    break;
+                case 57:
+                    goto57();
+                    break;
+                case 58:
+                    goto58();
+                    break;
+                case 59:
+                    goto59();
+                    break;
+                case 60:
+                    goto60();
+                    break;
+                case 61:
+                    goto61();
+                    break;
+                case 62:
+                    goto62();
+                    break;
+                case 63:
+                    goto63();
+                    break;
+                case 64:
+                    goto64();
+                    break;
+                case 65:
+                    goto65();
+                    break;
+                case 66:
+                    goto66();
+                    break;
+                case 67:
+                    goto67();
+                    break;
+                case 68:
+                    goto68();
+                    break;
+                case 69:
+                    goto69();
+                    break;
+                case 70:
+                    goto70();
+                    break;
+                case 71:
+                    goto71();
+                    break;
+                case 72:
+                    goto72();
+                    break;
+                case 73:
+                    goto73();
+                    break;
+                case 74:
+                    goto74();
+                    break;
+                case 75:
+                    goto75();
+                    break;
+                case 76:
+                    goto76();
+                    break;
+                case 77:
+                    goto77();
+                    break;
+                case 78:
+                    goto78();
+                    break;
+                case 79:
+                    goto79();
+                    break;
+                case 80:
+                    goto80();
+                    break;
+                case 81:
+                    goto81();
+                    break;
+                case 82:
+                    goto82();
+                    break;
+                case 83:
+                    goto83();
+                    break;
+                case 84:
+                    goto84();
+                    break;
+                case 85:
+                    goto85();
+                    break;
+                case 86:
+                    goto86();
+                    break;
+                case 87:
+                    goto87();
+                    break;
+                case 88:
+                    goto88();
+                    break;
+                case 89:
+                    goto89();
+                    break;
+                case 90:
+                    goto90();
+                    break;
+                case 91:
+                    goto91();
+                    break;
+                case 92:
+                    goto92();
+                    break;
+                case 93:
+                    goto93();
+                    break;
+                case 94:
+                    goto94();
+                    break;
+                case 95:
+                    goto95();
+                    break;
+                case 96:
+                    goto96();
+                    break;
+                case 97:
+                    goto97();
+                    break;
+                case 98:
+                    goto98();
+                    break;
+                case 99:
+                    goto99();
+                    break;
+                case 100:
+                    goto100();
+                    break;
+                case 101:
+                    goto101();
+                    break;
+                case 102:
+                    goto102();
+                    break;
+                case 103:
+                    goto103();
+                    break;
+                case 104:
+                    goto104();
+                    break;
+                case 105:
+                    goto105();
+                    break;
+                case 106:
+                    goto106();
+                    break;
+                case 107:
+                    goto107();
+                    break;
+                case 108:
+                    goto108();
+                    break;
+                case 109:
+                    goto109();
+                    break;
+                case 110:
+                    goto110();
+                    break;
+                case 111:
+                    goto111();
+                    break;
+                case 112:
+                    goto112();
+                    break;
+                case 113:
+                    goto113();
+                    break;
+                case 114:
+                    goto114();
+                    break;
+                case 115:
+                    goto115();
+                    break;
+                case 116:
+                    goto116();
+                    break;
+                case 117:
+                    goto117();
+                    break;
+                case 118:
+                    goto118();
+                    break;
+                case 119:
+                    goto119();
+                    break;
+                case 120:
+                    goto120();
+                    break;
+                case 121:
+                    goto121();
+                    break;
+                case 122:
+                    goto122();
+                    break;
+                case 123:
+                    goto123();
+                    break;
+                case 124:
+                    goto124();
+                    break;
+                case 125:
+                    goto125();
+                    break;
+                case 126:
+                    goto126();
+                    break;
+                case 127:
+                    goto127();
+                    break;
+                case 128:
+                    goto128();
+                    break;
+                case 129:
+                    goto129();
+                    break;
+                case 130:
+                    goto130();
+                    break;
+                case 131:
+                    goto131();
+                    break;
+                case 132:
+                    goto132();
+                    break;
+                case 133:
+                    goto133();
+                    break;
+                case 134:
+                    goto134();
+                    break;
+                case 135:
+                    goto135();
+                    break;
+                case 136:
+                    goto136();
+                    break;
+                case 137:
+                    goto137();
+                    break;
+                case 138:
+                    goto138();
+                    break;
+                case 139:
+                    goto139();
+                    break;
+                case 140:
+                    goto140();
+                    break;
+                case 141:
+                    goto141();
+                    break;
+                case 142:
+                    goto142();
+                    break;
+                case 143:
+                    goto143();
+                    break;
+                case 144:
+                    goto144();
+                    break;
+                case 145:
+                    goto145();
+                    break;
+                case 146:
+                    goto146();
+                    break;
+                case 147:
+                    goto147();
+                    break;
+                case 148:
+                    goto148();
+                    break;
+                case 149:
+                    goto149();
+                    break;
+                case 150:
+                    goto150();
+                    break;
+                case 151:
+                    goto151();
+                    break;
+                case 152:
+                    goto152();
+                    break;
+                case 153:
+                    goto153();
+                    break;
+                case 154:
+                    goto154();
+                    break;
+                case 155:
+                    goto155();
+                    break;
+                case 156:
+                    goto156();
+                    break;
+                case 157:
+                    goto157();
+                    break;
+                case 158:
+                    goto158();
+                    break;
+                case 159:
+                    goto159();
+                    break;
+                case 160:
+                    goto160();
+                    break;
+                case 161:
+                    goto161();
+                    break;
+                case 162:
+                    goto162();
+                    break;
+                case 163:
+                    goto163();
+                    break;
+                case 164:
+                    goto164();
+                    break;
+                case 165:
+                    goto165();
+                    break;
+                case 166:
+                    goto166();
+                    break;
+                case 167:
+                    goto167();
+                    break;
+                case 168:
+                    goto168();
+                    break;
+                case 169:
+                    goto169();
+                    break;
+                case 170:
+                    goto170();
+                    break;
+                case 171:
+                    goto171();
+                    break;
+                case 172:
+                    goto172();
+                    break;
+                case 173:
+                    goto173();
+                    break;
+                case 174:
+                    goto174();
+                    break;
+                case 175:
+                    goto175();
+                    break;
+                case 176:
+                    goto176();
+                    break;
+                case 177:
+                    goto177();
+                    break;
+                case 178:
+                    goto178();
+                    break;
+                case 179:
+                    goto179();
+                    break;
+                case 180:
+                    goto180();
+                    break;
+                case 181:
+                    goto181();
+                    break;
+                case 182:
+                    goto182();
+                    break;
+                case 183:
+                    goto183();
+                    break;
+                case 184:
+                    goto184();
+                    break;
+                case 185:
+                    goto185();
+                    break;
+                case 186:
+                    goto186();
+                    break;
+                case 187:
+                    goto187();
+                    break;
+                case 188:
+                    goto188();
+                    break;
+                case 189:
+                    goto189();
+                    break;
+                case 190:
+                    goto190();
+                    break;
+                case 191:
+                    goto191();
+                    break;
+                case 192:
+                    goto192();
+                    break;
+                case 193:
+                    goto193();
+                    break;
+                case 194:
+                    goto194();
+                    break;
+                case 195:
+                    goto195();
+                    break;
+                case 196:
+                    goto196();
+                    break;
+                case 197:
+                    goto197();
+                    break;
+                case 198:
+                    goto198();
+                    break;
+                case 199:
+                    goto199();
+                    break;
+                case 200:
+                    goto200();
+                    break;
+                case 201:
+                    goto201();
+                    break;
+                case 202:
+                    goto202();
+                    break;
+                case 203:
+                    goto203();
+                    break;
+                case 204:
+                    goto204();
+                    break;
+                case 205:
+                    goto205();
+                    break;
+                case 206:
+                    goto206();
+                    break;
+                case 207:
+                    goto207();
+                    break;
+                case 208:
+                    goto208();
+                    break;
+                case 209:
+                    goto209();
+                    break;
+                case 210:
+                    goto210();
+                    break;
+                case 211:
+                    goto211();
+                    break;
+                case 212:
+                    goto212();
+                    break;
+                case 213:
+                    goto213();
+                    break;
+                case 214:
+                    goto214();
+                    break;
+                case 215:
+                    goto215();
+                    break;
+                case 216:
+                    goto216();
+                    break;
+                case 217:
+                    goto217();
+                    break;
+                case 218:
+                    goto218();
+                    break;
+                case 219:
+                    goto219();
+                    break;
+                case 220:
+                    goto220();
+                    break;
+                case 221:
+                    goto221();
+                    break;
+                case 222:
+                    goto222();
+                    break;
+                case 223:
+                    goto223();
+                    break;
+                case 224:
+                    goto224();
+                    break;
+                case 225:
+                    goto225();
+                    break;
+                case 226:
+                    goto226();
+                    break;
+                case 227:
+                    goto227();
+                    break;
+                case 228:
+                    goto228();
+                    break;
+                case 229:
+                    goto229();
+                    break;
+                case 230:
+                    goto230();
+                    break;
+                case 231:
+                    goto231();
+                    break;
+                case 232:
+                    goto232();
+                    break;
+                case 233:
+                    goto233();
+                    break;
+                case 234:
+                    goto234();
+                    break;
+                case 235:
+                    goto235();
+                    break;
+                default:
+                    String msg = fmt("Unknown reduce state %d.", reduceState);
+                    throw new RuntimeException(msg);
+            }
+        }
+    }
+
+    /**
+     * Parser action code for parser state 0.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action0() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 1.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action1() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInIoTool : ERRKW;
+                doReduce1(token, 0);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInIoTool1((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 0;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 2.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action2() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInIoTool : ERRLNKW;
+                doReduce1(token, 0);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInIoTool2((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 0;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 3.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action3() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInIoTool : OUTKW;
+                doReduce1(token, 0);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInIoTool3((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 0;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 4.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action4() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInIoTool : OUTLNKW;
+                doReduce1(token, 0);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInIoTool4((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 0;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 5.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action5() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInGenericTool : APPKW;
+                doReduce1(token, 1);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInGenericTool1((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 1;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 6.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action6() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInGenericTool : EXECKW;
+                doReduce1(token, 1);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInGenericTool2((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 1;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 7.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action7() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInGenericTool : TOOLDEFKW;
+                doReduce1(token, 1);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInGenericTool3((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 1;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 8.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action8() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInPathTool : ABSPATHKW;
+                doReduce1(token, 2);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInPathTool01((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 2;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 9.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action9() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInPathTool : BASENAMEKW;
+                doReduce1(token, 2);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInPathTool02((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 2;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 10.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action10() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInPathTool : CHDIRKW;
+                doReduce1(token, 2);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInPathTool03((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 2;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 11.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action11() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInPathTool : CHFILEEXTKW;
+                doReduce1(token, 2);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInPathTool04((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 2;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 12.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action12() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInPathTool : CURDIRKW;
+                doReduce1(token, 2);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInPathTool05((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 2;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 13.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action13() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInPathTool : DIRNAMEKW;
+                doReduce1(token, 2);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInPathTool06((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 2;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 14.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action14() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInPathTool : FILEEXTKW;
+                doReduce1(token, 2);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInPathTool07((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 2;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 15.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action15() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInPathTool : HASFILEEXTKW;
+                doReduce1(token, 2);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInPathTool08((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 2;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 16.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action16() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInPathTool : PATHJOINKW;
+                doReduce1(token, 2);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInPathTool09((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 2;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 17.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action17() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInPathTool : SCRIPTPATHKW;
+                doReduce1(token, 2);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInPathTool10((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 2;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 18.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action18() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInFileTool : CPDIRKW;
+                doReduce1(token, 3);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInFileTool01((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 3;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 19.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action19() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInFileTool : CPFILEKW;
+                doReduce1(token, 3);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInFileTool02((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 3;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 20.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action20() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInFileTool : DIFFKW;
+                doReduce1(token, 3);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInFileTool03((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 3;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 21.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action21() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInFileTool : EXISTSKW;
+                doReduce1(token, 3);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInFileTool04((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 3;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 22.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action22() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInFileTool : FILENEWERKW;
+                doReduce1(token, 3);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInFileTool05((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 3;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 23.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action23() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInFileTool : FILESIZEKW;
+                doReduce1(token, 3);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInFileTool06((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 3;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 24.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action24() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInFileTool : FINDKW;
+                doReduce1(token, 3);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInFileTool07((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 3;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 25.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action25() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInFileTool : ISDIRKW;
+                doReduce1(token, 3);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInFileTool08((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 3;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 26.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action26() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInFileTool : ISFILEKW;
+                doReduce1(token, 3);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInFileTool09((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 3;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 27.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action27() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInFileTool : MKDIRKW;
+                doReduce1(token, 3);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInFileTool10((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 3;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 28.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action28() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInFileTool : MVDIRKW;
+                doReduce1(token, 3);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInFileTool11((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 3;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 29.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action29() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInFileTool : MVFILEKW;
+                doReduce1(token, 3);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInFileTool12((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 3;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 30.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action30() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInFileTool : READLINESKW;
+                doReduce1(token, 3);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInFileTool13((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 3;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 31.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action31() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInFileTool : RMDIRKW;
+                doReduce1(token, 3);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInFileTool14((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 3;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 32.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action32() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInFileTool : RMFILEKW;
+                doReduce1(token, 3);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInFileTool15((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 3;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 33.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action33() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInFileTool : WRITEFILEKW;
+                doReduce1(token, 3);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInFileTool16((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 3;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 34.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action34() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : ABSKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool01((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 35.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action35() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : CEILKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool02((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 36.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action36() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : CONTAINSKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool03((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 37.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action37() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : DELKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool04((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 38.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action38() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : DELIDXKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool05((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 39.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action39() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : EMPTYKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool06((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 40.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action40() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : ENDSWITHKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool07((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 41.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action41() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : ENTRIESKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool08((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 42.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action42() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : ENUMERATEKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool09((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 43.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action43() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : FLOORKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool10((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 44.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action44() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : FMTKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool11((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 45.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action45() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : INDEXOFKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool12((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 46.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action46() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : JOINKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool13((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 47.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action47() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : KEYSKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool14((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 48.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action48() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : LASTINDEXOFKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool15((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 49.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action49() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : LNKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool16((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 50.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action50() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : LOGKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool17((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 51.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action51() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : LOWERKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool18((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 52.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action52() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : LTRIMKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool19((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 53.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action53() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : MAXKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool20((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 54.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action54() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : MINKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool21((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 55.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action55() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : POWKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool22((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 56.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action56() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : RANGEKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool23((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 57.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action57() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : REPLACEKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool24((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 58.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action58() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : REVERSEKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool25((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 59.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action59() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : ROUNDKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool26((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 60.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action60() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : RTRIMKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool27((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 61.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action61() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : SIZEKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool28((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 62.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action62() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : SORTEDKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool29((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 63.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action63() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : SPLITKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool30((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 64.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action64() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : SQRTKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool31((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 65.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action65() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : STARTSWITHKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool32((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 66.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action66() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : STRKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool33((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 67.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action67() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : STRDUPKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool34((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 68.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action68() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : SUBSETKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool35((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 69.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action69() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : TRIMKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool36((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 70.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action70() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : UPPERKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool37((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 71.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action71() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInDataTool : VALUESKW;
+                doReduce1(token, 4);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseBuiltInDataTool38((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 4;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 72.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action72() throws IOException {
+        switch (token.id) {
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 121:
+            case 122:
+            case 125:
+            case 126:
+            case 127: {
+                // Reduce Name : IDENTIFIERTK;
+                doReduce1(token, 22);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseName1((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 22;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 73.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action73() throws IOException {
+        switch (token.id) {
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 121:
+            case 122:
+            case 125:
+            case 126:
+            case 127: {
+                // Reduce Name : RELATIVENAMETK;
+                doReduce1(token, 22);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseName2((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 22;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 74.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action74() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInTool : BuiltInDataTool;
+                doReduce1(token, 20);
+                Object o1 = doReduce2();
+
+                ToolRef o = hooks.parseBuiltInTool5((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 20;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 75.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action75() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInTool : BuiltInFileTool;
+                doReduce1(token, 20);
+                Object o1 = doReduce2();
+
+                ToolRef o = hooks.parseBuiltInTool4((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 20;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 76.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action76() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInTool : BuiltInGenericTool;
+                doReduce1(token, 20);
+                Object o1 = doReduce2();
+
+                ToolRef o = hooks.parseBuiltInTool2((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 20;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 77.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action77() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInTool : BuiltInIoTool;
+                doReduce1(token, 20);
+                Object o1 = doReduce2();
+
+                ToolRef o = hooks.parseBuiltInTool1((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 20;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 78.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action78() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce BuiltInTool : BuiltInPathTool;
+                doReduce1(token, 20);
+                Object o1 = doReduce2();
+
+                ToolRef o = hooks.parseBuiltInTool3((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 20;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 79.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action79() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce ToolRef : BuiltInTool;
+                doReduce1(token, 19);
+                Object o1 = doReduce2();
+
+                ToolRef o = hooks.parseToolRef1((ToolRef)o1);
+
+                reduce = true;
+                reduceNonTerminal = 19;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 80.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action80() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Reduce ToolRef : Name;
+                doReduce1(token, 19);
+                Object o1 = doReduce2();
+
+                ToolRef o = hooks.parseToolRef2((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 19;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 81.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action81() throws IOException {
+        switch (token.id) {
+            case 136: {
+                // Accept.
+                Object rslt = doAccept(token);
+                accept = true;
+                acceptObject = (ToolInvokeExpression)rslt;
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 82.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action82() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Shift 83.
+                token = doShift(token, 83);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 83.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action83() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 9: {
+                // Shift 84.
+                token = doShift(token, 84);
+                return;
+            }
+
+            case 19: {
+                // Shift 85.
+                token = doShift(token, 85);
+                return;
+            }
+
+            case 25: {
+                // Shift 86.
+                token = doShift(token, 86);
+                return;
+            }
+
+            case 103: {
+                // Shift 87.
+                token = doShift(token, 87);
+                return;
+            }
+
+            case 110: {
+                // Shift 88.
+                token = doShift(token, 88);
+                return;
+            }
+
+            case 117: {
+                // Shift 89.
+                token = doShift(token, 89);
+                return;
+            }
+
+            case 118: {
+                // Shift 90.
+                token = doShift(token, 90);
+                return;
+            }
+
+            case 120: {
+                // Shift 91.
+                token = doShift(token, 91);
+                return;
+            }
+
+            case 121: {
+                // Shift 92.
+                token = doShift(token, 92);
+                return;
+            }
+
+            case 122: {
+                // Shift 93.
+                token = doShift(token, 93);
+                return;
+            }
+
+            case 127: {
+                // Shift 94.
+                token = doShift(token, 94);
+                return;
+            }
+
+            case 128: {
+                // Shift 95.
+                token = doShift(token, 95);
+                return;
+            }
+
+            case 130: {
+                // Shift 96.
+                token = doShift(token, 96);
+                return;
+            }
+
+            case 131: {
+                // Shift 97.
+                token = doShift(token, 97);
+                return;
+            }
+
+            case 132: {
+                // Shift 98.
+                token = doShift(token, 98);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 84.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action84() throws IOException {
+        switch (token.id) {
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 125:
+            case 126:
+            case 127: {
+                // Reduce ExpressionFactor : FALSEKW;
+                doReduce1(token, 16);
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseExpressionFactor02((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 16;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 85.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action85() throws IOException {
+        switch (token.id) {
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 125:
+            case 126:
+            case 127: {
+                // Reduce ExpressionFactor : NULLKW;
+                doReduce1(token, 16);
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseExpressionFactor05((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 16;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 86.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action86() throws IOException {
+        switch (token.id) {
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 125:
+            case 126:
+            case 127: {
+                // Reduce ExpressionFactor : TRUEKW;
+                doReduce1(token, 16);
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseExpressionFactor01((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 16;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 87.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action87() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 9: {
+                // Shift 84.
+                token = doShift(token, 84);
+                return;
+            }
+
+            case 19: {
+                // Shift 85.
+                token = doShift(token, 85);
+                return;
+            }
+
+            case 25: {
+                // Shift 86.
+                token = doShift(token, 86);
+                return;
+            }
+
+            case 103: {
+                // Shift 87.
+                token = doShift(token, 87);
+                return;
+            }
+
+            case 110: {
+                // Shift 88.
+                token = doShift(token, 88);
+                return;
+            }
+
+            case 117: {
+                // Shift 89.
+                token = doShift(token, 89);
+                return;
+            }
+
+            case 118: {
+                // Shift 90.
+                token = doShift(token, 90);
+                return;
+            }
+
+            case 121: {
+                // Shift 92.
+                token = doShift(token, 92);
+                return;
+            }
+
+            case 122: {
+                // Shift 93.
+                token = doShift(token, 93);
+                return;
+            }
+
+            case 127: {
+                // Shift 94.
+                token = doShift(token, 94);
+                return;
+            }
+
+            case 130: {
+                // Shift 96.
+                token = doShift(token, 96);
+                return;
+            }
+
+            case 131: {
+                // Shift 97.
+                token = doShift(token, 97);
+                return;
+            }
+
+            case 132: {
+                // Shift 98.
+                token = doShift(token, 98);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 88.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action88() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 9: {
+                // Shift 84.
+                token = doShift(token, 84);
+                return;
+            }
+
+            case 19: {
+                // Shift 85.
+                token = doShift(token, 85);
+                return;
+            }
+
+            case 25: {
+                // Shift 86.
+                token = doShift(token, 86);
+                return;
+            }
+
+            case 103: {
+                // Shift 87.
+                token = doShift(token, 87);
+                return;
+            }
+
+            case 110: {
+                // Shift 88.
+                token = doShift(token, 88);
+                return;
+            }
+
+            case 117: {
+                // Shift 89.
+                token = doShift(token, 89);
+                return;
+            }
+
+            case 118: {
+                // Shift 90.
+                token = doShift(token, 90);
+                return;
+            }
+
+            case 121: {
+                // Shift 92.
+                token = doShift(token, 92);
+                return;
+            }
+
+            case 122: {
+                // Shift 93.
+                token = doShift(token, 93);
+                return;
+            }
+
+            case 127: {
+                // Shift 94.
+                token = doShift(token, 94);
+                return;
+            }
+
+            case 130: {
+                // Shift 96.
+                token = doShift(token, 96);
+                return;
+            }
+
+            case 131: {
+                // Shift 97.
+                token = doShift(token, 97);
+                return;
+            }
+
+            case 132: {
+                // Shift 98.
+                token = doShift(token, 98);
+                return;
+            }
+
+            case 109: {
+                // Shift 221.
+                token = doShift(token, 221);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 89.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action89() throws IOException {
+        switch (token.id) {
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 1: {
+                // Shift 170.
+                token = doShift(token, 170);
+                return;
+            }
+
+            case 4: {
+                // Shift 171.
+                token = doShift(token, 171);
+                return;
+            }
+
+            case 15: {
+                // Shift 172.
+                token = doShift(token, 172);
+                return;
+            }
+
+            case 16: {
+                // Shift 173.
+                token = doShift(token, 173);
+                return;
+            }
+
+            case 17: {
+                // Shift 174.
+                token = doShift(token, 174);
+                return;
+            }
+
+            case 18: {
+                // Shift 175.
+                token = doShift(token, 175);
+                return;
+            }
+
+            case 20: {
+                // Shift 176.
+                token = doShift(token, 176);
+                return;
+            }
+
+            case 22: {
+                // Shift 177.
+                token = doShift(token, 177);
+                return;
+            }
+
+            case 23: {
+                // Shift 178.
+                token = doShift(token, 178);
+                return;
+            }
+
+            case 26: {
+                // Shift 179.
+                token = doShift(token, 179);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 90.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action90() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 9: {
+                // Shift 84.
+                token = doShift(token, 84);
+                return;
+            }
+
+            case 19: {
+                // Shift 85.
+                token = doShift(token, 85);
+                return;
+            }
+
+            case 25: {
+                // Shift 86.
+                token = doShift(token, 86);
+                return;
+            }
+
+            case 103: {
+                // Shift 87.
+                token = doShift(token, 87);
+                return;
+            }
+
+            case 110: {
+                // Shift 88.
+                token = doShift(token, 88);
+                return;
+            }
+
+            case 117: {
+                // Shift 89.
+                token = doShift(token, 89);
+                return;
+            }
+
+            case 118: {
+                // Shift 90.
+                token = doShift(token, 90);
+                return;
+            }
+
+            case 121: {
+                // Shift 92.
+                token = doShift(token, 92);
+                return;
+            }
+
+            case 122: {
+                // Shift 93.
+                token = doShift(token, 93);
+                return;
+            }
+
+            case 127: {
+                // Shift 94.
+                token = doShift(token, 94);
+                return;
+            }
+
+            case 130: {
+                // Shift 96.
+                token = doShift(token, 96);
+                return;
+            }
+
+            case 131: {
+                // Shift 97.
+                token = doShift(token, 97);
+                return;
+            }
+
+            case 132: {
+                // Shift 98.
+                token = doShift(token, 98);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 91.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action91() throws IOException {
+        switch (token.id) {
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 125:
+            case 126:
+            case 127:
+            case 136: {
+                // Reduce ToolInvokeExpression : ToolRef PAROPENTK PARCLOSETK;
+                doReduce1(token, 18);
+                doReduce2();
+                Object o2 = doReduce2();
+                Object o1 = doReduce2();
+
+                ToolInvokeExpression o = hooks.parseToolInvokeExpression2((ToolRef)o1, (Token)o2);
+
+                reduce = true;
+                reduceNonTerminal = 18;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 92.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action92() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 9: {
+                // Shift 84.
+                token = doShift(token, 84);
+                return;
+            }
+
+            case 19: {
+                // Shift 85.
+                token = doShift(token, 85);
+                return;
+            }
+
+            case 25: {
+                // Shift 86.
+                token = doShift(token, 86);
+                return;
+            }
+
+            case 103: {
+                // Shift 87.
+                token = doShift(token, 87);
+                return;
+            }
+
+            case 110: {
+                // Shift 88.
+                token = doShift(token, 88);
+                return;
+            }
+
+            case 117: {
+                // Shift 89.
+                token = doShift(token, 89);
+                return;
+            }
+
+            case 118: {
+                // Shift 90.
+                token = doShift(token, 90);
+                return;
+            }
+
+            case 121: {
+                // Shift 92.
+                token = doShift(token, 92);
+                return;
+            }
+
+            case 122: {
+                // Shift 93.
+                token = doShift(token, 93);
+                return;
+            }
+
+            case 127: {
+                // Shift 94.
+                token = doShift(token, 94);
+                return;
+            }
+
+            case 130: {
+                // Shift 96.
+                token = doShift(token, 96);
+                return;
+            }
+
+            case 131: {
+                // Shift 97.
+                token = doShift(token, 97);
+                return;
+            }
+
+            case 132: {
+                // Shift 98.
+                token = doShift(token, 98);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 93.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action93() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 9: {
+                // Shift 84.
+                token = doShift(token, 84);
+                return;
+            }
+
+            case 19: {
+                // Shift 85.
+                token = doShift(token, 85);
+                return;
+            }
+
+            case 25: {
+                // Shift 86.
+                token = doShift(token, 86);
+                return;
+            }
+
+            case 103: {
+                // Shift 87.
+                token = doShift(token, 87);
+                return;
+            }
+
+            case 110: {
+                // Shift 88.
+                token = doShift(token, 88);
+                return;
+            }
+
+            case 117: {
+                // Shift 89.
+                token = doShift(token, 89);
+                return;
+            }
+
+            case 118: {
+                // Shift 90.
+                token = doShift(token, 90);
+                return;
+            }
+
+            case 121: {
+                // Shift 92.
+                token = doShift(token, 92);
+                return;
+            }
+
+            case 122: {
+                // Shift 93.
+                token = doShift(token, 93);
+                return;
+            }
+
+            case 127: {
+                // Shift 94.
+                token = doShift(token, 94);
+                return;
+            }
+
+            case 130: {
+                // Shift 96.
+                token = doShift(token, 96);
+                return;
+            }
+
+            case 131: {
+                // Shift 97.
+                token = doShift(token, 97);
+                return;
+            }
+
+            case 132: {
+                // Shift 98.
+                token = doShift(token, 98);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 94.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action94() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 9: {
+                // Shift 84.
+                token = doShift(token, 84);
+                return;
+            }
+
+            case 19: {
+                // Shift 85.
+                token = doShift(token, 85);
+                return;
+            }
+
+            case 25: {
+                // Shift 86.
+                token = doShift(token, 86);
+                return;
+            }
+
+            case 103: {
+                // Shift 87.
+                token = doShift(token, 87);
+                return;
+            }
+
+            case 110: {
+                // Shift 88.
+                token = doShift(token, 88);
+                return;
+            }
+
+            case 117: {
+                // Shift 89.
+                token = doShift(token, 89);
+                return;
+            }
+
+            case 118: {
+                // Shift 90.
+                token = doShift(token, 90);
+                return;
+            }
+
+            case 121: {
+                // Shift 92.
+                token = doShift(token, 92);
+                return;
+            }
+
+            case 122: {
+                // Shift 93.
+                token = doShift(token, 93);
+                return;
+            }
+
+            case 127: {
+                // Shift 94.
+                token = doShift(token, 94);
+                return;
+            }
+
+            case 130: {
+                // Shift 96.
+                token = doShift(token, 96);
+                return;
+            }
+
+            case 131: {
+                // Shift 97.
+                token = doShift(token, 97);
+                return;
+            }
+
+            case 132: {
+                // Shift 98.
+                token = doShift(token, 98);
+                return;
+            }
+
+            case 126: {
+                // Shift 155.
+                token = doShift(token, 155);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 95.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action95() throws IOException {
+        switch (token.id) {
+            case 113: {
+                // Shift 153.
+                token = doShift(token, 153);
+                return;
+            }
+
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 108:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 121:
+            case 122:
+            case 125:
+            case 127: {
+                // Reduce Name : IDENTIFIERTK;
+                doReduce1(token, 22);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseName1((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 22;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 96.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action96() throws IOException {
+        switch (token.id) {
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 125:
+            case 126:
+            case 127: {
+                // Reduce ExpressionFactor : NUMBERTK;
+                doReduce1(token, 16);
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseExpressionFactor03((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 16;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 97.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action97() throws IOException {
+        switch (token.id) {
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 125:
+            case 126:
+            case 127: {
+                // Reduce ExpressionFactor : DOUBLETK;
+                doReduce1(token, 16);
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseExpressionFactor04((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 16;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 98.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action98() throws IOException {
+        switch (token.id) {
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 125:
+            case 126:
+            case 127: {
+                // Reduce ExpressionFactor : STRINGTK;
+                doReduce1(token, 16);
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseExpressionFactor06((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 16;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 99.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action99() throws IOException {
+        switch (token.id) {
+            case 118: {
+                // Shift 126.
+                token = doShift(token, 126);
+                return;
+            }
+
+            case 122: {
+                // Shift 127.
+                token = doShift(token, 127);
+                return;
+            }
+
+            case 100:
+            case 104:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 119:
+            case 120:
+            case 126: {
+                // Reduce CompareExpression : AddExpression;
+                doReduce1(token, 11);
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseCompareExpression1((Expression)o1);
+
+                reduce = true;
+                reduceNonTerminal = 11;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 100.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action100() throws IOException {
+        switch (token.id) {
+            case 100: {
+                // Shift 117.
+                token = doShift(token, 117);
+                return;
+            }
+
+            case 104:
+            case 107:
+            case 108:
+            case 109:
+            case 120:
+            case 126: {
+                // Reduce Expression : AndExpression;
+                doReduce1(token, 9);
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseExpression1((Expression)o1);
+
+                reduce = true;
+                reduceNonTerminal = 9;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 101.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action101() throws IOException {
+        switch (token.id) {
+            case 112: {
+                // Shift 119.
+                token = doShift(token, 119);
+                return;
+            }
+
+            case 114: {
+                // Shift 120.
+                token = doShift(token, 120);
+                return;
+            }
+
+            case 115: {
+                // Shift 121.
+                token = doShift(token, 121);
+                return;
+            }
+
+            case 116: {
+                // Shift 122.
+                token = doShift(token, 122);
+                return;
+            }
+
+            case 117: {
+                // Shift 123.
+                token = doShift(token, 123);
+                return;
+            }
+
+            case 119: {
+                // Shift 124.
+                token = doShift(token, 124);
+                return;
+            }
+
+            case 100:
+            case 104:
+            case 107:
+            case 108:
+            case 109:
+            case 120:
+            case 126: {
+                // Reduce AndExpression : CompareExpression;
+                doReduce1(token, 10);
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseAndExpression1((Expression)o1);
+
+                reduce = true;
+                reduceNonTerminal = 10;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 102.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action102() throws IOException {
+        switch (token.id) {
+            case 104: {
+                // Shift 115.
+                token = doShift(token, 115);
+                return;
+            }
+
+            case 108:
+            case 120: {
+                // Reduce ToolArgs : Expression;
+                doReduce1(token, 21);
+                Object o1 = doReduce2();
+
+                List<ToolArgument> o = hooks.parseToolArgs1((Expression)o1);
+
+                reduce = true;
+                reduceNonTerminal = 21;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 103.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action103() throws IOException {
+        switch (token.id) {
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 125:
+            case 126:
+            case 127: {
+                // Reduce ProjExpression : ExpressionFactor;
+                doReduce1(token, 15);
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseProjExpression1((Expression)o1);
+
+                reduce = true;
+                reduceNonTerminal = 15;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 104.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action104() throws IOException {
+        switch (token.id) {
+            case 101: {
+                // Shift 129.
+                token = doShift(token, 129);
+                return;
+            }
+
+            case 102: {
+                // Shift 130.
+                token = doShift(token, 130);
+                return;
+            }
+
+            case 105: {
+                // Shift 131.
+                token = doShift(token, 131);
+                return;
+            }
+
+            case 125: {
+                // Shift 132.
+                token = doShift(token, 132);
+                return;
+            }
+
+            case 100:
+            case 104:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 126: {
+                // Reduce AddExpression : MulExpression;
+                doReduce1(token, 12);
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseAddExpression1((Expression)o1);
+
+                reduce = true;
+                reduceNonTerminal = 12;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 105.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action105() throws IOException {
+        switch (token.id) {
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 125:
+            case 126:
+            case 127: {
+                // Reduce ExpressionFactor : Name;
+                doReduce1(token, 16);
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseExpressionFactor16((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 16;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            case 121: {
+                // Reduce ToolRef : Name;
+                doReduce1(token, 19);
+                Object o1 = doReduce2();
+
+                ToolRef o = hooks.parseToolRef2((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 19;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 106.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action106() throws IOException {
+        switch (token.id) {
+            case 127: {
+                // Shift 145.
+                token = doShift(token, 145);
+                return;
+            }
+
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 125:
+            case 126: {
+                // Reduce UnaryExpression : ProjExpression;
+                doReduce1(token, 14);
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseUnaryExpression1((Expression)o1);
+
+                reduce = true;
+                reduceNonTerminal = 14;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 107.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action107() throws IOException {
+        switch (token.id) {
+            case 108: {
+                // Shift 110.
+                token = doShift(token, 110);
+                return;
+            }
+
+            case 120: {
+                // Reduce OptComma : ;
+                doReduce1(token, 23);
+                Token o = hooks.parseOptComma1();
+
+                reduce = true;
+                reduceNonTerminal = 23;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 108.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action108() throws IOException {
+        switch (token.id) {
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 125:
+            case 126:
+            case 127: {
+                // Reduce ExpressionFactor : ToolInvokeExpression;
+                doReduce1(token, 16);
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseExpressionFactor15((ToolInvokeExpression)o1);
+
+                reduce = true;
+                reduceNonTerminal = 16;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 109.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action109() throws IOException {
+        switch (token.id) {
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 125:
+            case 126: {
+                // Reduce MulExpression : UnaryExpression;
+                doReduce1(token, 13);
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseMulExpression1((Expression)o1);
+
+                reduce = true;
+                reduceNonTerminal = 13;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 110.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action110() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 9: {
+                // Shift 84.
+                token = doShift(token, 84);
+                return;
+            }
+
+            case 19: {
+                // Shift 85.
+                token = doShift(token, 85);
+                return;
+            }
+
+            case 25: {
+                // Shift 86.
+                token = doShift(token, 86);
+                return;
+            }
+
+            case 103: {
+                // Shift 87.
+                token = doShift(token, 87);
+                return;
+            }
+
+            case 110: {
+                // Shift 88.
+                token = doShift(token, 88);
+                return;
+            }
+
+            case 117: {
+                // Shift 89.
+                token = doShift(token, 89);
+                return;
+            }
+
+            case 118: {
+                // Shift 90.
+                token = doShift(token, 90);
+                return;
+            }
+
+            case 121: {
+                // Shift 92.
+                token = doShift(token, 92);
+                return;
+            }
+
+            case 122: {
+                // Shift 93.
+                token = doShift(token, 93);
+                return;
+            }
+
+            case 127: {
+                // Shift 94.
+                token = doShift(token, 94);
+                return;
+            }
+
+            case 130: {
+                // Shift 96.
+                token = doShift(token, 96);
+                return;
+            }
+
+            case 131: {
+                // Shift 97.
+                token = doShift(token, 97);
+                return;
+            }
+
+            case 132: {
+                // Shift 98.
+                token = doShift(token, 98);
+                return;
+            }
+
+            case 128: {
+                // Shift 113.
+                token = doShift(token, 113);
+                return;
+            }
+
+            case 120: {
+                // Reduce OptComma : COMMATK;
+                doReduce1(token, 23);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseOptComma2((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 23;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 111.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action111() throws IOException {
+        switch (token.id) {
+            case 120: {
+                // Shift 112.
+                token = doShift(token, 112);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 112.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action112() throws IOException {
+        switch (token.id) {
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 125:
+            case 126:
+            case 127:
+            case 136: {
+                // Reduce ToolInvokeExpression : ToolRef PAROPENTK ToolArgs OptComma PARCLOSETK;
+                doReduce1(token, 18);
+                doReduce2();
+                Object o4 = doReduce2();
+                Object o3 = doReduce2();
+                Object o2 = doReduce2();
+                Object o1 = doReduce2();
+
+                ToolInvokeExpression o = hooks.parseToolInvokeExpression1((ToolRef)o1, (Token)o2, (List<ToolArgument>)o3, (Token)o4);
+
+                reduce = true;
+                reduceNonTerminal = 18;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 113.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action113() throws IOException {
+        switch (token.id) {
+            case 113: {
+                // Shift 143.
+                token = doShift(token, 143);
+                return;
+            }
+
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 108:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 121:
+            case 122:
+            case 125:
+            case 127: {
+                // Reduce Name : IDENTIFIERTK;
+                doReduce1(token, 22);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseName1((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 22;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 114.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action114() throws IOException {
+        switch (token.id) {
+            case 104: {
+                // Shift 115.
+                token = doShift(token, 115);
+                return;
+            }
+
+            case 108:
+            case 120: {
+                // Reduce ToolArgs : ToolArgs COMMATK Expression;
+                doReduce1(token, 21);
+                Object o3 = doReduce2();
+                doReduce2();
+                Object o1 = doReduce2();
+
+                List<ToolArgument> o = hooks.parseToolArgs3((List<ToolArgument>)o1, (Expression)o3);
+
+                reduce = true;
+                reduceNonTerminal = 21;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 115.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action115() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 9: {
+                // Shift 84.
+                token = doShift(token, 84);
+                return;
+            }
+
+            case 19: {
+                // Shift 85.
+                token = doShift(token, 85);
+                return;
+            }
+
+            case 25: {
+                // Shift 86.
+                token = doShift(token, 86);
+                return;
+            }
+
+            case 103: {
+                // Shift 87.
+                token = doShift(token, 87);
+                return;
+            }
+
+            case 110: {
+                // Shift 88.
+                token = doShift(token, 88);
+                return;
+            }
+
+            case 117: {
+                // Shift 89.
+                token = doShift(token, 89);
+                return;
+            }
+
+            case 118: {
+                // Shift 90.
+                token = doShift(token, 90);
+                return;
+            }
+
+            case 121: {
+                // Shift 92.
+                token = doShift(token, 92);
+                return;
+            }
+
+            case 122: {
+                // Shift 93.
+                token = doShift(token, 93);
+                return;
+            }
+
+            case 127: {
+                // Shift 94.
+                token = doShift(token, 94);
+                return;
+            }
+
+            case 130: {
+                // Shift 96.
+                token = doShift(token, 96);
+                return;
+            }
+
+            case 131: {
+                // Shift 97.
+                token = doShift(token, 97);
+                return;
+            }
+
+            case 132: {
+                // Shift 98.
+                token = doShift(token, 98);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 116.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action116() throws IOException {
+        switch (token.id) {
+            case 100: {
+                // Shift 117.
+                token = doShift(token, 117);
+                return;
+            }
+
+            case 104:
+            case 107:
+            case 108:
+            case 109:
+            case 120:
+            case 126: {
+                // Reduce Expression : Expression ORKW AndExpression;
+                doReduce1(token, 9);
+                Object o3 = doReduce2();
+                Object o2 = doReduce2();
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseExpression2((Expression)o1, (Token)o2, (Expression)o3);
+
+                reduce = true;
+                reduceNonTerminal = 9;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 117.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action117() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 9: {
+                // Shift 84.
+                token = doShift(token, 84);
+                return;
+            }
+
+            case 19: {
+                // Shift 85.
+                token = doShift(token, 85);
+                return;
+            }
+
+            case 25: {
+                // Shift 86.
+                token = doShift(token, 86);
+                return;
+            }
+
+            case 103: {
+                // Shift 87.
+                token = doShift(token, 87);
+                return;
+            }
+
+            case 110: {
+                // Shift 88.
+                token = doShift(token, 88);
+                return;
+            }
+
+            case 117: {
+                // Shift 89.
+                token = doShift(token, 89);
+                return;
+            }
+
+            case 118: {
+                // Shift 90.
+                token = doShift(token, 90);
+                return;
+            }
+
+            case 121: {
+                // Shift 92.
+                token = doShift(token, 92);
+                return;
+            }
+
+            case 122: {
+                // Shift 93.
+                token = doShift(token, 93);
+                return;
+            }
+
+            case 127: {
+                // Shift 94.
+                token = doShift(token, 94);
+                return;
+            }
+
+            case 130: {
+                // Shift 96.
+                token = doShift(token, 96);
+                return;
+            }
+
+            case 131: {
+                // Shift 97.
+                token = doShift(token, 97);
+                return;
+            }
+
+            case 132: {
+                // Shift 98.
+                token = doShift(token, 98);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 118.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action118() throws IOException {
+        switch (token.id) {
+            case 112: {
+                // Shift 119.
+                token = doShift(token, 119);
+                return;
+            }
+
+            case 114: {
+                // Shift 120.
+                token = doShift(token, 120);
+                return;
+            }
+
+            case 115: {
+                // Shift 121.
+                token = doShift(token, 121);
+                return;
+            }
+
+            case 116: {
+                // Shift 122.
+                token = doShift(token, 122);
+                return;
+            }
+
+            case 117: {
+                // Shift 123.
+                token = doShift(token, 123);
+                return;
+            }
+
+            case 119: {
+                // Shift 124.
+                token = doShift(token, 124);
+                return;
+            }
+
+            case 100:
+            case 104:
+            case 107:
+            case 108:
+            case 109:
+            case 120:
+            case 126: {
+                // Reduce AndExpression : AndExpression ANDKW CompareExpression;
+                doReduce1(token, 10);
+                Object o3 = doReduce2();
+                Object o2 = doReduce2();
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseAndExpression2((Expression)o1, (Token)o2, (Expression)o3);
+
+                reduce = true;
+                reduceNonTerminal = 10;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 119.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action119() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 9: {
+                // Shift 84.
+                token = doShift(token, 84);
+                return;
+            }
+
+            case 19: {
+                // Shift 85.
+                token = doShift(token, 85);
+                return;
+            }
+
+            case 25: {
+                // Shift 86.
+                token = doShift(token, 86);
+                return;
+            }
+
+            case 103: {
+                // Shift 87.
+                token = doShift(token, 87);
+                return;
+            }
+
+            case 110: {
+                // Shift 88.
+                token = doShift(token, 88);
+                return;
+            }
+
+            case 117: {
+                // Shift 89.
+                token = doShift(token, 89);
+                return;
+            }
+
+            case 118: {
+                // Shift 90.
+                token = doShift(token, 90);
+                return;
+            }
+
+            case 121: {
+                // Shift 92.
+                token = doShift(token, 92);
+                return;
+            }
+
+            case 122: {
+                // Shift 93.
+                token = doShift(token, 93);
+                return;
+            }
+
+            case 127: {
+                // Shift 94.
+                token = doShift(token, 94);
+                return;
+            }
+
+            case 130: {
+                // Shift 96.
+                token = doShift(token, 96);
+                return;
+            }
+
+            case 131: {
+                // Shift 97.
+                token = doShift(token, 97);
+                return;
+            }
+
+            case 132: {
+                // Shift 98.
+                token = doShift(token, 98);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 120.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action120() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 9: {
+                // Shift 84.
+                token = doShift(token, 84);
+                return;
+            }
+
+            case 19: {
+                // Shift 85.
+                token = doShift(token, 85);
+                return;
+            }
+
+            case 25: {
+                // Shift 86.
+                token = doShift(token, 86);
+                return;
+            }
+
+            case 103: {
+                // Shift 87.
+                token = doShift(token, 87);
+                return;
+            }
+
+            case 110: {
+                // Shift 88.
+                token = doShift(token, 88);
+                return;
+            }
+
+            case 117: {
+                // Shift 89.
+                token = doShift(token, 89);
+                return;
+            }
+
+            case 118: {
+                // Shift 90.
+                token = doShift(token, 90);
+                return;
+            }
+
+            case 121: {
+                // Shift 92.
+                token = doShift(token, 92);
+                return;
+            }
+
+            case 122: {
+                // Shift 93.
+                token = doShift(token, 93);
+                return;
+            }
+
+            case 127: {
+                // Shift 94.
+                token = doShift(token, 94);
+                return;
+            }
+
+            case 130: {
+                // Shift 96.
+                token = doShift(token, 96);
+                return;
+            }
+
+            case 131: {
+                // Shift 97.
+                token = doShift(token, 97);
+                return;
+            }
+
+            case 132: {
+                // Shift 98.
+                token = doShift(token, 98);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 121.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action121() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 9: {
+                // Shift 84.
+                token = doShift(token, 84);
+                return;
+            }
+
+            case 19: {
+                // Shift 85.
+                token = doShift(token, 85);
+                return;
+            }
+
+            case 25: {
+                // Shift 86.
+                token = doShift(token, 86);
+                return;
+            }
+
+            case 103: {
+                // Shift 87.
+                token = doShift(token, 87);
+                return;
+            }
+
+            case 110: {
+                // Shift 88.
+                token = doShift(token, 88);
+                return;
+            }
+
+            case 117: {
+                // Shift 89.
+                token = doShift(token, 89);
+                return;
+            }
+
+            case 118: {
+                // Shift 90.
+                token = doShift(token, 90);
+                return;
+            }
+
+            case 121: {
+                // Shift 92.
+                token = doShift(token, 92);
+                return;
+            }
+
+            case 122: {
+                // Shift 93.
+                token = doShift(token, 93);
+                return;
+            }
+
+            case 127: {
+                // Shift 94.
+                token = doShift(token, 94);
+                return;
+            }
+
+            case 130: {
+                // Shift 96.
+                token = doShift(token, 96);
+                return;
+            }
+
+            case 131: {
+                // Shift 97.
+                token = doShift(token, 97);
+                return;
+            }
+
+            case 132: {
+                // Shift 98.
+                token = doShift(token, 98);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 122.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action122() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 9: {
+                // Shift 84.
+                token = doShift(token, 84);
+                return;
+            }
+
+            case 19: {
+                // Shift 85.
+                token = doShift(token, 85);
+                return;
+            }
+
+            case 25: {
+                // Shift 86.
+                token = doShift(token, 86);
+                return;
+            }
+
+            case 103: {
+                // Shift 87.
+                token = doShift(token, 87);
+                return;
+            }
+
+            case 110: {
+                // Shift 88.
+                token = doShift(token, 88);
+                return;
+            }
+
+            case 117: {
+                // Shift 89.
+                token = doShift(token, 89);
+                return;
+            }
+
+            case 118: {
+                // Shift 90.
+                token = doShift(token, 90);
+                return;
+            }
+
+            case 121: {
+                // Shift 92.
+                token = doShift(token, 92);
+                return;
+            }
+
+            case 122: {
+                // Shift 93.
+                token = doShift(token, 93);
+                return;
+            }
+
+            case 127: {
+                // Shift 94.
+                token = doShift(token, 94);
+                return;
+            }
+
+            case 130: {
+                // Shift 96.
+                token = doShift(token, 96);
+                return;
+            }
+
+            case 131: {
+                // Shift 97.
+                token = doShift(token, 97);
+                return;
+            }
+
+            case 132: {
+                // Shift 98.
+                token = doShift(token, 98);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 123.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action123() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 9: {
+                // Shift 84.
+                token = doShift(token, 84);
+                return;
+            }
+
+            case 19: {
+                // Shift 85.
+                token = doShift(token, 85);
+                return;
+            }
+
+            case 25: {
+                // Shift 86.
+                token = doShift(token, 86);
+                return;
+            }
+
+            case 103: {
+                // Shift 87.
+                token = doShift(token, 87);
+                return;
+            }
+
+            case 110: {
+                // Shift 88.
+                token = doShift(token, 88);
+                return;
+            }
+
+            case 117: {
+                // Shift 89.
+                token = doShift(token, 89);
+                return;
+            }
+
+            case 118: {
+                // Shift 90.
+                token = doShift(token, 90);
+                return;
+            }
+
+            case 121: {
+                // Shift 92.
+                token = doShift(token, 92);
+                return;
+            }
+
+            case 122: {
+                // Shift 93.
+                token = doShift(token, 93);
+                return;
+            }
+
+            case 127: {
+                // Shift 94.
+                token = doShift(token, 94);
+                return;
+            }
+
+            case 130: {
+                // Shift 96.
+                token = doShift(token, 96);
+                return;
+            }
+
+            case 131: {
+                // Shift 97.
+                token = doShift(token, 97);
+                return;
+            }
+
+            case 132: {
+                // Shift 98.
+                token = doShift(token, 98);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 124.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action124() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 9: {
+                // Shift 84.
+                token = doShift(token, 84);
+                return;
+            }
+
+            case 19: {
+                // Shift 85.
+                token = doShift(token, 85);
+                return;
+            }
+
+            case 25: {
+                // Shift 86.
+                token = doShift(token, 86);
+                return;
+            }
+
+            case 103: {
+                // Shift 87.
+                token = doShift(token, 87);
+                return;
+            }
+
+            case 110: {
+                // Shift 88.
+                token = doShift(token, 88);
+                return;
+            }
+
+            case 117: {
+                // Shift 89.
+                token = doShift(token, 89);
+                return;
+            }
+
+            case 118: {
+                // Shift 90.
+                token = doShift(token, 90);
+                return;
+            }
+
+            case 121: {
+                // Shift 92.
+                token = doShift(token, 92);
+                return;
+            }
+
+            case 122: {
+                // Shift 93.
+                token = doShift(token, 93);
+                return;
+            }
+
+            case 127: {
+                // Shift 94.
+                token = doShift(token, 94);
+                return;
+            }
+
+            case 130: {
+                // Shift 96.
+                token = doShift(token, 96);
+                return;
+            }
+
+            case 131: {
+                // Shift 97.
+                token = doShift(token, 97);
+                return;
+            }
+
+            case 132: {
+                // Shift 98.
+                token = doShift(token, 98);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 125.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action125() throws IOException {
+        switch (token.id) {
+            case 118: {
+                // Shift 126.
+                token = doShift(token, 126);
+                return;
+            }
+
+            case 122: {
+                // Shift 127.
+                token = doShift(token, 127);
+                return;
+            }
+
+            case 100:
+            case 104:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 119:
+            case 120:
+            case 126: {
+                // Reduce CompareExpression : CompareExpression NETK AddExpression;
+                doReduce1(token, 11);
+                Object o3 = doReduce2();
+                Object o2 = doReduce2();
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseCompareExpression5((Expression)o1, (Token)o2, (Expression)o3);
+
+                reduce = true;
+                reduceNonTerminal = 11;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 126.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action126() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 9: {
+                // Shift 84.
+                token = doShift(token, 84);
+                return;
+            }
+
+            case 19: {
+                // Shift 85.
+                token = doShift(token, 85);
+                return;
+            }
+
+            case 25: {
+                // Shift 86.
+                token = doShift(token, 86);
+                return;
+            }
+
+            case 103: {
+                // Shift 87.
+                token = doShift(token, 87);
+                return;
+            }
+
+            case 110: {
+                // Shift 88.
+                token = doShift(token, 88);
+                return;
+            }
+
+            case 117: {
+                // Shift 89.
+                token = doShift(token, 89);
+                return;
+            }
+
+            case 118: {
+                // Shift 90.
+                token = doShift(token, 90);
+                return;
+            }
+
+            case 121: {
+                // Shift 92.
+                token = doShift(token, 92);
+                return;
+            }
+
+            case 122: {
+                // Shift 93.
+                token = doShift(token, 93);
+                return;
+            }
+
+            case 127: {
+                // Shift 94.
+                token = doShift(token, 94);
+                return;
+            }
+
+            case 130: {
+                // Shift 96.
+                token = doShift(token, 96);
+                return;
+            }
+
+            case 131: {
+                // Shift 97.
+                token = doShift(token, 97);
+                return;
+            }
+
+            case 132: {
+                // Shift 98.
+                token = doShift(token, 98);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 127.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action127() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 9: {
+                // Shift 84.
+                token = doShift(token, 84);
+                return;
+            }
+
+            case 19: {
+                // Shift 85.
+                token = doShift(token, 85);
+                return;
+            }
+
+            case 25: {
+                // Shift 86.
+                token = doShift(token, 86);
+                return;
+            }
+
+            case 103: {
+                // Shift 87.
+                token = doShift(token, 87);
+                return;
+            }
+
+            case 110: {
+                // Shift 88.
+                token = doShift(token, 88);
+                return;
+            }
+
+            case 117: {
+                // Shift 89.
+                token = doShift(token, 89);
+                return;
+            }
+
+            case 118: {
+                // Shift 90.
+                token = doShift(token, 90);
+                return;
+            }
+
+            case 121: {
+                // Shift 92.
+                token = doShift(token, 92);
+                return;
+            }
+
+            case 122: {
+                // Shift 93.
+                token = doShift(token, 93);
+                return;
+            }
+
+            case 127: {
+                // Shift 94.
+                token = doShift(token, 94);
+                return;
+            }
+
+            case 130: {
+                // Shift 96.
+                token = doShift(token, 96);
+                return;
+            }
+
+            case 131: {
+                // Shift 97.
+                token = doShift(token, 97);
+                return;
+            }
+
+            case 132: {
+                // Shift 98.
+                token = doShift(token, 98);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 128.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action128() throws IOException {
+        switch (token.id) {
+            case 101: {
+                // Shift 129.
+                token = doShift(token, 129);
+                return;
+            }
+
+            case 102: {
+                // Shift 130.
+                token = doShift(token, 130);
+                return;
+            }
+
+            case 105: {
+                // Shift 131.
+                token = doShift(token, 131);
+                return;
+            }
+
+            case 125: {
+                // Shift 132.
+                token = doShift(token, 132);
+                return;
+            }
+
+            case 100:
+            case 104:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 126: {
+                // Reduce AddExpression : AddExpression PLUSTK MulExpression;
+                doReduce1(token, 12);
+                Object o3 = doReduce2();
+                Object o2 = doReduce2();
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseAddExpression3((Expression)o1, (Token)o2, (Expression)o3);
+
+                reduce = true;
+                reduceNonTerminal = 12;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 129.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action129() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 9: {
+                // Shift 84.
+                token = doShift(token, 84);
+                return;
+            }
+
+            case 19: {
+                // Shift 85.
+                token = doShift(token, 85);
+                return;
+            }
+
+            case 25: {
+                // Shift 86.
+                token = doShift(token, 86);
+                return;
+            }
+
+            case 103: {
+                // Shift 87.
+                token = doShift(token, 87);
+                return;
+            }
+
+            case 110: {
+                // Shift 88.
+                token = doShift(token, 88);
+                return;
+            }
+
+            case 117: {
+                // Shift 89.
+                token = doShift(token, 89);
+                return;
+            }
+
+            case 118: {
+                // Shift 90.
+                token = doShift(token, 90);
+                return;
+            }
+
+            case 121: {
+                // Shift 92.
+                token = doShift(token, 92);
+                return;
+            }
+
+            case 122: {
+                // Shift 93.
+                token = doShift(token, 93);
+                return;
+            }
+
+            case 127: {
+                // Shift 94.
+                token = doShift(token, 94);
+                return;
+            }
+
+            case 130: {
+                // Shift 96.
+                token = doShift(token, 96);
+                return;
+            }
+
+            case 131: {
+                // Shift 97.
+                token = doShift(token, 97);
+                return;
+            }
+
+            case 132: {
+                // Shift 98.
+                token = doShift(token, 98);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 130.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action130() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 9: {
+                // Shift 84.
+                token = doShift(token, 84);
+                return;
+            }
+
+            case 19: {
+                // Shift 85.
+                token = doShift(token, 85);
+                return;
+            }
+
+            case 25: {
+                // Shift 86.
+                token = doShift(token, 86);
+                return;
+            }
+
+            case 103: {
+                // Shift 87.
+                token = doShift(token, 87);
+                return;
+            }
+
+            case 110: {
+                // Shift 88.
+                token = doShift(token, 88);
+                return;
+            }
+
+            case 117: {
+                // Shift 89.
+                token = doShift(token, 89);
+                return;
+            }
+
+            case 118: {
+                // Shift 90.
+                token = doShift(token, 90);
+                return;
+            }
+
+            case 121: {
+                // Shift 92.
+                token = doShift(token, 92);
+                return;
+            }
+
+            case 122: {
+                // Shift 93.
+                token = doShift(token, 93);
+                return;
+            }
+
+            case 127: {
+                // Shift 94.
+                token = doShift(token, 94);
+                return;
+            }
+
+            case 130: {
+                // Shift 96.
+                token = doShift(token, 96);
+                return;
+            }
+
+            case 131: {
+                // Shift 97.
+                token = doShift(token, 97);
+                return;
+            }
+
+            case 132: {
+                // Shift 98.
+                token = doShift(token, 98);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 131.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action131() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 9: {
+                // Shift 84.
+                token = doShift(token, 84);
+                return;
+            }
+
+            case 19: {
+                // Shift 85.
+                token = doShift(token, 85);
+                return;
+            }
+
+            case 25: {
+                // Shift 86.
+                token = doShift(token, 86);
+                return;
+            }
+
+            case 103: {
+                // Shift 87.
+                token = doShift(token, 87);
+                return;
+            }
+
+            case 110: {
+                // Shift 88.
+                token = doShift(token, 88);
+                return;
+            }
+
+            case 117: {
+                // Shift 89.
+                token = doShift(token, 89);
+                return;
+            }
+
+            case 118: {
+                // Shift 90.
+                token = doShift(token, 90);
+                return;
+            }
+
+            case 121: {
+                // Shift 92.
+                token = doShift(token, 92);
+                return;
+            }
+
+            case 122: {
+                // Shift 93.
+                token = doShift(token, 93);
+                return;
+            }
+
+            case 127: {
+                // Shift 94.
+                token = doShift(token, 94);
+                return;
+            }
+
+            case 130: {
+                // Shift 96.
+                token = doShift(token, 96);
+                return;
+            }
+
+            case 131: {
+                // Shift 97.
+                token = doShift(token, 97);
+                return;
+            }
+
+            case 132: {
+                // Shift 98.
+                token = doShift(token, 98);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 132.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action132() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 9: {
+                // Shift 84.
+                token = doShift(token, 84);
+                return;
+            }
+
+            case 19: {
+                // Shift 85.
+                token = doShift(token, 85);
+                return;
+            }
+
+            case 25: {
+                // Shift 86.
+                token = doShift(token, 86);
+                return;
+            }
+
+            case 103: {
+                // Shift 87.
+                token = doShift(token, 87);
+                return;
+            }
+
+            case 110: {
+                // Shift 88.
+                token = doShift(token, 88);
+                return;
+            }
+
+            case 117: {
+                // Shift 89.
+                token = doShift(token, 89);
+                return;
+            }
+
+            case 118: {
+                // Shift 90.
+                token = doShift(token, 90);
+                return;
+            }
+
+            case 121: {
+                // Shift 92.
+                token = doShift(token, 92);
+                return;
+            }
+
+            case 122: {
+                // Shift 93.
+                token = doShift(token, 93);
+                return;
+            }
+
+            case 127: {
+                // Shift 94.
+                token = doShift(token, 94);
+                return;
+            }
+
+            case 130: {
+                // Shift 96.
+                token = doShift(token, 96);
+                return;
+            }
+
+            case 131: {
+                // Shift 97.
+                token = doShift(token, 97);
+                return;
+            }
+
+            case 132: {
+                // Shift 98.
+                token = doShift(token, 98);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 133.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action133() throws IOException {
+        switch (token.id) {
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 125:
+            case 126: {
+                // Reduce MulExpression : MulExpression SLASHTK UnaryExpression;
+                doReduce1(token, 13);
+                Object o3 = doReduce2();
+                Object o2 = doReduce2();
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseMulExpression3((Expression)o1, (Token)o2, (Expression)o3);
+
+                reduce = true;
+                reduceNonTerminal = 13;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 134.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action134() throws IOException {
+        switch (token.id) {
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 125:
+            case 126: {
+                // Reduce MulExpression : MulExpression ASTERISKTK UnaryExpression;
+                doReduce1(token, 13);
+                Object o3 = doReduce2();
+                Object o2 = doReduce2();
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseMulExpression2((Expression)o1, (Token)o2, (Expression)o3);
+
+                reduce = true;
+                reduceNonTerminal = 13;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 135.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action135() throws IOException {
+        switch (token.id) {
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 125:
+            case 126: {
+                // Reduce MulExpression : MulExpression MODKW UnaryExpression;
+                doReduce1(token, 13);
+                Object o3 = doReduce2();
+                Object o2 = doReduce2();
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseMulExpression5((Expression)o1, (Token)o2, (Expression)o3);
+
+                reduce = true;
+                reduceNonTerminal = 13;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 136.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action136() throws IOException {
+        switch (token.id) {
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 125:
+            case 126: {
+                // Reduce MulExpression : MulExpression DIVKW UnaryExpression;
+                doReduce1(token, 13);
+                Object o3 = doReduce2();
+                Object o2 = doReduce2();
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseMulExpression4((Expression)o1, (Token)o2, (Expression)o3);
+
+                reduce = true;
+                reduceNonTerminal = 13;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 137.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action137() throws IOException {
+        switch (token.id) {
+            case 101: {
+                // Shift 129.
+                token = doShift(token, 129);
+                return;
+            }
+
+            case 102: {
+                // Shift 130.
+                token = doShift(token, 130);
+                return;
+            }
+
+            case 105: {
+                // Shift 131.
+                token = doShift(token, 131);
+                return;
+            }
+
+            case 125: {
+                // Shift 132.
+                token = doShift(token, 132);
+                return;
+            }
+
+            case 100:
+            case 104:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 126: {
+                // Reduce AddExpression : AddExpression MINUSTK MulExpression;
+                doReduce1(token, 12);
+                Object o3 = doReduce2();
+                Object o2 = doReduce2();
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseAddExpression2((Expression)o1, (Token)o2, (Expression)o3);
+
+                reduce = true;
+                reduceNonTerminal = 12;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 138.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action138() throws IOException {
+        switch (token.id) {
+            case 118: {
+                // Shift 126.
+                token = doShift(token, 126);
+                return;
+            }
+
+            case 122: {
+                // Shift 127.
+                token = doShift(token, 127);
+                return;
+            }
+
+            case 100:
+            case 104:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 119:
+            case 120:
+            case 126: {
+                // Reduce CompareExpression : CompareExpression LTTK AddExpression;
+                doReduce1(token, 11);
+                Object o3 = doReduce2();
+                Object o2 = doReduce2();
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseCompareExpression2((Expression)o1, (Token)o2, (Expression)o3);
+
+                reduce = true;
+                reduceNonTerminal = 11;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 139.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action139() throws IOException {
+        switch (token.id) {
+            case 118: {
+                // Shift 126.
+                token = doShift(token, 126);
+                return;
+            }
+
+            case 122: {
+                // Shift 127.
+                token = doShift(token, 127);
+                return;
+            }
+
+            case 100:
+            case 104:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 119:
+            case 120:
+            case 126: {
+                // Reduce CompareExpression : CompareExpression LETK AddExpression;
+                doReduce1(token, 11);
+                Object o3 = doReduce2();
+                Object o2 = doReduce2();
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseCompareExpression3((Expression)o1, (Token)o2, (Expression)o3);
+
+                reduce = true;
+                reduceNonTerminal = 11;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 140.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action140() throws IOException {
+        switch (token.id) {
+            case 118: {
+                // Shift 126.
+                token = doShift(token, 126);
+                return;
+            }
+
+            case 122: {
+                // Shift 127.
+                token = doShift(token, 127);
+                return;
+            }
+
+            case 100:
+            case 104:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 119:
+            case 120:
+            case 126: {
+                // Reduce CompareExpression : CompareExpression GTTK AddExpression;
+                doReduce1(token, 11);
+                Object o3 = doReduce2();
+                Object o2 = doReduce2();
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseCompareExpression7((Expression)o1, (Token)o2, (Expression)o3);
+
+                reduce = true;
+                reduceNonTerminal = 11;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 141.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action141() throws IOException {
+        switch (token.id) {
+            case 118: {
+                // Shift 126.
+                token = doShift(token, 126);
+                return;
+            }
+
+            case 122: {
+                // Shift 127.
+                token = doShift(token, 127);
+                return;
+            }
+
+            case 100:
+            case 104:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 119:
+            case 120:
+            case 126: {
+                // Reduce CompareExpression : CompareExpression GETK AddExpression;
+                doReduce1(token, 11);
+                Object o3 = doReduce2();
+                Object o2 = doReduce2();
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseCompareExpression6((Expression)o1, (Token)o2, (Expression)o3);
+
+                reduce = true;
+                reduceNonTerminal = 11;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 142.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action142() throws IOException {
+        switch (token.id) {
+            case 118: {
+                // Shift 126.
+                token = doShift(token, 126);
+                return;
+            }
+
+            case 122: {
+                // Shift 127.
+                token = doShift(token, 127);
+                return;
+            }
+
+            case 100:
+            case 104:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 119:
+            case 120:
+            case 126: {
+                // Reduce CompareExpression : CompareExpression EQEQTK AddExpression;
+                doReduce1(token, 11);
+                Object o3 = doReduce2();
+                Object o2 = doReduce2();
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseCompareExpression4((Expression)o1, (Token)o2, (Expression)o3);
+
+                reduce = true;
+                reduceNonTerminal = 11;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 143.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action143() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 9: {
+                // Shift 84.
+                token = doShift(token, 84);
+                return;
+            }
+
+            case 19: {
+                // Shift 85.
+                token = doShift(token, 85);
+                return;
+            }
+
+            case 25: {
+                // Shift 86.
+                token = doShift(token, 86);
+                return;
+            }
+
+            case 103: {
+                // Shift 87.
+                token = doShift(token, 87);
+                return;
+            }
+
+            case 110: {
+                // Shift 88.
+                token = doShift(token, 88);
+                return;
+            }
+
+            case 117: {
+                // Shift 89.
+                token = doShift(token, 89);
+                return;
+            }
+
+            case 118: {
+                // Shift 90.
+                token = doShift(token, 90);
+                return;
+            }
+
+            case 121: {
+                // Shift 92.
+                token = doShift(token, 92);
+                return;
+            }
+
+            case 122: {
+                // Shift 93.
+                token = doShift(token, 93);
+                return;
+            }
+
+            case 127: {
+                // Shift 94.
+                token = doShift(token, 94);
+                return;
+            }
+
+            case 130: {
+                // Shift 96.
+                token = doShift(token, 96);
+                return;
+            }
+
+            case 131: {
+                // Shift 97.
+                token = doShift(token, 97);
+                return;
+            }
+
+            case 132: {
+                // Shift 98.
+                token = doShift(token, 98);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 144.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action144() throws IOException {
+        switch (token.id) {
+            case 104: {
+                // Shift 115.
+                token = doShift(token, 115);
+                return;
+            }
+
+            case 108:
+            case 120: {
+                // Reduce ToolArgs : ToolArgs COMMATK IDENTIFIERTK EQTK Expression;
+                doReduce1(token, 21);
+                Object o5 = doReduce2();
+                doReduce2();
+                Object o3 = doReduce2();
+                doReduce2();
+                Object o1 = doReduce2();
+
+                List<ToolArgument> o = hooks.parseToolArgs4((List<ToolArgument>)o1, (Token)o3, (Expression)o5);
+
+                reduce = true;
+                reduceNonTerminal = 21;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 145.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action145() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 9: {
+                // Shift 84.
+                token = doShift(token, 84);
+                return;
+            }
+
+            case 19: {
+                // Shift 85.
+                token = doShift(token, 85);
+                return;
+            }
+
+            case 25: {
+                // Shift 86.
+                token = doShift(token, 86);
+                return;
+            }
+
+            case 103: {
+                // Shift 87.
+                token = doShift(token, 87);
+                return;
+            }
+
+            case 110: {
+                // Shift 88.
+                token = doShift(token, 88);
+                return;
+            }
+
+            case 117: {
+                // Shift 89.
+                token = doShift(token, 89);
+                return;
+            }
+
+            case 118: {
+                // Shift 90.
+                token = doShift(token, 90);
+                return;
+            }
+
+            case 121: {
+                // Shift 92.
+                token = doShift(token, 92);
+                return;
+            }
+
+            case 122: {
+                // Shift 93.
+                token = doShift(token, 93);
+                return;
+            }
+
+            case 127: {
+                // Shift 94.
+                token = doShift(token, 94);
+                return;
+            }
+
+            case 130: {
+                // Shift 96.
+                token = doShift(token, 96);
+                return;
+            }
+
+            case 131: {
+                // Shift 97.
+                token = doShift(token, 97);
+                return;
+            }
+
+            case 132: {
+                // Shift 98.
+                token = doShift(token, 98);
+                return;
+            }
+
+            case 107: {
+                // Reduce OptExpression : ;
+                doReduce1(token, 8);
+                Expression o = hooks.parseOptExpression1();
+
+                reduce = true;
+                reduceNonTerminal = 8;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 146.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action146() throws IOException {
+        switch (token.id) {
+            case 104: {
+                // Shift 115.
+                token = doShift(token, 115);
+                return;
+            }
+
+            case 126: {
+                // Shift 152.
+                token = doShift(token, 152);
+                return;
+            }
+
+            case 107: {
+                // Reduce OptExpression : Expression;
+                doReduce1(token, 8);
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseOptExpression2((Expression)o1);
+
+                reduce = true;
+                reduceNonTerminal = 8;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 147.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action147() throws IOException {
+        switch (token.id) {
+            case 107: {
+                // Shift 148.
+                token = doShift(token, 148);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 148.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action148() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 9: {
+                // Shift 84.
+                token = doShift(token, 84);
+                return;
+            }
+
+            case 19: {
+                // Shift 85.
+                token = doShift(token, 85);
+                return;
+            }
+
+            case 25: {
+                // Shift 86.
+                token = doShift(token, 86);
+                return;
+            }
+
+            case 103: {
+                // Shift 87.
+                token = doShift(token, 87);
+                return;
+            }
+
+            case 110: {
+                // Shift 88.
+                token = doShift(token, 88);
+                return;
+            }
+
+            case 117: {
+                // Shift 89.
+                token = doShift(token, 89);
+                return;
+            }
+
+            case 118: {
+                // Shift 90.
+                token = doShift(token, 90);
+                return;
+            }
+
+            case 121: {
+                // Shift 92.
+                token = doShift(token, 92);
+                return;
+            }
+
+            case 122: {
+                // Shift 93.
+                token = doShift(token, 93);
+                return;
+            }
+
+            case 127: {
+                // Shift 94.
+                token = doShift(token, 94);
+                return;
+            }
+
+            case 130: {
+                // Shift 96.
+                token = doShift(token, 96);
+                return;
+            }
+
+            case 131: {
+                // Shift 97.
+                token = doShift(token, 97);
+                return;
+            }
+
+            case 132: {
+                // Shift 98.
+                token = doShift(token, 98);
+                return;
+            }
+
+            case 126: {
+                // Reduce OptExpression : ;
+                doReduce1(token, 8);
+                Expression o = hooks.parseOptExpression1();
+
+                reduce = true;
+                reduceNonTerminal = 8;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 149.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action149() throws IOException {
+        switch (token.id) {
+            case 104: {
+                // Shift 115.
+                token = doShift(token, 115);
+                return;
+            }
+
+            case 126: {
+                // Reduce OptExpression : Expression;
+                doReduce1(token, 8);
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseOptExpression2((Expression)o1);
+
+                reduce = true;
+                reduceNonTerminal = 8;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 150.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action150() throws IOException {
+        switch (token.id) {
+            case 126: {
+                // Shift 151.
+                token = doShift(token, 151);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 151.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action151() throws IOException {
+        switch (token.id) {
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 125:
+            case 126:
+            case 127: {
+                // Reduce ProjExpression : ProjExpression SQOPENTK OptExpression COLONTK OptExpression SQCLOSETK;
+                doReduce1(token, 15);
+                doReduce2();
+                Object o5 = doReduce2();
+                doReduce2();
+                Object o3 = doReduce2();
+                Object o2 = doReduce2();
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseProjExpression3((Expression)o1, (Token)o2, (Expression)o3, (Expression)o5);
+
+                reduce = true;
+                reduceNonTerminal = 15;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 152.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action152() throws IOException {
+        switch (token.id) {
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 125:
+            case 126:
+            case 127: {
+                // Reduce ProjExpression : ProjExpression SQOPENTK Expression SQCLOSETK;
+                doReduce1(token, 15);
+                doReduce2();
+                Object o3 = doReduce2();
+                Object o2 = doReduce2();
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseProjExpression2((Expression)o1, (Token)o2, (Expression)o3);
+
+                reduce = true;
+                reduceNonTerminal = 15;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 153.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action153() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 9: {
+                // Shift 84.
+                token = doShift(token, 84);
+                return;
+            }
+
+            case 19: {
+                // Shift 85.
+                token = doShift(token, 85);
+                return;
+            }
+
+            case 25: {
+                // Shift 86.
+                token = doShift(token, 86);
+                return;
+            }
+
+            case 103: {
+                // Shift 87.
+                token = doShift(token, 87);
+                return;
+            }
+
+            case 110: {
+                // Shift 88.
+                token = doShift(token, 88);
+                return;
+            }
+
+            case 117: {
+                // Shift 89.
+                token = doShift(token, 89);
+                return;
+            }
+
+            case 118: {
+                // Shift 90.
+                token = doShift(token, 90);
+                return;
+            }
+
+            case 121: {
+                // Shift 92.
+                token = doShift(token, 92);
+                return;
+            }
+
+            case 122: {
+                // Shift 93.
+                token = doShift(token, 93);
+                return;
+            }
+
+            case 127: {
+                // Shift 94.
+                token = doShift(token, 94);
+                return;
+            }
+
+            case 130: {
+                // Shift 96.
+                token = doShift(token, 96);
+                return;
+            }
+
+            case 131: {
+                // Shift 97.
+                token = doShift(token, 97);
+                return;
+            }
+
+            case 132: {
+                // Shift 98.
+                token = doShift(token, 98);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 154.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action154() throws IOException {
+        switch (token.id) {
+            case 104: {
+                // Shift 115.
+                token = doShift(token, 115);
+                return;
+            }
+
+            case 108:
+            case 120: {
+                // Reduce ToolArgs : IDENTIFIERTK EQTK Expression;
+                doReduce1(token, 21);
+                Object o3 = doReduce2();
+                doReduce2();
+                Object o1 = doReduce2();
+
+                List<ToolArgument> o = hooks.parseToolArgs2((Token)o1, (Expression)o3);
+
+                reduce = true;
+                reduceNonTerminal = 21;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 155.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action155() throws IOException {
+        switch (token.id) {
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 125:
+            case 126:
+            case 127: {
+                // Reduce ExpressionFactor : SQOPENTK SQCLOSETK;
+                doReduce1(token, 16);
+                doReduce2();
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseExpressionFactor08((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 16;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 156.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action156() throws IOException {
+        switch (token.id) {
+            case 104: {
+                // Shift 115.
+                token = doShift(token, 115);
+                return;
+            }
+
+            case 108:
+            case 120:
+            case 126: {
+                // Reduce Expressions : Expression;
+                doReduce1(token, 7);
+                Object o1 = doReduce2();
+
+                List<Expression> o = hooks.parseExpressions1((Expression)o1);
+
+                reduce = true;
+                reduceNonTerminal = 7;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 157.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action157() throws IOException {
+        switch (token.id) {
+            case 108: {
+                // Shift 158.
+                token = doShift(token, 158);
+                return;
+            }
+
+            case 126: {
+                // Reduce OptComma : ;
+                doReduce1(token, 23);
+                Token o = hooks.parseOptComma1();
+
+                reduce = true;
+                reduceNonTerminal = 23;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 158.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action158() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 9: {
+                // Shift 84.
+                token = doShift(token, 84);
+                return;
+            }
+
+            case 19: {
+                // Shift 85.
+                token = doShift(token, 85);
+                return;
+            }
+
+            case 25: {
+                // Shift 86.
+                token = doShift(token, 86);
+                return;
+            }
+
+            case 103: {
+                // Shift 87.
+                token = doShift(token, 87);
+                return;
+            }
+
+            case 110: {
+                // Shift 88.
+                token = doShift(token, 88);
+                return;
+            }
+
+            case 117: {
+                // Shift 89.
+                token = doShift(token, 89);
+                return;
+            }
+
+            case 118: {
+                // Shift 90.
+                token = doShift(token, 90);
+                return;
+            }
+
+            case 121: {
+                // Shift 92.
+                token = doShift(token, 92);
+                return;
+            }
+
+            case 122: {
+                // Shift 93.
+                token = doShift(token, 93);
+                return;
+            }
+
+            case 127: {
+                // Shift 94.
+                token = doShift(token, 94);
+                return;
+            }
+
+            case 130: {
+                // Shift 96.
+                token = doShift(token, 96);
+                return;
+            }
+
+            case 131: {
+                // Shift 97.
+                token = doShift(token, 97);
+                return;
+            }
+
+            case 132: {
+                // Shift 98.
+                token = doShift(token, 98);
+                return;
+            }
+
+            case 109:
+            case 120:
+            case 126: {
+                // Reduce OptComma : COMMATK;
+                doReduce1(token, 23);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseOptComma2((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 23;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 159.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action159() throws IOException {
+        switch (token.id) {
+            case 126: {
+                // Shift 160.
+                token = doShift(token, 160);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 160.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action160() throws IOException {
+        switch (token.id) {
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 125:
+            case 126:
+            case 127: {
+                // Reduce ExpressionFactor : SQOPENTK Expressions OptComma SQCLOSETK;
+                doReduce1(token, 16);
+                doReduce2();
+                Object o3 = doReduce2();
+                Object o2 = doReduce2();
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseExpressionFactor09((Token)o1, (List<Expression>)o2, (Token)o3);
+
+                reduce = true;
+                reduceNonTerminal = 16;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 161.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action161() throws IOException {
+        switch (token.id) {
+            case 104: {
+                // Shift 115.
+                token = doShift(token, 115);
+                return;
+            }
+
+            case 108:
+            case 109:
+            case 120:
+            case 126: {
+                // Reduce Expressions : Expressions COMMATK Expression;
+                doReduce1(token, 7);
+                Object o3 = doReduce2();
+                doReduce2();
+                Object o1 = doReduce2();
+
+                List<Expression> o = hooks.parseExpressions2((List<Expression>)o1, (Expression)o3);
+
+                reduce = true;
+                reduceNonTerminal = 7;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 162.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action162() throws IOException {
+        switch (token.id) {
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 125:
+            case 126: {
+                // Reduce UnaryExpression : PLUSTK UnaryExpression;
+                doReduce1(token, 14);
+                Object o2 = doReduce2();
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseUnaryExpression3((Token)o1, (Expression)o2);
+
+                reduce = true;
+                reduceNonTerminal = 14;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 163.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action163() throws IOException {
+        switch (token.id) {
+            case 104: {
+                // Shift 115.
+                token = doShift(token, 115);
+                return;
+            }
+
+            case 108: {
+                // Shift 164.
+                token = doShift(token, 164);
+                return;
+            }
+
+            case 120: {
+                // Shift 165.
+                token = doShift(token, 165);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 164.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action164() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 9: {
+                // Shift 84.
+                token = doShift(token, 84);
+                return;
+            }
+
+            case 19: {
+                // Shift 85.
+                token = doShift(token, 85);
+                return;
+            }
+
+            case 25: {
+                // Shift 86.
+                token = doShift(token, 86);
+                return;
+            }
+
+            case 103: {
+                // Shift 87.
+                token = doShift(token, 87);
+                return;
+            }
+
+            case 110: {
+                // Shift 88.
+                token = doShift(token, 88);
+                return;
+            }
+
+            case 117: {
+                // Shift 89.
+                token = doShift(token, 89);
+                return;
+            }
+
+            case 118: {
+                // Shift 90.
+                token = doShift(token, 90);
+                return;
+            }
+
+            case 121: {
+                // Shift 92.
+                token = doShift(token, 92);
+                return;
+            }
+
+            case 122: {
+                // Shift 93.
+                token = doShift(token, 93);
+                return;
+            }
+
+            case 127: {
+                // Shift 94.
+                token = doShift(token, 94);
+                return;
+            }
+
+            case 130: {
+                // Shift 96.
+                token = doShift(token, 96);
+                return;
+            }
+
+            case 131: {
+                // Shift 97.
+                token = doShift(token, 97);
+                return;
+            }
+
+            case 132: {
+                // Shift 98.
+                token = doShift(token, 98);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 165.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action165() throws IOException {
+        switch (token.id) {
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 125:
+            case 126:
+            case 127: {
+                // Reduce ExpressionFactor : PAROPENTK Expression PARCLOSETK;
+                doReduce1(token, 16);
+                doReduce2();
+                Object o2 = doReduce2();
+                doReduce2();
+
+                Expression o = hooks.parseExpressionFactor14((Expression)o2);
+
+                reduce = true;
+                reduceNonTerminal = 16;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 166.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action166() throws IOException {
+        switch (token.id) {
+            case 108: {
+                // Shift 158.
+                token = doShift(token, 158);
+                return;
+            }
+
+            case 120: {
+                // Reduce OptComma : ;
+                doReduce1(token, 23);
+                Token o = hooks.parseOptComma1();
+
+                reduce = true;
+                reduceNonTerminal = 23;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 167.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action167() throws IOException {
+        switch (token.id) {
+            case 120: {
+                // Shift 168.
+                token = doShift(token, 168);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 168.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action168() throws IOException {
+        switch (token.id) {
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 125:
+            case 126:
+            case 127: {
+                // Reduce ExpressionFactor : PAROPENTK Expression COMMATK Expressions OptComma PARCLOSETK;
+                doReduce1(token, 16);
+                doReduce2();
+                Object o5 = doReduce2();
+                Object o4 = doReduce2();
+                doReduce2();
+                Object o2 = doReduce2();
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseExpressionFactor13((Token)o1, (Expression)o2, (List<Expression>)o4, (Token)o5);
+
+                reduce = true;
+                reduceNonTerminal = 16;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 169.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action169() throws IOException {
+        switch (token.id) {
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 125:
+            case 126: {
+                // Reduce UnaryExpression : MINUSTK UnaryExpression;
+                doReduce1(token, 14);
+                Object o2 = doReduce2();
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseUnaryExpression2((Token)o1, (Expression)o2);
+
+                reduce = true;
+                reduceNonTerminal = 14;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 170.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action170() throws IOException {
+        switch (token.id) {
+            case 123: {
+                // Shift 220.
+                token = doShift(token, 220);
+                return;
+            }
+
+            case 107:
+            case 108:
+            case 115:
+            case 120: {
+                // Reduce Type : BOOLKW;
+                doReduce1(token, 6);
+                Object o1 = doReduce2();
+
+                ToolDefType o = hooks.parseType01((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 6;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 171.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action171() throws IOException {
+        switch (token.id) {
+            case 123: {
+                // Shift 219.
+                token = doShift(token, 219);
+                return;
+            }
+
+            case 107:
+            case 108:
+            case 115:
+            case 120: {
+                // Reduce Type : DOUBLEKW;
+                doReduce1(token, 6);
+                Object o1 = doReduce2();
+
+                ToolDefType o = hooks.parseType07((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 6;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 172.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action172() throws IOException {
+        switch (token.id) {
+            case 123: {
+                // Shift 218.
+                token = doShift(token, 218);
+                return;
+            }
+
+            case 107:
+            case 108:
+            case 115:
+            case 120: {
+                // Reduce Type : INTKW;
+                doReduce1(token, 6);
+                Object o1 = doReduce2();
+
+                ToolDefType o = hooks.parseType03((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 6;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 173.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action173() throws IOException {
+        switch (token.id) {
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 1: {
+                // Shift 170.
+                token = doShift(token, 170);
+                return;
+            }
+
+            case 4: {
+                // Shift 171.
+                token = doShift(token, 171);
+                return;
+            }
+
+            case 15: {
+                // Shift 172.
+                token = doShift(token, 172);
+                return;
+            }
+
+            case 16: {
+                // Shift 173.
+                token = doShift(token, 173);
+                return;
+            }
+
+            case 17: {
+                // Shift 174.
+                token = doShift(token, 174);
+                return;
+            }
+
+            case 18: {
+                // Shift 175.
+                token = doShift(token, 175);
+                return;
+            }
+
+            case 20: {
+                // Shift 176.
+                token = doShift(token, 176);
+                return;
+            }
+
+            case 22: {
+                // Shift 177.
+                token = doShift(token, 177);
+                return;
+            }
+
+            case 23: {
+                // Shift 178.
+                token = doShift(token, 178);
+                return;
+            }
+
+            case 26: {
+                // Shift 179.
+                token = doShift(token, 179);
+                return;
+            }
+
+            case 123: {
+                // Shift 215.
+                token = doShift(token, 215);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 174.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action174() throws IOException {
+        switch (token.id) {
+            case 123: {
+                // Shift 214.
+                token = doShift(token, 214);
+                return;
+            }
+
+            case 107:
+            case 108:
+            case 115:
+            case 120: {
+                // Reduce Type : LONGKW;
+                doReduce1(token, 6);
+                Object o1 = doReduce2();
+
+                ToolDefType o = hooks.parseType05((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 6;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 175.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action175() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Shift 203.
+                token = doShift(token, 203);
+                return;
+            }
+
+            case 123: {
+                // Shift 204.
+                token = doShift(token, 204);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 176.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action176() throws IOException {
+        switch (token.id) {
+            case 123: {
+                // Shift 202.
+                token = doShift(token, 202);
+                return;
+            }
+
+            case 107:
+            case 108:
+            case 115:
+            case 120: {
+                // Reduce Type : OBJECTKW;
+                doReduce1(token, 6);
+                Object o1 = doReduce2();
+
+                ToolDefType o = hooks.parseType19((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 6;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 177.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action177() throws IOException {
+        switch (token.id) {
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 1: {
+                // Shift 170.
+                token = doShift(token, 170);
+                return;
+            }
+
+            case 4: {
+                // Shift 171.
+                token = doShift(token, 171);
+                return;
+            }
+
+            case 15: {
+                // Shift 172.
+                token = doShift(token, 172);
+                return;
+            }
+
+            case 16: {
+                // Shift 173.
+                token = doShift(token, 173);
+                return;
+            }
+
+            case 17: {
+                // Shift 174.
+                token = doShift(token, 174);
+                return;
+            }
+
+            case 18: {
+                // Shift 175.
+                token = doShift(token, 175);
+                return;
+            }
+
+            case 20: {
+                // Shift 176.
+                token = doShift(token, 176);
+                return;
+            }
+
+            case 22: {
+                // Shift 177.
+                token = doShift(token, 177);
+                return;
+            }
+
+            case 23: {
+                // Shift 178.
+                token = doShift(token, 178);
+                return;
+            }
+
+            case 26: {
+                // Shift 179.
+                token = doShift(token, 179);
+                return;
+            }
+
+            case 123: {
+                // Shift 199.
+                token = doShift(token, 199);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 178.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action178() throws IOException {
+        switch (token.id) {
+            case 123: {
+                // Shift 198.
+                token = doShift(token, 198);
+                return;
+            }
+
+            case 107:
+            case 108:
+            case 115:
+            case 120: {
+                // Reduce Type : STRINGKW;
+                doReduce1(token, 6);
+                Object o1 = doReduce2();
+
+                ToolDefType o = hooks.parseType09((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 6;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 179.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action179() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Shift 184.
+                token = doShift(token, 184);
+                return;
+            }
+
+            case 123: {
+                // Shift 185.
+                token = doShift(token, 185);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 180.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action180() throws IOException {
+        switch (token.id) {
+            case 107:
+            case 108:
+            case 115:
+            case 120: {
+                // Reduce Type : Name;
+                doReduce1(token, 6);
+                Object o1 = doReduce2();
+
+                ToolDefType o = hooks.parseType21((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 6;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 181.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action181() throws IOException {
+        switch (token.id) {
+            case 115: {
+                // Shift 182.
+                token = doShift(token, 182);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 182.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action182() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 9: {
+                // Shift 84.
+                token = doShift(token, 84);
+                return;
+            }
+
+            case 19: {
+                // Shift 85.
+                token = doShift(token, 85);
+                return;
+            }
+
+            case 25: {
+                // Shift 86.
+                token = doShift(token, 86);
+                return;
+            }
+
+            case 110: {
+                // Shift 88.
+                token = doShift(token, 88);
+                return;
+            }
+
+            case 117: {
+                // Shift 89.
+                token = doShift(token, 89);
+                return;
+            }
+
+            case 121: {
+                // Shift 92.
+                token = doShift(token, 92);
+                return;
+            }
+
+            case 127: {
+                // Shift 94.
+                token = doShift(token, 94);
+                return;
+            }
+
+            case 130: {
+                // Shift 96.
+                token = doShift(token, 96);
+                return;
+            }
+
+            case 131: {
+                // Shift 97.
+                token = doShift(token, 97);
+                return;
+            }
+
+            case 132: {
+                // Shift 98.
+                token = doShift(token, 98);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 183.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action183() throws IOException {
+        switch (token.id) {
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 125:
+            case 126:
+            case 127: {
+                // Reduce ExpressionFactor : LTTK Type GTTK ExpressionFactor;
+                doReduce1(token, 16);
+                Object o4 = doReduce2();
+                doReduce2();
+                Object o2 = doReduce2();
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseExpressionFactor07((Token)o1, (ToolDefType)o2, (Expression)o4);
+
+                reduce = true;
+                reduceNonTerminal = 16;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 184.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action184() throws IOException {
+        switch (token.id) {
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 1: {
+                // Shift 170.
+                token = doShift(token, 170);
+                return;
+            }
+
+            case 4: {
+                // Shift 171.
+                token = doShift(token, 171);
+                return;
+            }
+
+            case 15: {
+                // Shift 172.
+                token = doShift(token, 172);
+                return;
+            }
+
+            case 16: {
+                // Shift 173.
+                token = doShift(token, 173);
+                return;
+            }
+
+            case 17: {
+                // Shift 174.
+                token = doShift(token, 174);
+                return;
+            }
+
+            case 18: {
+                // Shift 175.
+                token = doShift(token, 175);
+                return;
+            }
+
+            case 20: {
+                // Shift 176.
+                token = doShift(token, 176);
+                return;
+            }
+
+            case 22: {
+                // Shift 177.
+                token = doShift(token, 177);
+                return;
+            }
+
+            case 23: {
+                // Shift 178.
+                token = doShift(token, 178);
+                return;
+            }
+
+            case 26: {
+                // Shift 179.
+                token = doShift(token, 179);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 185.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action185() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Shift 186.
+                token = doShift(token, 186);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 186.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action186() throws IOException {
+        switch (token.id) {
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 1: {
+                // Shift 170.
+                token = doShift(token, 170);
+                return;
+            }
+
+            case 4: {
+                // Shift 171.
+                token = doShift(token, 171);
+                return;
+            }
+
+            case 15: {
+                // Shift 172.
+                token = doShift(token, 172);
+                return;
+            }
+
+            case 16: {
+                // Shift 173.
+                token = doShift(token, 173);
+                return;
+            }
+
+            case 17: {
+                // Shift 174.
+                token = doShift(token, 174);
+                return;
+            }
+
+            case 18: {
+                // Shift 175.
+                token = doShift(token, 175);
+                return;
+            }
+
+            case 20: {
+                // Shift 176.
+                token = doShift(token, 176);
+                return;
+            }
+
+            case 22: {
+                // Shift 177.
+                token = doShift(token, 177);
+                return;
+            }
+
+            case 23: {
+                // Shift 178.
+                token = doShift(token, 178);
+                return;
+            }
+
+            case 26: {
+                // Shift 179.
+                token = doShift(token, 179);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 187.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action187() throws IOException {
+        switch (token.id) {
+            case 108: {
+                // Shift 188.
+                token = doShift(token, 188);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 188.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action188() throws IOException {
+        switch (token.id) {
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 1: {
+                // Shift 170.
+                token = doShift(token, 170);
+                return;
+            }
+
+            case 4: {
+                // Shift 171.
+                token = doShift(token, 171);
+                return;
+            }
+
+            case 15: {
+                // Shift 172.
+                token = doShift(token, 172);
+                return;
+            }
+
+            case 16: {
+                // Shift 173.
+                token = doShift(token, 173);
+                return;
+            }
+
+            case 17: {
+                // Shift 174.
+                token = doShift(token, 174);
+                return;
+            }
+
+            case 18: {
+                // Shift 175.
+                token = doShift(token, 175);
+                return;
+            }
+
+            case 20: {
+                // Shift 176.
+                token = doShift(token, 176);
+                return;
+            }
+
+            case 22: {
+                // Shift 177.
+                token = doShift(token, 177);
+                return;
+            }
+
+            case 23: {
+                // Shift 178.
+                token = doShift(token, 178);
+                return;
+            }
+
+            case 26: {
+                // Shift 179.
+                token = doShift(token, 179);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 189.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action189() throws IOException {
+        switch (token.id) {
+            case 108:
+            case 120: {
+                // Reduce Types : Type;
+                doReduce1(token, 5);
+                Object o1 = doReduce2();
+
+                List<ToolDefType> o = hooks.parseTypes1((ToolDefType)o1);
+
+                reduce = true;
+                reduceNonTerminal = 5;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 190.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action190() throws IOException {
+        switch (token.id) {
+            case 108: {
+                // Shift 191.
+                token = doShift(token, 191);
+                return;
+            }
+
+            case 120: {
+                // Shift 192.
+                token = doShift(token, 192);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 191.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action191() throws IOException {
+        switch (token.id) {
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 1: {
+                // Shift 170.
+                token = doShift(token, 170);
+                return;
+            }
+
+            case 4: {
+                // Shift 171.
+                token = doShift(token, 171);
+                return;
+            }
+
+            case 15: {
+                // Shift 172.
+                token = doShift(token, 172);
+                return;
+            }
+
+            case 16: {
+                // Shift 173.
+                token = doShift(token, 173);
+                return;
+            }
+
+            case 17: {
+                // Shift 174.
+                token = doShift(token, 174);
+                return;
+            }
+
+            case 18: {
+                // Shift 175.
+                token = doShift(token, 175);
+                return;
+            }
+
+            case 20: {
+                // Shift 176.
+                token = doShift(token, 176);
+                return;
+            }
+
+            case 22: {
+                // Shift 177.
+                token = doShift(token, 177);
+                return;
+            }
+
+            case 23: {
+                // Shift 178.
+                token = doShift(token, 178);
+                return;
+            }
+
+            case 26: {
+                // Shift 179.
+                token = doShift(token, 179);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 192.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action192() throws IOException {
+        switch (token.id) {
+            case 107:
+            case 108:
+            case 115:
+            case 120: {
+                // Reduce Type : TUPLEKW QUESTIONTK PAROPENTK Type COMMATK Types PARCLOSETK;
+                doReduce1(token, 6);
+                doReduce2();
+                Object o6 = doReduce2();
+                doReduce2();
+                Object o4 = doReduce2();
+                doReduce2();
+                doReduce2();
+                Object o1 = doReduce2();
+
+                ToolDefType o = hooks.parseType18((Token)o1, (ToolDefType)o4, (List<ToolDefType>)o6);
+
+                reduce = true;
+                reduceNonTerminal = 6;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 193.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action193() throws IOException {
+        switch (token.id) {
+            case 108:
+            case 120: {
+                // Reduce Types : Types COMMATK Type;
+                doReduce1(token, 5);
+                Object o3 = doReduce2();
+                doReduce2();
+                Object o1 = doReduce2();
+
+                List<ToolDefType> o = hooks.parseTypes2((List<ToolDefType>)o1, (ToolDefType)o3);
+
+                reduce = true;
+                reduceNonTerminal = 5;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 194.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action194() throws IOException {
+        switch (token.id) {
+            case 108: {
+                // Shift 195.
+                token = doShift(token, 195);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 195.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action195() throws IOException {
+        switch (token.id) {
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 1: {
+                // Shift 170.
+                token = doShift(token, 170);
+                return;
+            }
+
+            case 4: {
+                // Shift 171.
+                token = doShift(token, 171);
+                return;
+            }
+
+            case 15: {
+                // Shift 172.
+                token = doShift(token, 172);
+                return;
+            }
+
+            case 16: {
+                // Shift 173.
+                token = doShift(token, 173);
+                return;
+            }
+
+            case 17: {
+                // Shift 174.
+                token = doShift(token, 174);
+                return;
+            }
+
+            case 18: {
+                // Shift 175.
+                token = doShift(token, 175);
+                return;
+            }
+
+            case 20: {
+                // Shift 176.
+                token = doShift(token, 176);
+                return;
+            }
+
+            case 22: {
+                // Shift 177.
+                token = doShift(token, 177);
+                return;
+            }
+
+            case 23: {
+                // Shift 178.
+                token = doShift(token, 178);
+                return;
+            }
+
+            case 26: {
+                // Shift 179.
+                token = doShift(token, 179);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 196.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action196() throws IOException {
+        switch (token.id) {
+            case 108: {
+                // Shift 191.
+                token = doShift(token, 191);
+                return;
+            }
+
+            case 120: {
+                // Shift 197.
+                token = doShift(token, 197);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 197.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action197() throws IOException {
+        switch (token.id) {
+            case 107:
+            case 108:
+            case 115:
+            case 120: {
+                // Reduce Type : TUPLEKW PAROPENTK Type COMMATK Types PARCLOSETK;
+                doReduce1(token, 6);
+                doReduce2();
+                Object o5 = doReduce2();
+                doReduce2();
+                Object o3 = doReduce2();
+                doReduce2();
+                Object o1 = doReduce2();
+
+                ToolDefType o = hooks.parseType17((Token)o1, (ToolDefType)o3, (List<ToolDefType>)o5);
+
+                reduce = true;
+                reduceNonTerminal = 6;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 198.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action198() throws IOException {
+        switch (token.id) {
+            case 107:
+            case 108:
+            case 115:
+            case 120: {
+                // Reduce Type : STRINGKW QUESTIONTK;
+                doReduce1(token, 6);
+                doReduce2();
+                Object o1 = doReduce2();
+
+                ToolDefType o = hooks.parseType10((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 6;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 199.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action199() throws IOException {
+        switch (token.id) {
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 1: {
+                // Shift 170.
+                token = doShift(token, 170);
+                return;
+            }
+
+            case 4: {
+                // Shift 171.
+                token = doShift(token, 171);
+                return;
+            }
+
+            case 15: {
+                // Shift 172.
+                token = doShift(token, 172);
+                return;
+            }
+
+            case 16: {
+                // Shift 173.
+                token = doShift(token, 173);
+                return;
+            }
+
+            case 17: {
+                // Shift 174.
+                token = doShift(token, 174);
+                return;
+            }
+
+            case 18: {
+                // Shift 175.
+                token = doShift(token, 175);
+                return;
+            }
+
+            case 20: {
+                // Shift 176.
+                token = doShift(token, 176);
+                return;
+            }
+
+            case 22: {
+                // Shift 177.
+                token = doShift(token, 177);
+                return;
+            }
+
+            case 23: {
+                // Shift 178.
+                token = doShift(token, 178);
+                return;
+            }
+
+            case 26: {
+                // Shift 179.
+                token = doShift(token, 179);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 200.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action200() throws IOException {
+        switch (token.id) {
+            case 107:
+            case 108:
+            case 115:
+            case 120: {
+                // Reduce Type : SETKW Type;
+                doReduce1(token, 6);
+                Object o2 = doReduce2();
+                Object o1 = doReduce2();
+
+                ToolDefType o = hooks.parseType13((Token)o1, (ToolDefType)o2);
+
+                reduce = true;
+                reduceNonTerminal = 6;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 201.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action201() throws IOException {
+        switch (token.id) {
+            case 107:
+            case 108:
+            case 115:
+            case 120: {
+                // Reduce Type : SETKW QUESTIONTK Type;
+                doReduce1(token, 6);
+                Object o3 = doReduce2();
+                doReduce2();
+                Object o1 = doReduce2();
+
+                ToolDefType o = hooks.parseType14((Token)o1, (ToolDefType)o3);
+
+                reduce = true;
+                reduceNonTerminal = 6;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 202.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action202() throws IOException {
+        switch (token.id) {
+            case 107:
+            case 108:
+            case 115:
+            case 120: {
+                // Reduce Type : OBJECTKW QUESTIONTK;
+                doReduce1(token, 6);
+                doReduce2();
+                Object o1 = doReduce2();
+
+                ToolDefType o = hooks.parseType20((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 6;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 203.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action203() throws IOException {
+        switch (token.id) {
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 1: {
+                // Shift 170.
+                token = doShift(token, 170);
+                return;
+            }
+
+            case 4: {
+                // Shift 171.
+                token = doShift(token, 171);
+                return;
+            }
+
+            case 15: {
+                // Shift 172.
+                token = doShift(token, 172);
+                return;
+            }
+
+            case 16: {
+                // Shift 173.
+                token = doShift(token, 173);
+                return;
+            }
+
+            case 17: {
+                // Shift 174.
+                token = doShift(token, 174);
+                return;
+            }
+
+            case 18: {
+                // Shift 175.
+                token = doShift(token, 175);
+                return;
+            }
+
+            case 20: {
+                // Shift 176.
+                token = doShift(token, 176);
+                return;
+            }
+
+            case 22: {
+                // Shift 177.
+                token = doShift(token, 177);
+                return;
+            }
+
+            case 23: {
+                // Shift 178.
+                token = doShift(token, 178);
+                return;
+            }
+
+            case 26: {
+                // Shift 179.
+                token = doShift(token, 179);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 204.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action204() throws IOException {
+        switch (token.id) {
+            case 121: {
+                // Shift 205.
+                token = doShift(token, 205);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 205.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action205() throws IOException {
+        switch (token.id) {
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 1: {
+                // Shift 170.
+                token = doShift(token, 170);
+                return;
+            }
+
+            case 4: {
+                // Shift 171.
+                token = doShift(token, 171);
+                return;
+            }
+
+            case 15: {
+                // Shift 172.
+                token = doShift(token, 172);
+                return;
+            }
+
+            case 16: {
+                // Shift 173.
+                token = doShift(token, 173);
+                return;
+            }
+
+            case 17: {
+                // Shift 174.
+                token = doShift(token, 174);
+                return;
+            }
+
+            case 18: {
+                // Shift 175.
+                token = doShift(token, 175);
+                return;
+            }
+
+            case 20: {
+                // Shift 176.
+                token = doShift(token, 176);
+                return;
+            }
+
+            case 22: {
+                // Shift 177.
+                token = doShift(token, 177);
+                return;
+            }
+
+            case 23: {
+                // Shift 178.
+                token = doShift(token, 178);
+                return;
+            }
+
+            case 26: {
+                // Shift 179.
+                token = doShift(token, 179);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 206.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action206() throws IOException {
+        switch (token.id) {
+            case 107: {
+                // Shift 207.
+                token = doShift(token, 207);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 207.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action207() throws IOException {
+        switch (token.id) {
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 1: {
+                // Shift 170.
+                token = doShift(token, 170);
+                return;
+            }
+
+            case 4: {
+                // Shift 171.
+                token = doShift(token, 171);
+                return;
+            }
+
+            case 15: {
+                // Shift 172.
+                token = doShift(token, 172);
+                return;
+            }
+
+            case 16: {
+                // Shift 173.
+                token = doShift(token, 173);
+                return;
+            }
+
+            case 17: {
+                // Shift 174.
+                token = doShift(token, 174);
+                return;
+            }
+
+            case 18: {
+                // Shift 175.
+                token = doShift(token, 175);
+                return;
+            }
+
+            case 20: {
+                // Shift 176.
+                token = doShift(token, 176);
+                return;
+            }
+
+            case 22: {
+                // Shift 177.
+                token = doShift(token, 177);
+                return;
+            }
+
+            case 23: {
+                // Shift 178.
+                token = doShift(token, 178);
+                return;
+            }
+
+            case 26: {
+                // Shift 179.
+                token = doShift(token, 179);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 208.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action208() throws IOException {
+        switch (token.id) {
+            case 120: {
+                // Shift 209.
+                token = doShift(token, 209);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 209.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action209() throws IOException {
+        switch (token.id) {
+            case 107:
+            case 108:
+            case 115:
+            case 120: {
+                // Reduce Type : MAPKW QUESTIONTK PAROPENTK Type COLONTK Type PARCLOSETK;
+                doReduce1(token, 6);
+                doReduce2();
+                Object o6 = doReduce2();
+                doReduce2();
+                Object o4 = doReduce2();
+                doReduce2();
+                doReduce2();
+                Object o1 = doReduce2();
+
+                ToolDefType o = hooks.parseType16((Token)o1, (ToolDefType)o4, (ToolDefType)o6);
+
+                reduce = true;
+                reduceNonTerminal = 6;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 210.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action210() throws IOException {
+        switch (token.id) {
+            case 107: {
+                // Shift 211.
+                token = doShift(token, 211);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 211.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action211() throws IOException {
+        switch (token.id) {
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 1: {
+                // Shift 170.
+                token = doShift(token, 170);
+                return;
+            }
+
+            case 4: {
+                // Shift 171.
+                token = doShift(token, 171);
+                return;
+            }
+
+            case 15: {
+                // Shift 172.
+                token = doShift(token, 172);
+                return;
+            }
+
+            case 16: {
+                // Shift 173.
+                token = doShift(token, 173);
+                return;
+            }
+
+            case 17: {
+                // Shift 174.
+                token = doShift(token, 174);
+                return;
+            }
+
+            case 18: {
+                // Shift 175.
+                token = doShift(token, 175);
+                return;
+            }
+
+            case 20: {
+                // Shift 176.
+                token = doShift(token, 176);
+                return;
+            }
+
+            case 22: {
+                // Shift 177.
+                token = doShift(token, 177);
+                return;
+            }
+
+            case 23: {
+                // Shift 178.
+                token = doShift(token, 178);
+                return;
+            }
+
+            case 26: {
+                // Shift 179.
+                token = doShift(token, 179);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 212.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action212() throws IOException {
+        switch (token.id) {
+            case 120: {
+                // Shift 213.
+                token = doShift(token, 213);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 213.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action213() throws IOException {
+        switch (token.id) {
+            case 107:
+            case 108:
+            case 115:
+            case 120: {
+                // Reduce Type : MAPKW PAROPENTK Type COLONTK Type PARCLOSETK;
+                doReduce1(token, 6);
+                doReduce2();
+                Object o5 = doReduce2();
+                doReduce2();
+                Object o3 = doReduce2();
+                doReduce2();
+                Object o1 = doReduce2();
+
+                ToolDefType o = hooks.parseType15((Token)o1, (ToolDefType)o3, (ToolDefType)o5);
+
+                reduce = true;
+                reduceNonTerminal = 6;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 214.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action214() throws IOException {
+        switch (token.id) {
+            case 107:
+            case 108:
+            case 115:
+            case 120: {
+                // Reduce Type : LONGKW QUESTIONTK;
+                doReduce1(token, 6);
+                doReduce2();
+                Object o1 = doReduce2();
+
+                ToolDefType o = hooks.parseType06((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 6;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 215.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action215() throws IOException {
+        switch (token.id) {
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 1: {
+                // Shift 170.
+                token = doShift(token, 170);
+                return;
+            }
+
+            case 4: {
+                // Shift 171.
+                token = doShift(token, 171);
+                return;
+            }
+
+            case 15: {
+                // Shift 172.
+                token = doShift(token, 172);
+                return;
+            }
+
+            case 16: {
+                // Shift 173.
+                token = doShift(token, 173);
+                return;
+            }
+
+            case 17: {
+                // Shift 174.
+                token = doShift(token, 174);
+                return;
+            }
+
+            case 18: {
+                // Shift 175.
+                token = doShift(token, 175);
+                return;
+            }
+
+            case 20: {
+                // Shift 176.
+                token = doShift(token, 176);
+                return;
+            }
+
+            case 22: {
+                // Shift 177.
+                token = doShift(token, 177);
+                return;
+            }
+
+            case 23: {
+                // Shift 178.
+                token = doShift(token, 178);
+                return;
+            }
+
+            case 26: {
+                // Shift 179.
+                token = doShift(token, 179);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 216.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action216() throws IOException {
+        switch (token.id) {
+            case 107:
+            case 108:
+            case 115:
+            case 120: {
+                // Reduce Type : LISTKW Type;
+                doReduce1(token, 6);
+                Object o2 = doReduce2();
+                Object o1 = doReduce2();
+
+                ToolDefType o = hooks.parseType11((Token)o1, (ToolDefType)o2);
+
+                reduce = true;
+                reduceNonTerminal = 6;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 217.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action217() throws IOException {
+        switch (token.id) {
+            case 107:
+            case 108:
+            case 115:
+            case 120: {
+                // Reduce Type : LISTKW QUESTIONTK Type;
+                doReduce1(token, 6);
+                Object o3 = doReduce2();
+                doReduce2();
+                Object o1 = doReduce2();
+
+                ToolDefType o = hooks.parseType12((Token)o1, (ToolDefType)o3);
+
+                reduce = true;
+                reduceNonTerminal = 6;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 218.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action218() throws IOException {
+        switch (token.id) {
+            case 107:
+            case 108:
+            case 115:
+            case 120: {
+                // Reduce Type : INTKW QUESTIONTK;
+                doReduce1(token, 6);
+                doReduce2();
+                Object o1 = doReduce2();
+
+                ToolDefType o = hooks.parseType04((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 6;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 219.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action219() throws IOException {
+        switch (token.id) {
+            case 107:
+            case 108:
+            case 115:
+            case 120: {
+                // Reduce Type : DOUBLEKW QUESTIONTK;
+                doReduce1(token, 6);
+                doReduce2();
+                Object o1 = doReduce2();
+
+                ToolDefType o = hooks.parseType08((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 6;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 220.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action220() throws IOException {
+        switch (token.id) {
+            case 107:
+            case 108:
+            case 115:
+            case 120: {
+                // Reduce Type : BOOLKW QUESTIONTK;
+                doReduce1(token, 6);
+                doReduce2();
+                Object o1 = doReduce2();
+
+                ToolDefType o = hooks.parseType02((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 6;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 221.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action221() throws IOException {
+        switch (token.id) {
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 125:
+            case 126:
+            case 127: {
+                // Reduce ExpressionFactor : CUROPENTK CURCLOSETK;
+                doReduce1(token, 16);
+                doReduce2();
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseExpressionFactor10((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 16;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 222.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action222() throws IOException {
+        switch (token.id) {
+            case 104: {
+                // Shift 115.
+                token = doShift(token, 115);
+                return;
+            }
+
+            case 107: {
+                // Shift 233.
+                token = doShift(token, 233);
+                return;
+            }
+
+            case 108:
+            case 109: {
+                // Reduce Expressions : Expression;
+                doReduce1(token, 7);
+                Object o1 = doReduce2();
+
+                List<Expression> o = hooks.parseExpressions1((Expression)o1);
+
+                reduce = true;
+                reduceNonTerminal = 7;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 223.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action223() throws IOException {
+        switch (token.id) {
+            case 108: {
+                // Shift 158.
+                token = doShift(token, 158);
+                return;
+            }
+
+            case 109: {
+                // Reduce OptComma : ;
+                doReduce1(token, 23);
+                Token o = hooks.parseOptComma1();
+
+                reduce = true;
+                reduceNonTerminal = 23;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 224.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action224() throws IOException {
+        switch (token.id) {
+            case 108: {
+                // Shift 225.
+                token = doShift(token, 225);
+                return;
+            }
+
+            case 109: {
+                // Reduce OptComma : ;
+                doReduce1(token, 23);
+                Token o = hooks.parseOptComma1();
+
+                reduce = true;
+                reduceNonTerminal = 23;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 225.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action225() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 9: {
+                // Shift 84.
+                token = doShift(token, 84);
+                return;
+            }
+
+            case 19: {
+                // Shift 85.
+                token = doShift(token, 85);
+                return;
+            }
+
+            case 25: {
+                // Shift 86.
+                token = doShift(token, 86);
+                return;
+            }
+
+            case 103: {
+                // Shift 87.
+                token = doShift(token, 87);
+                return;
+            }
+
+            case 110: {
+                // Shift 88.
+                token = doShift(token, 88);
+                return;
+            }
+
+            case 117: {
+                // Shift 89.
+                token = doShift(token, 89);
+                return;
+            }
+
+            case 118: {
+                // Shift 90.
+                token = doShift(token, 90);
+                return;
+            }
+
+            case 121: {
+                // Shift 92.
+                token = doShift(token, 92);
+                return;
+            }
+
+            case 122: {
+                // Shift 93.
+                token = doShift(token, 93);
+                return;
+            }
+
+            case 127: {
+                // Shift 94.
+                token = doShift(token, 94);
+                return;
+            }
+
+            case 130: {
+                // Shift 96.
+                token = doShift(token, 96);
+                return;
+            }
+
+            case 131: {
+                // Shift 97.
+                token = doShift(token, 97);
+                return;
+            }
+
+            case 132: {
+                // Shift 98.
+                token = doShift(token, 98);
+                return;
+            }
+
+            case 109: {
+                // Reduce OptComma : COMMATK;
+                doReduce1(token, 23);
+                Object o1 = doReduce2();
+
+                Token o = hooks.parseOptComma2((Token)o1);
+
+                reduce = true;
+                reduceNonTerminal = 23;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 226.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action226() throws IOException {
+        switch (token.id) {
+            case 109: {
+                // Shift 227.
+                token = doShift(token, 227);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 227.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action227() throws IOException {
+        switch (token.id) {
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 125:
+            case 126:
+            case 127: {
+                // Reduce ExpressionFactor : CUROPENTK MapEntries OptComma CURCLOSETK;
+                doReduce1(token, 16);
+                doReduce2();
+                Object o3 = doReduce2();
+                Object o2 = doReduce2();
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseExpressionFactor12((Token)o1, (List<MapEntry>)o2, (Token)o3);
+
+                reduce = true;
+                reduceNonTerminal = 16;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 228.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action228() throws IOException {
+        switch (token.id) {
+            case 104: {
+                // Shift 115.
+                token = doShift(token, 115);
+                return;
+            }
+
+            case 107: {
+                // Shift 229.
+                token = doShift(token, 229);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 229.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action229() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 9: {
+                // Shift 84.
+                token = doShift(token, 84);
+                return;
+            }
+
+            case 19: {
+                // Shift 85.
+                token = doShift(token, 85);
+                return;
+            }
+
+            case 25: {
+                // Shift 86.
+                token = doShift(token, 86);
+                return;
+            }
+
+            case 103: {
+                // Shift 87.
+                token = doShift(token, 87);
+                return;
+            }
+
+            case 110: {
+                // Shift 88.
+                token = doShift(token, 88);
+                return;
+            }
+
+            case 117: {
+                // Shift 89.
+                token = doShift(token, 89);
+                return;
+            }
+
+            case 118: {
+                // Shift 90.
+                token = doShift(token, 90);
+                return;
+            }
+
+            case 121: {
+                // Shift 92.
+                token = doShift(token, 92);
+                return;
+            }
+
+            case 122: {
+                // Shift 93.
+                token = doShift(token, 93);
+                return;
+            }
+
+            case 127: {
+                // Shift 94.
+                token = doShift(token, 94);
+                return;
+            }
+
+            case 130: {
+                // Shift 96.
+                token = doShift(token, 96);
+                return;
+            }
+
+            case 131: {
+                // Shift 97.
+                token = doShift(token, 97);
+                return;
+            }
+
+            case 132: {
+                // Shift 98.
+                token = doShift(token, 98);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 230.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action230() throws IOException {
+        switch (token.id) {
+            case 104: {
+                // Shift 115.
+                token = doShift(token, 115);
+                return;
+            }
+
+            case 108:
+            case 109: {
+                // Reduce MapEntries : MapEntries COMMATK Expression COLONTK Expression;
+                doReduce1(token, 17);
+                Object o5 = doReduce2();
+                Object o4 = doReduce2();
+                Object o3 = doReduce2();
+                doReduce2();
+                Object o1 = doReduce2();
+
+                List<MapEntry> o = hooks.parseMapEntries2((List<MapEntry>)o1, (Expression)o3, (Token)o4, (Expression)o5);
+
+                reduce = true;
+                reduceNonTerminal = 17;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 231.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action231() throws IOException {
+        switch (token.id) {
+            case 109: {
+                // Shift 232.
+                token = doShift(token, 232);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 232.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action232() throws IOException {
+        switch (token.id) {
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 125:
+            case 126:
+            case 127: {
+                // Reduce ExpressionFactor : CUROPENTK Expressions OptComma CURCLOSETK;
+                doReduce1(token, 16);
+                doReduce2();
+                Object o3 = doReduce2();
+                Object o2 = doReduce2();
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseExpressionFactor11((Token)o1, (List<Expression>)o2, (Token)o3);
+
+                reduce = true;
+                reduceNonTerminal = 16;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 233.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action233() throws IOException {
+        switch (token.id) {
+            case 29: {
+                // Shift 1.
+                token = doShift(token, 1);
+                return;
+            }
+
+            case 30: {
+                // Shift 2.
+                token = doShift(token, 2);
+                return;
+            }
+
+            case 31: {
+                // Shift 3.
+                token = doShift(token, 3);
+                return;
+            }
+
+            case 32: {
+                // Shift 4.
+                token = doShift(token, 4);
+                return;
+            }
+
+            case 33: {
+                // Shift 5.
+                token = doShift(token, 5);
+                return;
+            }
+
+            case 34: {
+                // Shift 6.
+                token = doShift(token, 6);
+                return;
+            }
+
+            case 35: {
+                // Shift 7.
+                token = doShift(token, 7);
+                return;
+            }
+
+            case 36: {
+                // Shift 8.
+                token = doShift(token, 8);
+                return;
+            }
+
+            case 37: {
+                // Shift 9.
+                token = doShift(token, 9);
+                return;
+            }
+
+            case 38: {
+                // Shift 10.
+                token = doShift(token, 10);
+                return;
+            }
+
+            case 39: {
+                // Shift 11.
+                token = doShift(token, 11);
+                return;
+            }
+
+            case 40: {
+                // Shift 12.
+                token = doShift(token, 12);
+                return;
+            }
+
+            case 41: {
+                // Shift 13.
+                token = doShift(token, 13);
+                return;
+            }
+
+            case 42: {
+                // Shift 14.
+                token = doShift(token, 14);
+                return;
+            }
+
+            case 43: {
+                // Shift 15.
+                token = doShift(token, 15);
+                return;
+            }
+
+            case 44: {
+                // Shift 16.
+                token = doShift(token, 16);
+                return;
+            }
+
+            case 45: {
+                // Shift 17.
+                token = doShift(token, 17);
+                return;
+            }
+
+            case 46: {
+                // Shift 18.
+                token = doShift(token, 18);
+                return;
+            }
+
+            case 47: {
+                // Shift 19.
+                token = doShift(token, 19);
+                return;
+            }
+
+            case 48: {
+                // Shift 20.
+                token = doShift(token, 20);
+                return;
+            }
+
+            case 49: {
+                // Shift 21.
+                token = doShift(token, 21);
+                return;
+            }
+
+            case 50: {
+                // Shift 22.
+                token = doShift(token, 22);
+                return;
+            }
+
+            case 51: {
+                // Shift 23.
+                token = doShift(token, 23);
+                return;
+            }
+
+            case 52: {
+                // Shift 24.
+                token = doShift(token, 24);
+                return;
+            }
+
+            case 53: {
+                // Shift 25.
+                token = doShift(token, 25);
+                return;
+            }
+
+            case 54: {
+                // Shift 26.
+                token = doShift(token, 26);
+                return;
+            }
+
+            case 55: {
+                // Shift 27.
+                token = doShift(token, 27);
+                return;
+            }
+
+            case 56: {
+                // Shift 28.
+                token = doShift(token, 28);
+                return;
+            }
+
+            case 57: {
+                // Shift 29.
+                token = doShift(token, 29);
+                return;
+            }
+
+            case 58: {
+                // Shift 30.
+                token = doShift(token, 30);
+                return;
+            }
+
+            case 59: {
+                // Shift 31.
+                token = doShift(token, 31);
+                return;
+            }
+
+            case 60: {
+                // Shift 32.
+                token = doShift(token, 32);
+                return;
+            }
+
+            case 61: {
+                // Shift 33.
+                token = doShift(token, 33);
+                return;
+            }
+
+            case 62: {
+                // Shift 34.
+                token = doShift(token, 34);
+                return;
+            }
+
+            case 63: {
+                // Shift 35.
+                token = doShift(token, 35);
+                return;
+            }
+
+            case 64: {
+                // Shift 36.
+                token = doShift(token, 36);
+                return;
+            }
+
+            case 65: {
+                // Shift 37.
+                token = doShift(token, 37);
+                return;
+            }
+
+            case 66: {
+                // Shift 38.
+                token = doShift(token, 38);
+                return;
+            }
+
+            case 67: {
+                // Shift 39.
+                token = doShift(token, 39);
+                return;
+            }
+
+            case 68: {
+                // Shift 40.
+                token = doShift(token, 40);
+                return;
+            }
+
+            case 69: {
+                // Shift 41.
+                token = doShift(token, 41);
+                return;
+            }
+
+            case 70: {
+                // Shift 42.
+                token = doShift(token, 42);
+                return;
+            }
+
+            case 71: {
+                // Shift 43.
+                token = doShift(token, 43);
+                return;
+            }
+
+            case 72: {
+                // Shift 44.
+                token = doShift(token, 44);
+                return;
+            }
+
+            case 73: {
+                // Shift 45.
+                token = doShift(token, 45);
+                return;
+            }
+
+            case 74: {
+                // Shift 46.
+                token = doShift(token, 46);
+                return;
+            }
+
+            case 75: {
+                // Shift 47.
+                token = doShift(token, 47);
+                return;
+            }
+
+            case 76: {
+                // Shift 48.
+                token = doShift(token, 48);
+                return;
+            }
+
+            case 77: {
+                // Shift 49.
+                token = doShift(token, 49);
+                return;
+            }
+
+            case 78: {
+                // Shift 50.
+                token = doShift(token, 50);
+                return;
+            }
+
+            case 79: {
+                // Shift 51.
+                token = doShift(token, 51);
+                return;
+            }
+
+            case 80: {
+                // Shift 52.
+                token = doShift(token, 52);
+                return;
+            }
+
+            case 81: {
+                // Shift 53.
+                token = doShift(token, 53);
+                return;
+            }
+
+            case 82: {
+                // Shift 54.
+                token = doShift(token, 54);
+                return;
+            }
+
+            case 83: {
+                // Shift 55.
+                token = doShift(token, 55);
+                return;
+            }
+
+            case 84: {
+                // Shift 56.
+                token = doShift(token, 56);
+                return;
+            }
+
+            case 85: {
+                // Shift 57.
+                token = doShift(token, 57);
+                return;
+            }
+
+            case 86: {
+                // Shift 58.
+                token = doShift(token, 58);
+                return;
+            }
+
+            case 87: {
+                // Shift 59.
+                token = doShift(token, 59);
+                return;
+            }
+
+            case 88: {
+                // Shift 60.
+                token = doShift(token, 60);
+                return;
+            }
+
+            case 89: {
+                // Shift 61.
+                token = doShift(token, 61);
+                return;
+            }
+
+            case 90: {
+                // Shift 62.
+                token = doShift(token, 62);
+                return;
+            }
+
+            case 91: {
+                // Shift 63.
+                token = doShift(token, 63);
+                return;
+            }
+
+            case 92: {
+                // Shift 64.
+                token = doShift(token, 64);
+                return;
+            }
+
+            case 93: {
+                // Shift 65.
+                token = doShift(token, 65);
+                return;
+            }
+
+            case 94: {
+                // Shift 66.
+                token = doShift(token, 66);
+                return;
+            }
+
+            case 95: {
+                // Shift 67.
+                token = doShift(token, 67);
+                return;
+            }
+
+            case 96: {
+                // Shift 68.
+                token = doShift(token, 68);
+                return;
+            }
+
+            case 97: {
+                // Shift 69.
+                token = doShift(token, 69);
+                return;
+            }
+
+            case 98: {
+                // Shift 70.
+                token = doShift(token, 70);
+                return;
+            }
+
+            case 99: {
+                // Shift 71.
+                token = doShift(token, 71);
+                return;
+            }
+
+            case 128: {
+                // Shift 72.
+                token = doShift(token, 72);
+                return;
+            }
+
+            case 129: {
+                // Shift 73.
+                token = doShift(token, 73);
+                return;
+            }
+
+            case 9: {
+                // Shift 84.
+                token = doShift(token, 84);
+                return;
+            }
+
+            case 19: {
+                // Shift 85.
+                token = doShift(token, 85);
+                return;
+            }
+
+            case 25: {
+                // Shift 86.
+                token = doShift(token, 86);
+                return;
+            }
+
+            case 103: {
+                // Shift 87.
+                token = doShift(token, 87);
+                return;
+            }
+
+            case 110: {
+                // Shift 88.
+                token = doShift(token, 88);
+                return;
+            }
+
+            case 117: {
+                // Shift 89.
+                token = doShift(token, 89);
+                return;
+            }
+
+            case 118: {
+                // Shift 90.
+                token = doShift(token, 90);
+                return;
+            }
+
+            case 121: {
+                // Shift 92.
+                token = doShift(token, 92);
+                return;
+            }
+
+            case 122: {
+                // Shift 93.
+                token = doShift(token, 93);
+                return;
+            }
+
+            case 127: {
+                // Shift 94.
+                token = doShift(token, 94);
+                return;
+            }
+
+            case 130: {
+                // Shift 96.
+                token = doShift(token, 96);
+                return;
+            }
+
+            case 131: {
+                // Shift 97.
+                token = doShift(token, 97);
+                return;
+            }
+
+            case 132: {
+                // Shift 98.
+                token = doShift(token, 98);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 234.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action234() throws IOException {
+        switch (token.id) {
+            case 104: {
+                // Shift 115.
+                token = doShift(token, 115);
+                return;
+            }
+
+            case 108:
+            case 109: {
+                // Reduce MapEntries : Expression COLONTK Expression;
+                doReduce1(token, 17);
+                Object o3 = doReduce2();
+                Object o2 = doReduce2();
+                Object o1 = doReduce2();
+
+                List<MapEntry> o = hooks.parseMapEntries1((Expression)o1, (Token)o2, (Expression)o3);
+
+                reduce = true;
+                reduceNonTerminal = 17;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /**
+     * Parser action code for parser state 235.
+     *
+     * @throws IOException If reading the input failed due to an I/O error.
+     */
+    private final void action235() throws IOException {
+        switch (token.id) {
+            case 100:
+            case 101:
+            case 102:
+            case 104:
+            case 105:
+            case 107:
+            case 108:
+            case 109:
+            case 112:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+            case 120:
+            case 122:
+            case 125:
+            case 126: {
+                // Reduce UnaryExpression : NOTKW UnaryExpression;
+                doReduce1(token, 14);
+                Object o2 = doReduce2();
+                Object o1 = doReduce2();
+
+                Expression o = hooks.parseUnaryExpression4((Token)o1, (Expression)o2);
+
+                reduce = true;
+                reduceNonTerminal = 14;
+                reduceState = doReduce3(o);
+                return;
+            }
+
+            default:
+                parsingFailed(token);
+        }
+    }
+
+    /** Parser goto code for parser state 0. */
+    private final void goto0() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(81);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 22:
+                // Name
+                doGoto(80);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 1. */
+    private final void goto1() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 2. */
+    private final void goto2() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 3. */
+    private final void goto3() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 4. */
+    private final void goto4() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 5. */
+    private final void goto5() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 6. */
+    private final void goto6() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 7. */
+    private final void goto7() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 8. */
+    private final void goto8() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 9. */
+    private final void goto9() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 10. */
+    private final void goto10() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 11. */
+    private final void goto11() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 12. */
+    private final void goto12() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 13. */
+    private final void goto13() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 14. */
+    private final void goto14() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 15. */
+    private final void goto15() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 16. */
+    private final void goto16() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 17. */
+    private final void goto17() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 18. */
+    private final void goto18() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 19. */
+    private final void goto19() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 20. */
+    private final void goto20() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 21. */
+    private final void goto21() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 22. */
+    private final void goto22() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 23. */
+    private final void goto23() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 24. */
+    private final void goto24() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 25. */
+    private final void goto25() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 26. */
+    private final void goto26() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 27. */
+    private final void goto27() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 28. */
+    private final void goto28() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 29. */
+    private final void goto29() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 30. */
+    private final void goto30() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 31. */
+    private final void goto31() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 32. */
+    private final void goto32() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 33. */
+    private final void goto33() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 34. */
+    private final void goto34() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 35. */
+    private final void goto35() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 36. */
+    private final void goto36() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 37. */
+    private final void goto37() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 38. */
+    private final void goto38() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 39. */
+    private final void goto39() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 40. */
+    private final void goto40() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 41. */
+    private final void goto41() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 42. */
+    private final void goto42() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 43. */
+    private final void goto43() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 44. */
+    private final void goto44() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 45. */
+    private final void goto45() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 46. */
+    private final void goto46() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 47. */
+    private final void goto47() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 48. */
+    private final void goto48() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 49. */
+    private final void goto49() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 50. */
+    private final void goto50() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 51. */
+    private final void goto51() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 52. */
+    private final void goto52() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 53. */
+    private final void goto53() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 54. */
+    private final void goto54() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 55. */
+    private final void goto55() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 56. */
+    private final void goto56() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 57. */
+    private final void goto57() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 58. */
+    private final void goto58() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 59. */
+    private final void goto59() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 60. */
+    private final void goto60() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 61. */
+    private final void goto61() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 62. */
+    private final void goto62() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 63. */
+    private final void goto63() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 64. */
+    private final void goto64() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 65. */
+    private final void goto65() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 66. */
+    private final void goto66() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 67. */
+    private final void goto67() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 68. */
+    private final void goto68() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 69. */
+    private final void goto69() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 70. */
+    private final void goto70() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 71. */
+    private final void goto71() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 72. */
+    private final void goto72() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 73. */
+    private final void goto73() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 74. */
+    private final void goto74() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 75. */
+    private final void goto75() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 76. */
+    private final void goto76() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 77. */
+    private final void goto77() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 78. */
+    private final void goto78() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 79. */
+    private final void goto79() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 80. */
+    private final void goto80() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 81. */
+    private final void goto81() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 82. */
+    private final void goto82() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 83. */
+    private final void goto83() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 9:
+                // Expression
+                doGoto(102);
+                return;
+
+            case 10:
+                // AndExpression
+                doGoto(100);
+                return;
+
+            case 11:
+                // CompareExpression
+                doGoto(101);
+                return;
+
+            case 12:
+                // AddExpression
+                doGoto(99);
+                return;
+
+            case 13:
+                // MulExpression
+                doGoto(104);
+                return;
+
+            case 14:
+                // UnaryExpression
+                doGoto(109);
+                return;
+
+            case 15:
+                // ProjExpression
+                doGoto(106);
+                return;
+
+            case 16:
+                // ExpressionFactor
+                doGoto(103);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(108);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 21:
+                // ToolArgs
+                doGoto(107);
+                return;
+
+            case 22:
+                // Name
+                doGoto(105);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 84. */
+    private final void goto84() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 85. */
+    private final void goto85() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 86. */
+    private final void goto86() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 87. */
+    private final void goto87() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 14:
+                // UnaryExpression
+                doGoto(235);
+                return;
+
+            case 15:
+                // ProjExpression
+                doGoto(106);
+                return;
+
+            case 16:
+                // ExpressionFactor
+                doGoto(103);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(108);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 22:
+                // Name
+                doGoto(105);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 88. */
+    private final void goto88() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 7:
+                // Expressions
+                doGoto(223);
+                return;
+
+            case 9:
+                // Expression
+                doGoto(222);
+                return;
+
+            case 10:
+                // AndExpression
+                doGoto(100);
+                return;
+
+            case 11:
+                // CompareExpression
+                doGoto(101);
+                return;
+
+            case 12:
+                // AddExpression
+                doGoto(99);
+                return;
+
+            case 13:
+                // MulExpression
+                doGoto(104);
+                return;
+
+            case 14:
+                // UnaryExpression
+                doGoto(109);
+                return;
+
+            case 15:
+                // ProjExpression
+                doGoto(106);
+                return;
+
+            case 16:
+                // ExpressionFactor
+                doGoto(103);
+                return;
+
+            case 17:
+                // MapEntries
+                doGoto(224);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(108);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 22:
+                // Name
+                doGoto(105);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 89. */
+    private final void goto89() {
+        switch (reduceNonTerminal) {
+            case 6:
+                // Type
+                doGoto(181);
+                return;
+
+            case 22:
+                // Name
+                doGoto(180);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 90. */
+    private final void goto90() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 14:
+                // UnaryExpression
+                doGoto(169);
+                return;
+
+            case 15:
+                // ProjExpression
+                doGoto(106);
+                return;
+
+            case 16:
+                // ExpressionFactor
+                doGoto(103);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(108);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 22:
+                // Name
+                doGoto(105);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 91. */
+    private final void goto91() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 92. */
+    private final void goto92() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 9:
+                // Expression
+                doGoto(163);
+                return;
+
+            case 10:
+                // AndExpression
+                doGoto(100);
+                return;
+
+            case 11:
+                // CompareExpression
+                doGoto(101);
+                return;
+
+            case 12:
+                // AddExpression
+                doGoto(99);
+                return;
+
+            case 13:
+                // MulExpression
+                doGoto(104);
+                return;
+
+            case 14:
+                // UnaryExpression
+                doGoto(109);
+                return;
+
+            case 15:
+                // ProjExpression
+                doGoto(106);
+                return;
+
+            case 16:
+                // ExpressionFactor
+                doGoto(103);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(108);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 22:
+                // Name
+                doGoto(105);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 93. */
+    private final void goto93() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 14:
+                // UnaryExpression
+                doGoto(162);
+                return;
+
+            case 15:
+                // ProjExpression
+                doGoto(106);
+                return;
+
+            case 16:
+                // ExpressionFactor
+                doGoto(103);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(108);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 22:
+                // Name
+                doGoto(105);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 94. */
+    private final void goto94() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 7:
+                // Expressions
+                doGoto(157);
+                return;
+
+            case 9:
+                // Expression
+                doGoto(156);
+                return;
+
+            case 10:
+                // AndExpression
+                doGoto(100);
+                return;
+
+            case 11:
+                // CompareExpression
+                doGoto(101);
+                return;
+
+            case 12:
+                // AddExpression
+                doGoto(99);
+                return;
+
+            case 13:
+                // MulExpression
+                doGoto(104);
+                return;
+
+            case 14:
+                // UnaryExpression
+                doGoto(109);
+                return;
+
+            case 15:
+                // ProjExpression
+                doGoto(106);
+                return;
+
+            case 16:
+                // ExpressionFactor
+                doGoto(103);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(108);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 22:
+                // Name
+                doGoto(105);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 95. */
+    private final void goto95() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 96. */
+    private final void goto96() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 97. */
+    private final void goto97() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 98. */
+    private final void goto98() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 99. */
+    private final void goto99() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 100. */
+    private final void goto100() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 101. */
+    private final void goto101() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 102. */
+    private final void goto102() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 103. */
+    private final void goto103() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 104. */
+    private final void goto104() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 105. */
+    private final void goto105() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 106. */
+    private final void goto106() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 107. */
+    private final void goto107() {
+        switch (reduceNonTerminal) {
+            case 23:
+                // OptComma
+                doGoto(111);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 108. */
+    private final void goto108() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 109. */
+    private final void goto109() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 110. */
+    private final void goto110() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 9:
+                // Expression
+                doGoto(114);
+                return;
+
+            case 10:
+                // AndExpression
+                doGoto(100);
+                return;
+
+            case 11:
+                // CompareExpression
+                doGoto(101);
+                return;
+
+            case 12:
+                // AddExpression
+                doGoto(99);
+                return;
+
+            case 13:
+                // MulExpression
+                doGoto(104);
+                return;
+
+            case 14:
+                // UnaryExpression
+                doGoto(109);
+                return;
+
+            case 15:
+                // ProjExpression
+                doGoto(106);
+                return;
+
+            case 16:
+                // ExpressionFactor
+                doGoto(103);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(108);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 22:
+                // Name
+                doGoto(105);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 111. */
+    private final void goto111() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 112. */
+    private final void goto112() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 113. */
+    private final void goto113() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 114. */
+    private final void goto114() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 115. */
+    private final void goto115() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 10:
+                // AndExpression
+                doGoto(116);
+                return;
+
+            case 11:
+                // CompareExpression
+                doGoto(101);
+                return;
+
+            case 12:
+                // AddExpression
+                doGoto(99);
+                return;
+
+            case 13:
+                // MulExpression
+                doGoto(104);
+                return;
+
+            case 14:
+                // UnaryExpression
+                doGoto(109);
+                return;
+
+            case 15:
+                // ProjExpression
+                doGoto(106);
+                return;
+
+            case 16:
+                // ExpressionFactor
+                doGoto(103);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(108);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 22:
+                // Name
+                doGoto(105);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 116. */
+    private final void goto116() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 117. */
+    private final void goto117() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 11:
+                // CompareExpression
+                doGoto(118);
+                return;
+
+            case 12:
+                // AddExpression
+                doGoto(99);
+                return;
+
+            case 13:
+                // MulExpression
+                doGoto(104);
+                return;
+
+            case 14:
+                // UnaryExpression
+                doGoto(109);
+                return;
+
+            case 15:
+                // ProjExpression
+                doGoto(106);
+                return;
+
+            case 16:
+                // ExpressionFactor
+                doGoto(103);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(108);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 22:
+                // Name
+                doGoto(105);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 118. */
+    private final void goto118() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 119. */
+    private final void goto119() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 12:
+                // AddExpression
+                doGoto(142);
+                return;
+
+            case 13:
+                // MulExpression
+                doGoto(104);
+                return;
+
+            case 14:
+                // UnaryExpression
+                doGoto(109);
+                return;
+
+            case 15:
+                // ProjExpression
+                doGoto(106);
+                return;
+
+            case 16:
+                // ExpressionFactor
+                doGoto(103);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(108);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 22:
+                // Name
+                doGoto(105);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 120. */
+    private final void goto120() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 12:
+                // AddExpression
+                doGoto(141);
+                return;
+
+            case 13:
+                // MulExpression
+                doGoto(104);
+                return;
+
+            case 14:
+                // UnaryExpression
+                doGoto(109);
+                return;
+
+            case 15:
+                // ProjExpression
+                doGoto(106);
+                return;
+
+            case 16:
+                // ExpressionFactor
+                doGoto(103);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(108);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 22:
+                // Name
+                doGoto(105);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 121. */
+    private final void goto121() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 12:
+                // AddExpression
+                doGoto(140);
+                return;
+
+            case 13:
+                // MulExpression
+                doGoto(104);
+                return;
+
+            case 14:
+                // UnaryExpression
+                doGoto(109);
+                return;
+
+            case 15:
+                // ProjExpression
+                doGoto(106);
+                return;
+
+            case 16:
+                // ExpressionFactor
+                doGoto(103);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(108);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 22:
+                // Name
+                doGoto(105);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 122. */
+    private final void goto122() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 12:
+                // AddExpression
+                doGoto(139);
+                return;
+
+            case 13:
+                // MulExpression
+                doGoto(104);
+                return;
+
+            case 14:
+                // UnaryExpression
+                doGoto(109);
+                return;
+
+            case 15:
+                // ProjExpression
+                doGoto(106);
+                return;
+
+            case 16:
+                // ExpressionFactor
+                doGoto(103);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(108);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 22:
+                // Name
+                doGoto(105);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 123. */
+    private final void goto123() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 12:
+                // AddExpression
+                doGoto(138);
+                return;
+
+            case 13:
+                // MulExpression
+                doGoto(104);
+                return;
+
+            case 14:
+                // UnaryExpression
+                doGoto(109);
+                return;
+
+            case 15:
+                // ProjExpression
+                doGoto(106);
+                return;
+
+            case 16:
+                // ExpressionFactor
+                doGoto(103);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(108);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 22:
+                // Name
+                doGoto(105);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 124. */
+    private final void goto124() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 12:
+                // AddExpression
+                doGoto(125);
+                return;
+
+            case 13:
+                // MulExpression
+                doGoto(104);
+                return;
+
+            case 14:
+                // UnaryExpression
+                doGoto(109);
+                return;
+
+            case 15:
+                // ProjExpression
+                doGoto(106);
+                return;
+
+            case 16:
+                // ExpressionFactor
+                doGoto(103);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(108);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 22:
+                // Name
+                doGoto(105);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 125. */
+    private final void goto125() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 126. */
+    private final void goto126() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 13:
+                // MulExpression
+                doGoto(137);
+                return;
+
+            case 14:
+                // UnaryExpression
+                doGoto(109);
+                return;
+
+            case 15:
+                // ProjExpression
+                doGoto(106);
+                return;
+
+            case 16:
+                // ExpressionFactor
+                doGoto(103);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(108);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 22:
+                // Name
+                doGoto(105);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 127. */
+    private final void goto127() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 13:
+                // MulExpression
+                doGoto(128);
+                return;
+
+            case 14:
+                // UnaryExpression
+                doGoto(109);
+                return;
+
+            case 15:
+                // ProjExpression
+                doGoto(106);
+                return;
+
+            case 16:
+                // ExpressionFactor
+                doGoto(103);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(108);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 22:
+                // Name
+                doGoto(105);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 128. */
+    private final void goto128() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 129. */
+    private final void goto129() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 14:
+                // UnaryExpression
+                doGoto(136);
+                return;
+
+            case 15:
+                // ProjExpression
+                doGoto(106);
+                return;
+
+            case 16:
+                // ExpressionFactor
+                doGoto(103);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(108);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 22:
+                // Name
+                doGoto(105);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 130. */
+    private final void goto130() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 14:
+                // UnaryExpression
+                doGoto(135);
+                return;
+
+            case 15:
+                // ProjExpression
+                doGoto(106);
+                return;
+
+            case 16:
+                // ExpressionFactor
+                doGoto(103);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(108);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 22:
+                // Name
+                doGoto(105);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 131. */
+    private final void goto131() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 14:
+                // UnaryExpression
+                doGoto(134);
+                return;
+
+            case 15:
+                // ProjExpression
+                doGoto(106);
+                return;
+
+            case 16:
+                // ExpressionFactor
+                doGoto(103);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(108);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 22:
+                // Name
+                doGoto(105);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 132. */
+    private final void goto132() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 14:
+                // UnaryExpression
+                doGoto(133);
+                return;
+
+            case 15:
+                // ProjExpression
+                doGoto(106);
+                return;
+
+            case 16:
+                // ExpressionFactor
+                doGoto(103);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(108);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 22:
+                // Name
+                doGoto(105);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 133. */
+    private final void goto133() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 134. */
+    private final void goto134() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 135. */
+    private final void goto135() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 136. */
+    private final void goto136() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 137. */
+    private final void goto137() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 138. */
+    private final void goto138() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 139. */
+    private final void goto139() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 140. */
+    private final void goto140() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 141. */
+    private final void goto141() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 142. */
+    private final void goto142() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 143. */
+    private final void goto143() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 9:
+                // Expression
+                doGoto(144);
+                return;
+
+            case 10:
+                // AndExpression
+                doGoto(100);
+                return;
+
+            case 11:
+                // CompareExpression
+                doGoto(101);
+                return;
+
+            case 12:
+                // AddExpression
+                doGoto(99);
+                return;
+
+            case 13:
+                // MulExpression
+                doGoto(104);
+                return;
+
+            case 14:
+                // UnaryExpression
+                doGoto(109);
+                return;
+
+            case 15:
+                // ProjExpression
+                doGoto(106);
+                return;
+
+            case 16:
+                // ExpressionFactor
+                doGoto(103);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(108);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 22:
+                // Name
+                doGoto(105);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 144. */
+    private final void goto144() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 145. */
+    private final void goto145() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 8:
+                // OptExpression
+                doGoto(147);
+                return;
+
+            case 9:
+                // Expression
+                doGoto(146);
+                return;
+
+            case 10:
+                // AndExpression
+                doGoto(100);
+                return;
+
+            case 11:
+                // CompareExpression
+                doGoto(101);
+                return;
+
+            case 12:
+                // AddExpression
+                doGoto(99);
+                return;
+
+            case 13:
+                // MulExpression
+                doGoto(104);
+                return;
+
+            case 14:
+                // UnaryExpression
+                doGoto(109);
+                return;
+
+            case 15:
+                // ProjExpression
+                doGoto(106);
+                return;
+
+            case 16:
+                // ExpressionFactor
+                doGoto(103);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(108);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 22:
+                // Name
+                doGoto(105);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 146. */
+    private final void goto146() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 147. */
+    private final void goto147() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 148. */
+    private final void goto148() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 8:
+                // OptExpression
+                doGoto(150);
+                return;
+
+            case 9:
+                // Expression
+                doGoto(149);
+                return;
+
+            case 10:
+                // AndExpression
+                doGoto(100);
+                return;
+
+            case 11:
+                // CompareExpression
+                doGoto(101);
+                return;
+
+            case 12:
+                // AddExpression
+                doGoto(99);
+                return;
+
+            case 13:
+                // MulExpression
+                doGoto(104);
+                return;
+
+            case 14:
+                // UnaryExpression
+                doGoto(109);
+                return;
+
+            case 15:
+                // ProjExpression
+                doGoto(106);
+                return;
+
+            case 16:
+                // ExpressionFactor
+                doGoto(103);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(108);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 22:
+                // Name
+                doGoto(105);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 149. */
+    private final void goto149() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 150. */
+    private final void goto150() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 151. */
+    private final void goto151() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 152. */
+    private final void goto152() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 153. */
+    private final void goto153() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 9:
+                // Expression
+                doGoto(154);
+                return;
+
+            case 10:
+                // AndExpression
+                doGoto(100);
+                return;
+
+            case 11:
+                // CompareExpression
+                doGoto(101);
+                return;
+
+            case 12:
+                // AddExpression
+                doGoto(99);
+                return;
+
+            case 13:
+                // MulExpression
+                doGoto(104);
+                return;
+
+            case 14:
+                // UnaryExpression
+                doGoto(109);
+                return;
+
+            case 15:
+                // ProjExpression
+                doGoto(106);
+                return;
+
+            case 16:
+                // ExpressionFactor
+                doGoto(103);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(108);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 22:
+                // Name
+                doGoto(105);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 154. */
+    private final void goto154() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 155. */
+    private final void goto155() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 156. */
+    private final void goto156() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 157. */
+    private final void goto157() {
+        switch (reduceNonTerminal) {
+            case 23:
+                // OptComma
+                doGoto(159);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 158. */
+    private final void goto158() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 9:
+                // Expression
+                doGoto(161);
+                return;
+
+            case 10:
+                // AndExpression
+                doGoto(100);
+                return;
+
+            case 11:
+                // CompareExpression
+                doGoto(101);
+                return;
+
+            case 12:
+                // AddExpression
+                doGoto(99);
+                return;
+
+            case 13:
+                // MulExpression
+                doGoto(104);
+                return;
+
+            case 14:
+                // UnaryExpression
+                doGoto(109);
+                return;
+
+            case 15:
+                // ProjExpression
+                doGoto(106);
+                return;
+
+            case 16:
+                // ExpressionFactor
+                doGoto(103);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(108);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 22:
+                // Name
+                doGoto(105);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 159. */
+    private final void goto159() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 160. */
+    private final void goto160() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 161. */
+    private final void goto161() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 162. */
+    private final void goto162() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 163. */
+    private final void goto163() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 164. */
+    private final void goto164() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 7:
+                // Expressions
+                doGoto(166);
+                return;
+
+            case 9:
+                // Expression
+                doGoto(156);
+                return;
+
+            case 10:
+                // AndExpression
+                doGoto(100);
+                return;
+
+            case 11:
+                // CompareExpression
+                doGoto(101);
+                return;
+
+            case 12:
+                // AddExpression
+                doGoto(99);
+                return;
+
+            case 13:
+                // MulExpression
+                doGoto(104);
+                return;
+
+            case 14:
+                // UnaryExpression
+                doGoto(109);
+                return;
+
+            case 15:
+                // ProjExpression
+                doGoto(106);
+                return;
+
+            case 16:
+                // ExpressionFactor
+                doGoto(103);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(108);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 22:
+                // Name
+                doGoto(105);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 165. */
+    private final void goto165() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 166. */
+    private final void goto166() {
+        switch (reduceNonTerminal) {
+            case 23:
+                // OptComma
+                doGoto(167);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 167. */
+    private final void goto167() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 168. */
+    private final void goto168() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 169. */
+    private final void goto169() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 170. */
+    private final void goto170() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 171. */
+    private final void goto171() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 172. */
+    private final void goto172() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 173. */
+    private final void goto173() {
+        switch (reduceNonTerminal) {
+            case 6:
+                // Type
+                doGoto(216);
+                return;
+
+            case 22:
+                // Name
+                doGoto(180);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 174. */
+    private final void goto174() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 175. */
+    private final void goto175() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 176. */
+    private final void goto176() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 177. */
+    private final void goto177() {
+        switch (reduceNonTerminal) {
+            case 6:
+                // Type
+                doGoto(200);
+                return;
+
+            case 22:
+                // Name
+                doGoto(180);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 178. */
+    private final void goto178() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 179. */
+    private final void goto179() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 180. */
+    private final void goto180() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 181. */
+    private final void goto181() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 182. */
+    private final void goto182() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 16:
+                // ExpressionFactor
+                doGoto(183);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(108);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 22:
+                // Name
+                doGoto(105);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 183. */
+    private final void goto183() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 184. */
+    private final void goto184() {
+        switch (reduceNonTerminal) {
+            case 6:
+                // Type
+                doGoto(194);
+                return;
+
+            case 22:
+                // Name
+                doGoto(180);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 185. */
+    private final void goto185() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 186. */
+    private final void goto186() {
+        switch (reduceNonTerminal) {
+            case 6:
+                // Type
+                doGoto(187);
+                return;
+
+            case 22:
+                // Name
+                doGoto(180);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 187. */
+    private final void goto187() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 188. */
+    private final void goto188() {
+        switch (reduceNonTerminal) {
+            case 5:
+                // Types
+                doGoto(190);
+                return;
+
+            case 6:
+                // Type
+                doGoto(189);
+                return;
+
+            case 22:
+                // Name
+                doGoto(180);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 189. */
+    private final void goto189() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 190. */
+    private final void goto190() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 191. */
+    private final void goto191() {
+        switch (reduceNonTerminal) {
+            case 6:
+                // Type
+                doGoto(193);
+                return;
+
+            case 22:
+                // Name
+                doGoto(180);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 192. */
+    private final void goto192() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 193. */
+    private final void goto193() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 194. */
+    private final void goto194() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 195. */
+    private final void goto195() {
+        switch (reduceNonTerminal) {
+            case 5:
+                // Types
+                doGoto(196);
+                return;
+
+            case 6:
+                // Type
+                doGoto(189);
+                return;
+
+            case 22:
+                // Name
+                doGoto(180);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 196. */
+    private final void goto196() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 197. */
+    private final void goto197() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 198. */
+    private final void goto198() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 199. */
+    private final void goto199() {
+        switch (reduceNonTerminal) {
+            case 6:
+                // Type
+                doGoto(201);
+                return;
+
+            case 22:
+                // Name
+                doGoto(180);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 200. */
+    private final void goto200() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 201. */
+    private final void goto201() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 202. */
+    private final void goto202() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 203. */
+    private final void goto203() {
+        switch (reduceNonTerminal) {
+            case 6:
+                // Type
+                doGoto(210);
+                return;
+
+            case 22:
+                // Name
+                doGoto(180);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 204. */
+    private final void goto204() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 205. */
+    private final void goto205() {
+        switch (reduceNonTerminal) {
+            case 6:
+                // Type
+                doGoto(206);
+                return;
+
+            case 22:
+                // Name
+                doGoto(180);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 206. */
+    private final void goto206() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 207. */
+    private final void goto207() {
+        switch (reduceNonTerminal) {
+            case 6:
+                // Type
+                doGoto(208);
+                return;
+
+            case 22:
+                // Name
+                doGoto(180);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 208. */
+    private final void goto208() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 209. */
+    private final void goto209() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 210. */
+    private final void goto210() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 211. */
+    private final void goto211() {
+        switch (reduceNonTerminal) {
+            case 6:
+                // Type
+                doGoto(212);
+                return;
+
+            case 22:
+                // Name
+                doGoto(180);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 212. */
+    private final void goto212() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 213. */
+    private final void goto213() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 214. */
+    private final void goto214() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 215. */
+    private final void goto215() {
+        switch (reduceNonTerminal) {
+            case 6:
+                // Type
+                doGoto(217);
+                return;
+
+            case 22:
+                // Name
+                doGoto(180);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 216. */
+    private final void goto216() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 217. */
+    private final void goto217() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 218. */
+    private final void goto218() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 219. */
+    private final void goto219() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 220. */
+    private final void goto220() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 221. */
+    private final void goto221() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 222. */
+    private final void goto222() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 223. */
+    private final void goto223() {
+        switch (reduceNonTerminal) {
+            case 23:
+                // OptComma
+                doGoto(231);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 224. */
+    private final void goto224() {
+        switch (reduceNonTerminal) {
+            case 23:
+                // OptComma
+                doGoto(226);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 225. */
+    private final void goto225() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 9:
+                // Expression
+                doGoto(228);
+                return;
+
+            case 10:
+                // AndExpression
+                doGoto(100);
+                return;
+
+            case 11:
+                // CompareExpression
+                doGoto(101);
+                return;
+
+            case 12:
+                // AddExpression
+                doGoto(99);
+                return;
+
+            case 13:
+                // MulExpression
+                doGoto(104);
+                return;
+
+            case 14:
+                // UnaryExpression
+                doGoto(109);
+                return;
+
+            case 15:
+                // ProjExpression
+                doGoto(106);
+                return;
+
+            case 16:
+                // ExpressionFactor
+                doGoto(103);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(108);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 22:
+                // Name
+                doGoto(105);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 226. */
+    private final void goto226() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 227. */
+    private final void goto227() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 228. */
+    private final void goto228() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 229. */
+    private final void goto229() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 9:
+                // Expression
+                doGoto(230);
+                return;
+
+            case 10:
+                // AndExpression
+                doGoto(100);
+                return;
+
+            case 11:
+                // CompareExpression
+                doGoto(101);
+                return;
+
+            case 12:
+                // AddExpression
+                doGoto(99);
+                return;
+
+            case 13:
+                // MulExpression
+                doGoto(104);
+                return;
+
+            case 14:
+                // UnaryExpression
+                doGoto(109);
+                return;
+
+            case 15:
+                // ProjExpression
+                doGoto(106);
+                return;
+
+            case 16:
+                // ExpressionFactor
+                doGoto(103);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(108);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 22:
+                // Name
+                doGoto(105);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 230. */
+    private final void goto230() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 231. */
+    private final void goto231() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 232. */
+    private final void goto232() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 233. */
+    private final void goto233() {
+        switch (reduceNonTerminal) {
+            case 0:
+                // BuiltInIoTool
+                doGoto(77);
+                return;
+
+            case 1:
+                // BuiltInGenericTool
+                doGoto(76);
+                return;
+
+            case 2:
+                // BuiltInPathTool
+                doGoto(78);
+                return;
+
+            case 3:
+                // BuiltInFileTool
+                doGoto(75);
+                return;
+
+            case 4:
+                // BuiltInDataTool
+                doGoto(74);
+                return;
+
+            case 9:
+                // Expression
+                doGoto(234);
+                return;
+
+            case 10:
+                // AndExpression
+                doGoto(100);
+                return;
+
+            case 11:
+                // CompareExpression
+                doGoto(101);
+                return;
+
+            case 12:
+                // AddExpression
+                doGoto(99);
+                return;
+
+            case 13:
+                // MulExpression
+                doGoto(104);
+                return;
+
+            case 14:
+                // UnaryExpression
+                doGoto(109);
+                return;
+
+            case 15:
+                // ProjExpression
+                doGoto(106);
+                return;
+
+            case 16:
+                // ExpressionFactor
+                doGoto(103);
+                return;
+
+            case 18:
+                // ToolInvokeExpression
+                doGoto(108);
+                return;
+
+            case 19:
+                // ToolRef
+                doGoto(82);
+                return;
+
+            case 20:
+                // BuiltInTool
+                doGoto(79);
+                return;
+
+            case 22:
+                // Name
+                doGoto(105);
+                return;
+
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 234. */
+    private final void goto234() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    /** Parser goto code for parser state 235. */
+    private final void goto235() {
+        switch (reduceNonTerminal) {
+            default:
+                String msg = fmt("Unknown non-terminal %d (%s) for reduce " +
+                                 "state %d.", reduceNonTerminal,
+                                 NON_TERMINAL_NAMES[reduceNonTerminal],
+                                 reduceState);
+                throw new RuntimeException(msg);
+        }
+    }
+
+    @Override
+    protected final String getNonTerminalName(int nonTerminalId) {
+        return NON_TERMINAL_NAMES[nonTerminalId];
+    }
+
+    /** See {@code Parser.firstTerminals}. */
+    private static final class FirstTerminals {
+        /** See {@code Parser.firstTerminals}. */
+        private static final int[][] FIRST_TERMINALS = new int[][] {
+            {29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 128, 129}, // state 0
+            {}, // state 1
+            {}, // state 2
+            {}, // state 3
+            {}, // state 4
+            {}, // state 5
+            {}, // state 6
+            {}, // state 7
+            {}, // state 8
+            {}, // state 9
+            {}, // state 10
+            {}, // state 11
+            {}, // state 12
+            {}, // state 13
+            {}, // state 14
+            {}, // state 15
+            {}, // state 16
+            {}, // state 17
+            {}, // state 18
+            {}, // state 19
+            {}, // state 20
+            {}, // state 21
+            {}, // state 22
+            {}, // state 23
+            {}, // state 24
+            {}, // state 25
+            {}, // state 26
+            {}, // state 27
+            {}, // state 28
+            {}, // state 29
+            {}, // state 30
+            {}, // state 31
+            {}, // state 32
+            {}, // state 33
+            {}, // state 34
+            {}, // state 35
+            {}, // state 36
+            {}, // state 37
+            {}, // state 38
+            {}, // state 39
+            {}, // state 40
+            {}, // state 41
+            {}, // state 42
+            {}, // state 43
+            {}, // state 44
+            {}, // state 45
+            {}, // state 46
+            {}, // state 47
+            {}, // state 48
+            {}, // state 49
+            {}, // state 50
+            {}, // state 51
+            {}, // state 52
+            {}, // state 53
+            {}, // state 54
+            {}, // state 55
+            {}, // state 56
+            {}, // state 57
+            {}, // state 58
+            {}, // state 59
+            {}, // state 60
+            {}, // state 61
+            {}, // state 62
+            {}, // state 63
+            {}, // state 64
+            {}, // state 65
+            {}, // state 66
+            {}, // state 67
+            {}, // state 68
+            {}, // state 69
+            {}, // state 70
+            {}, // state 71
+            {}, // state 72
+            {}, // state 73
+            {}, // state 74
+            {}, // state 75
+            {}, // state 76
+            {}, // state 77
+            {}, // state 78
+            {}, // state 79
+            {}, // state 80
+            {136}, // state 81
+            {121}, // state 82
+            {9, 19, 25, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 103, 110, 117, 118, 120, 121, 122, 127, 128, 129, 130, 131, 132}, // state 83
+            {}, // state 84
+            {}, // state 85
+            {}, // state 86
+            {9, 19, 25, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 103, 110, 117, 118, 121, 122, 127, 128, 129, 130, 131, 132}, // state 87
+            {9, 19, 25, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 103, 109, 110, 117, 118, 121, 122, 127, 128, 129, 130, 131, 132}, // state 88
+            {1, 4, 15, 16, 17, 18, 20, 22, 23, 26, 128, 129}, // state 89
+            {9, 19, 25, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 103, 110, 117, 118, 121, 122, 127, 128, 129, 130, 131, 132}, // state 90
+            {}, // state 91
+            {9, 19, 25, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 103, 110, 117, 118, 121, 122, 127, 128, 129, 130, 131, 132}, // state 92
+            {9, 19, 25, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 103, 110, 117, 118, 121, 122, 127, 128, 129, 130, 131, 132}, // state 93
+            {9, 19, 25, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 103, 110, 117, 118, 121, 122, 126, 127, 128, 129, 130, 131, 132}, // state 94
+            {113}, // state 95
+            {}, // state 96
+            {}, // state 97
+            {}, // state 98
+            {118, 122}, // state 99
+            {100}, // state 100
+            {112, 114, 115, 116, 117, 119}, // state 101
+            {104}, // state 102
+            {}, // state 103
+            {101, 102, 105, 125}, // state 104
+            {}, // state 105
+            {127}, // state 106
+            {108, 120}, // state 107
+            {}, // state 108
+            {}, // state 109
+            {9, 19, 25, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 103, 110, 117, 118, 121, 122, 127, 128, 129, 130, 131, 132}, // state 110
+            {120}, // state 111
+            {}, // state 112
+            {113}, // state 113
+            {104}, // state 114
+            {9, 19, 25, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 103, 110, 117, 118, 121, 122, 127, 128, 129, 130, 131, 132}, // state 115
+            {100}, // state 116
+            {9, 19, 25, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 103, 110, 117, 118, 121, 122, 127, 128, 129, 130, 131, 132}, // state 117
+            {112, 114, 115, 116, 117, 119}, // state 118
+            {9, 19, 25, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 103, 110, 117, 118, 121, 122, 127, 128, 129, 130, 131, 132}, // state 119
+            {9, 19, 25, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 103, 110, 117, 118, 121, 122, 127, 128, 129, 130, 131, 132}, // state 120
+            {9, 19, 25, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 103, 110, 117, 118, 121, 122, 127, 128, 129, 130, 131, 132}, // state 121
+            {9, 19, 25, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 103, 110, 117, 118, 121, 122, 127, 128, 129, 130, 131, 132}, // state 122
+            {9, 19, 25, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 103, 110, 117, 118, 121, 122, 127, 128, 129, 130, 131, 132}, // state 123
+            {9, 19, 25, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 103, 110, 117, 118, 121, 122, 127, 128, 129, 130, 131, 132}, // state 124
+            {118, 122}, // state 125
+            {9, 19, 25, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 103, 110, 117, 118, 121, 122, 127, 128, 129, 130, 131, 132}, // state 126
+            {9, 19, 25, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 103, 110, 117, 118, 121, 122, 127, 128, 129, 130, 131, 132}, // state 127
+            {101, 102, 105, 125}, // state 128
+            {9, 19, 25, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 103, 110, 117, 118, 121, 122, 127, 128, 129, 130, 131, 132}, // state 129
+            {9, 19, 25, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 103, 110, 117, 118, 121, 122, 127, 128, 129, 130, 131, 132}, // state 130
+            {9, 19, 25, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 103, 110, 117, 118, 121, 122, 127, 128, 129, 130, 131, 132}, // state 131
+            {9, 19, 25, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 103, 110, 117, 118, 121, 122, 127, 128, 129, 130, 131, 132}, // state 132
+            {}, // state 133
+            {}, // state 134
+            {}, // state 135
+            {}, // state 136
+            {101, 102, 105, 125}, // state 137
+            {118, 122}, // state 138
+            {118, 122}, // state 139
+            {118, 122}, // state 140
+            {118, 122}, // state 141
+            {118, 122}, // state 142
+            {9, 19, 25, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 103, 110, 117, 118, 121, 122, 127, 128, 129, 130, 131, 132}, // state 143
+            {104}, // state 144
+            {9, 19, 25, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 103, 107, 110, 117, 118, 121, 122, 127, 128, 129, 130, 131, 132}, // state 145
+            {104, 126}, // state 146
+            {107}, // state 147
+            {9, 19, 25, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 103, 110, 117, 118, 121, 122, 126, 127, 128, 129, 130, 131, 132}, // state 148
+            {104}, // state 149
+            {126}, // state 150
+            {}, // state 151
+            {}, // state 152
+            {9, 19, 25, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 103, 110, 117, 118, 121, 122, 127, 128, 129, 130, 131, 132}, // state 153
+            {104}, // state 154
+            {}, // state 155
+            {104}, // state 156
+            {108, 126}, // state 157
+            {9, 19, 25, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 103, 110, 117, 118, 121, 122, 127, 128, 129, 130, 131, 132}, // state 158
+            {126}, // state 159
+            {}, // state 160
+            {104}, // state 161
+            {}, // state 162
+            {104, 108, 120}, // state 163
+            {9, 19, 25, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 103, 110, 117, 118, 121, 122, 127, 128, 129, 130, 131, 132}, // state 164
+            {}, // state 165
+            {108, 120}, // state 166
+            {120}, // state 167
+            {}, // state 168
+            {}, // state 169
+            {123}, // state 170
+            {123}, // state 171
+            {123}, // state 172
+            {1, 4, 15, 16, 17, 18, 20, 22, 23, 26, 123, 128, 129}, // state 173
+            {123}, // state 174
+            {121, 123}, // state 175
+            {123}, // state 176
+            {1, 4, 15, 16, 17, 18, 20, 22, 23, 26, 123, 128, 129}, // state 177
+            {123}, // state 178
+            {121, 123}, // state 179
+            {}, // state 180
+            {115}, // state 181
+            {9, 19, 25, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 110, 117, 121, 127, 128, 129, 130, 131, 132}, // state 182
+            {}, // state 183
+            {1, 4, 15, 16, 17, 18, 20, 22, 23, 26, 128, 129}, // state 184
+            {121}, // state 185
+            {1, 4, 15, 16, 17, 18, 20, 22, 23, 26, 128, 129}, // state 186
+            {108}, // state 187
+            {1, 4, 15, 16, 17, 18, 20, 22, 23, 26, 128, 129}, // state 188
+            {}, // state 189
+            {108, 120}, // state 190
+            {1, 4, 15, 16, 17, 18, 20, 22, 23, 26, 128, 129}, // state 191
+            {}, // state 192
+            {}, // state 193
+            {108}, // state 194
+            {1, 4, 15, 16, 17, 18, 20, 22, 23, 26, 128, 129}, // state 195
+            {108, 120}, // state 196
+            {}, // state 197
+            {}, // state 198
+            {1, 4, 15, 16, 17, 18, 20, 22, 23, 26, 128, 129}, // state 199
+            {}, // state 200
+            {}, // state 201
+            {}, // state 202
+            {1, 4, 15, 16, 17, 18, 20, 22, 23, 26, 128, 129}, // state 203
+            {121}, // state 204
+            {1, 4, 15, 16, 17, 18, 20, 22, 23, 26, 128, 129}, // state 205
+            {107}, // state 206
+            {1, 4, 15, 16, 17, 18, 20, 22, 23, 26, 128, 129}, // state 207
+            {120}, // state 208
+            {}, // state 209
+            {107}, // state 210
+            {1, 4, 15, 16, 17, 18, 20, 22, 23, 26, 128, 129}, // state 211
+            {120}, // state 212
+            {}, // state 213
+            {}, // state 214
+            {1, 4, 15, 16, 17, 18, 20, 22, 23, 26, 128, 129}, // state 215
+            {}, // state 216
+            {}, // state 217
+            {}, // state 218
+            {}, // state 219
+            {}, // state 220
+            {}, // state 221
+            {104, 107}, // state 222
+            {108, 109}, // state 223
+            {108, 109}, // state 224
+            {9, 19, 25, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 103, 110, 117, 118, 121, 122, 127, 128, 129, 130, 131, 132}, // state 225
+            {109}, // state 226
+            {}, // state 227
+            {104, 107}, // state 228
+            {9, 19, 25, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 103, 110, 117, 118, 121, 122, 127, 128, 129, 130, 131, 132}, // state 229
+            {104}, // state 230
+            {109}, // state 231
+            {}, // state 232
+            {9, 19, 25, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 103, 110, 117, 118, 121, 122, 127, 128, 129, 130, 131, 132}, // state 233
+            {104}, // state 234
+            {}, // state 235
+        };
+    }
+
+    /** See {@code Parser.firstTerminalsReduced}. */
+    private static final class FirstTerminalsReduced {
+        /** See {@code Parser.firstTerminalsReduced}. */
+        private static final int[][][] FIRST_TERMINALS_REDUCED = new int[][][] {
+            { // state 0
+                {41, 136},
+                {42, 121},
+            },
+            {}, // state 1
+            {}, // state 2
+            {}, // state 3
+            {}, // state 4
+            {}, // state 5
+            {}, // state 6
+            {}, // state 7
+            {}, // state 8
+            {}, // state 9
+            {}, // state 10
+            {}, // state 11
+            {}, // state 12
+            {}, // state 13
+            {}, // state 14
+            {}, // state 15
+            {}, // state 16
+            {}, // state 17
+            {}, // state 18
+            {}, // state 19
+            {}, // state 20
+            {}, // state 21
+            {}, // state 22
+            {}, // state 23
+            {}, // state 24
+            {}, // state 25
+            {}, // state 26
+            {}, // state 27
+            {}, // state 28
+            {}, // state 29
+            {}, // state 30
+            {}, // state 31
+            {}, // state 32
+            {}, // state 33
+            {}, // state 34
+            {}, // state 35
+            {}, // state 36
+            {}, // state 37
+            {}, // state 38
+            {}, // state 39
+            {}, // state 40
+            {}, // state 41
+            {}, // state 42
+            {}, // state 43
+            {}, // state 44
+            {}, // state 45
+            {}, // state 46
+            {}, // state 47
+            {}, // state 48
+            {}, // state 49
+            {}, // state 50
+            {}, // state 51
+            {}, // state 52
+            {}, // state 53
+            {}, // state 54
+            {}, // state 55
+            {}, // state 56
+            {}, // state 57
+            {}, // state 58
+            {}, // state 59
+            {}, // state 60
+            {}, // state 61
+            {}, // state 62
+            {}, // state 63
+            {}, // state 64
+            {}, // state 65
+            {}, // state 66
+            {}, // state 67
+            {}, // state 68
+            {}, // state 69
+            {}, // state 70
+            {}, // state 71
+            {}, // state 72
+            {}, // state 73
+            {}, // state 74
+            {}, // state 75
+            {}, // state 76
+            {}, // state 77
+            {}, // state 78
+            {}, // state 79
+            {}, // state 80
+            {}, // state 81
+            {}, // state 82
+            { // state 83
+                {32, 104},
+                {33, 100},
+                {34, 112, 114, 115, 116, 117, 119},
+                {35, 118, 122},
+                {36, 101, 102, 105, 125},
+                {38, 127},
+                {42, 121},
+                {44, 108, 120},
+            },
+            {}, // state 84
+            {}, // state 85
+            {}, // state 86
+            { // state 87
+                {38, 127},
+                {42, 121},
+            },
+            { // state 88
+                {30, 108, 109},
+                {32, 104, 107},
+                {33, 100},
+                {34, 112, 114, 115, 116, 117, 119},
+                {35, 118, 122},
+                {36, 101, 102, 105, 125},
+                {38, 127},
+                {40, 108, 109},
+                {42, 121},
+            },
+            { // state 89
+                {29, 115},
+            },
+            { // state 90
+                {38, 127},
+                {42, 121},
+            },
+            {}, // state 91
+            { // state 92
+                {32, 104, 108, 120},
+                {33, 100},
+                {34, 112, 114, 115, 116, 117, 119},
+                {35, 118, 122},
+                {36, 101, 102, 105, 125},
+                {38, 127},
+                {42, 121},
+            },
+            { // state 93
+                {38, 127},
+                {42, 121},
+            },
+            { // state 94
+                {30, 108, 126},
+                {32, 104},
+                {33, 100},
+                {34, 112, 114, 115, 116, 117, 119},
+                {35, 118, 122},
+                {36, 101, 102, 105, 125},
+                {38, 127},
+                {42, 121},
+            },
+            {}, // state 95
+            {}, // state 96
+            {}, // state 97
+            {}, // state 98
+            {}, // state 99
+            {}, // state 100
+            {}, // state 101
+            {}, // state 102
+            {}, // state 103
+            {}, // state 104
+            {}, // state 105
+            {}, // state 106
+            { // state 107
+                {47, 120},
+            },
+            {}, // state 108
+            {}, // state 109
+            { // state 110
+                {32, 104},
+                {33, 100},
+                {34, 112, 114, 115, 116, 117, 119},
+                {35, 118, 122},
+                {36, 101, 102, 105, 125},
+                {38, 127},
+                {42, 121},
+            },
+            {}, // state 111
+            {}, // state 112
+            {}, // state 113
+            {}, // state 114
+            { // state 115
+                {33, 100},
+                {34, 112, 114, 115, 116, 117, 119},
+                {35, 118, 122},
+                {36, 101, 102, 105, 125},
+                {38, 127},
+                {42, 121},
+            },
+            {}, // state 116
+            { // state 117
+                {34, 112, 114, 115, 116, 117, 119},
+                {35, 118, 122},
+                {36, 101, 102, 105, 125},
+                {38, 127},
+                {42, 121},
+            },
+            {}, // state 118
+            { // state 119
+                {35, 118, 122},
+                {36, 101, 102, 105, 125},
+                {38, 127},
+                {42, 121},
+            },
+            { // state 120
+                {35, 118, 122},
+                {36, 101, 102, 105, 125},
+                {38, 127},
+                {42, 121},
+            },
+            { // state 121
+                {35, 118, 122},
+                {36, 101, 102, 105, 125},
+                {38, 127},
+                {42, 121},
+            },
+            { // state 122
+                {35, 118, 122},
+                {36, 101, 102, 105, 125},
+                {38, 127},
+                {42, 121},
+            },
+            { // state 123
+                {35, 118, 122},
+                {36, 101, 102, 105, 125},
+                {38, 127},
+                {42, 121},
+            },
+            { // state 124
+                {35, 118, 122},
+                {36, 101, 102, 105, 125},
+                {38, 127},
+                {42, 121},
+            },
+            {}, // state 125
+            { // state 126
+                {36, 101, 102, 105, 125},
+                {38, 127},
+                {42, 121},
+            },
+            { // state 127
+                {36, 101, 102, 105, 125},
+                {38, 127},
+                {42, 121},
+            },
+            {}, // state 128
+            { // state 129
+                {38, 127},
+                {42, 121},
+            },
+            { // state 130
+                {38, 127},
+                {42, 121},
+            },
+            { // state 131
+                {38, 127},
+                {42, 121},
+            },
+            { // state 132
+                {38, 127},
+                {42, 121},
+            },
+            {}, // state 133
+            {}, // state 134
+            {}, // state 135
+            {}, // state 136
+            {}, // state 137
+            {}, // state 138
+            {}, // state 139
+            {}, // state 140
+            {}, // state 141
+            {}, // state 142
+            { // state 143
+                {32, 104},
+                {33, 100},
+                {34, 112, 114, 115, 116, 117, 119},
+                {35, 118, 122},
+                {36, 101, 102, 105, 125},
+                {38, 127},
+                {42, 121},
+            },
+            {}, // state 144
+            { // state 145
+                {31, 107},
+                {32, 104, 126},
+                {33, 100},
+                {34, 112, 114, 115, 116, 117, 119},
+                {35, 118, 122},
+                {36, 101, 102, 105, 125},
+                {38, 127},
+                {42, 121},
+            },
+            {}, // state 146
+            {}, // state 147
+            { // state 148
+                {31, 126},
+                {32, 104},
+                {33, 100},
+                {34, 112, 114, 115, 116, 117, 119},
+                {35, 118, 122},
+                {36, 101, 102, 105, 125},
+                {38, 127},
+                {42, 121},
+            },
+            {}, // state 149
+            {}, // state 150
+            {}, // state 151
+            {}, // state 152
+            { // state 153
+                {32, 104},
+                {33, 100},
+                {34, 112, 114, 115, 116, 117, 119},
+                {35, 118, 122},
+                {36, 101, 102, 105, 125},
+                {38, 127},
+                {42, 121},
+            },
+            {}, // state 154
+            {}, // state 155
+            {}, // state 156
+            { // state 157
+                {47, 126},
+            },
+            { // state 158
+                {32, 104},
+                {33, 100},
+                {34, 112, 114, 115, 116, 117, 119},
+                {35, 118, 122},
+                {36, 101, 102, 105, 125},
+                {38, 127},
+                {42, 121},
+            },
+            {}, // state 159
+            {}, // state 160
+            {}, // state 161
+            {}, // state 162
+            {}, // state 163
+            { // state 164
+                {30, 108, 120},
+                {32, 104},
+                {33, 100},
+                {34, 112, 114, 115, 116, 117, 119},
+                {35, 118, 122},
+                {36, 101, 102, 105, 125},
+                {38, 127},
+                {42, 121},
+            },
+            {}, // state 165
+            { // state 166
+                {47, 120},
+            },
+            {}, // state 167
+            {}, // state 168
+            {}, // state 169
+            {}, // state 170
+            {}, // state 171
+            {}, // state 172
+            {}, // state 173
+            {}, // state 174
+            {}, // state 175
+            {}, // state 176
+            {}, // state 177
+            {}, // state 178
+            {}, // state 179
+            {}, // state 180
+            {}, // state 181
+            { // state 182
+                {42, 121},
+            },
+            {}, // state 183
+            { // state 184
+                {29, 108},
+            },
+            {}, // state 185
+            { // state 186
+                {29, 108},
+            },
+            {}, // state 187
+            { // state 188
+                {28, 108, 120},
+            },
+            {}, // state 189
+            {}, // state 190
+            {}, // state 191
+            {}, // state 192
+            {}, // state 193
+            {}, // state 194
+            { // state 195
+                {28, 108, 120},
+            },
+            {}, // state 196
+            {}, // state 197
+            {}, // state 198
+            {}, // state 199
+            {}, // state 200
+            {}, // state 201
+            {}, // state 202
+            { // state 203
+                {29, 107},
+            },
+            {}, // state 204
+            { // state 205
+                {29, 107},
+            },
+            {}, // state 206
+            { // state 207
+                {29, 120},
+            },
+            {}, // state 208
+            {}, // state 209
+            {}, // state 210
+            { // state 211
+                {29, 120},
+            },
+            {}, // state 212
+            {}, // state 213
+            {}, // state 214
+            {}, // state 215
+            {}, // state 216
+            {}, // state 217
+            {}, // state 218
+            {}, // state 219
+            {}, // state 220
+            {}, // state 221
+            {}, // state 222
+            { // state 223
+                {47, 109},
+            },
+            { // state 224
+                {47, 109},
+            },
+            { // state 225
+                {32, 104, 107},
+                {33, 100},
+                {34, 112, 114, 115, 116, 117, 119},
+                {35, 118, 122},
+                {36, 101, 102, 105, 125},
+                {38, 127},
+                {42, 121},
+            },
+            {}, // state 226
+            {}, // state 227
+            {}, // state 228
+            { // state 229
+                {32, 104},
+                {33, 100},
+                {34, 112, 114, 115, 116, 117, 119},
+                {35, 118, 122},
+                {36, 101, 102, 105, 125},
+                {38, 127},
+                {42, 121},
+            },
+            {}, // state 230
+            {}, // state 231
+            {}, // state 232
+            { // state 233
+                {32, 104},
+                {33, 100},
+                {34, 112, 114, 115, 116, 117, 119},
+                {35, 118, 122},
+                {36, 101, 102, 105, 125},
+                {38, 127},
+                {42, 121},
+            },
+            {}, // state 234
+            {}, // state 235
+        };
+    }
+
+    /** See {@code Parser.reducibleNonTerminals}. */
+    private static final class ReducibleNonTerminals {
+        /** See {@code Parser.reducibleNonTerminals}. */
+        private static final int[][][] REDUCIBLE_NON_TERMINALS = new int[][][] {
+            {}, // state 0
+            { // state 1
+                {0, 1},
+            },
+            { // state 2
+                {0, 1},
+            },
+            { // state 3
+                {0, 1},
+            },
+            { // state 4
+                {0, 1},
+            },
+            { // state 5
+                {1, 1},
+            },
+            { // state 6
+                {1, 1},
+            },
+            { // state 7
+                {1, 1},
+            },
+            { // state 8
+                {2, 1},
+            },
+            { // state 9
+                {2, 1},
+            },
+            { // state 10
+                {2, 1},
+            },
+            { // state 11
+                {2, 1},
+            },
+            { // state 12
+                {2, 1},
+            },
+            { // state 13
+                {2, 1},
+            },
+            { // state 14
+                {2, 1},
+            },
+            { // state 15
+                {2, 1},
+            },
+            { // state 16
+                {2, 1},
+            },
+            { // state 17
+                {2, 1},
+            },
+            { // state 18
+                {3, 1},
+            },
+            { // state 19
+                {3, 1},
+            },
+            { // state 20
+                {3, 1},
+            },
+            { // state 21
+                {3, 1},
+            },
+            { // state 22
+                {3, 1},
+            },
+            { // state 23
+                {3, 1},
+            },
+            { // state 24
+                {3, 1},
+            },
+            { // state 25
+                {3, 1},
+            },
+            { // state 26
+                {3, 1},
+            },
+            { // state 27
+                {3, 1},
+            },
+            { // state 28
+                {3, 1},
+            },
+            { // state 29
+                {3, 1},
+            },
+            { // state 30
+                {3, 1},
+            },
+            { // state 31
+                {3, 1},
+            },
+            { // state 32
+                {3, 1},
+            },
+            { // state 33
+                {3, 1},
+            },
+            { // state 34
+                {4, 1},
+            },
+            { // state 35
+                {4, 1},
+            },
+            { // state 36
+                {4, 1},
+            },
+            { // state 37
+                {4, 1},
+            },
+            { // state 38
+                {4, 1},
+            },
+            { // state 39
+                {4, 1},
+            },
+            { // state 40
+                {4, 1},
+            },
+            { // state 41
+                {4, 1},
+            },
+            { // state 42
+                {4, 1},
+            },
+            { // state 43
+                {4, 1},
+            },
+            { // state 44
+                {4, 1},
+            },
+            { // state 45
+                {4, 1},
+            },
+            { // state 46
+                {4, 1},
+            },
+            { // state 47
+                {4, 1},
+            },
+            { // state 48
+                {4, 1},
+            },
+            { // state 49
+                {4, 1},
+            },
+            { // state 50
+                {4, 1},
+            },
+            { // state 51
+                {4, 1},
+            },
+            { // state 52
+                {4, 1},
+            },
+            { // state 53
+                {4, 1},
+            },
+            { // state 54
+                {4, 1},
+            },
+            { // state 55
+                {4, 1},
+            },
+            { // state 56
+                {4, 1},
+            },
+            { // state 57
+                {4, 1},
+            },
+            { // state 58
+                {4, 1},
+            },
+            { // state 59
+                {4, 1},
+            },
+            { // state 60
+                {4, 1},
+            },
+            { // state 61
+                {4, 1},
+            },
+            { // state 62
+                {4, 1},
+            },
+            { // state 63
+                {4, 1},
+            },
+            { // state 64
+                {4, 1},
+            },
+            { // state 65
+                {4, 1},
+            },
+            { // state 66
+                {4, 1},
+            },
+            { // state 67
+                {4, 1},
+            },
+            { // state 68
+                {4, 1},
+            },
+            { // state 69
+                {4, 1},
+            },
+            { // state 70
+                {4, 1},
+            },
+            { // state 71
+                {4, 1},
+            },
+            { // state 72
+                {46, 1},
+            },
+            { // state 73
+                {46, 1},
+            },
+            { // state 74
+                {43, 1},
+            },
+            { // state 75
+                {43, 1},
+            },
+            { // state 76
+                {43, 1},
+            },
+            { // state 77
+                {43, 1},
+            },
+            { // state 78
+                {43, 1},
+            },
+            { // state 79
+                {42, 1},
+            },
+            { // state 80
+                {42, 1},
+            },
+            {}, // state 81
+            {}, // state 82
+            {}, // state 83
+            { // state 84
+                {39, 1},
+            },
+            { // state 85
+                {39, 1},
+            },
+            { // state 86
+                {39, 1},
+            },
+            {}, // state 87
+            {}, // state 88
+            {}, // state 89
+            {}, // state 90
+            { // state 91
+                {41, 3},
+            },
+            {}, // state 92
+            {}, // state 93
+            {}, // state 94
+            { // state 95
+                {46, 1},
+            },
+            { // state 96
+                {39, 1},
+            },
+            { // state 97
+                {39, 1},
+            },
+            { // state 98
+                {39, 1},
+            },
+            { // state 99
+                {34, 1},
+            },
+            { // state 100
+                {32, 1},
+            },
+            { // state 101
+                {33, 1},
+            },
+            { // state 102
+                {44, 1},
+            },
+            { // state 103
+                {38, 1},
+            },
+            { // state 104
+                {35, 1},
+            },
+            { // state 105
+                {39, 1},
+                {42, 1},
+            },
+            { // state 106
+                {37, 1},
+            },
+            { // state 107
+                {47, 0},
+            },
+            { // state 108
+                {39, 1},
+            },
+            { // state 109
+                {36, 1},
+            },
+            { // state 110
+                {47, 1},
+            },
+            {}, // state 111
+            { // state 112
+                {41, 5},
+            },
+            { // state 113
+                {46, 1},
+            },
+            { // state 114
+                {44, 3},
+            },
+            {}, // state 115
+            { // state 116
+                {32, 3},
+            },
+            {}, // state 117
+            { // state 118
+                {33, 3},
+            },
+            {}, // state 119
+            {}, // state 120
+            {}, // state 121
+            {}, // state 122
+            {}, // state 123
+            {}, // state 124
+            { // state 125
+                {34, 3},
+            },
+            {}, // state 126
+            {}, // state 127
+            { // state 128
+                {35, 3},
+            },
+            {}, // state 129
+            {}, // state 130
+            {}, // state 131
+            {}, // state 132
+            { // state 133
+                {36, 3},
+            },
+            { // state 134
+                {36, 3},
+            },
+            { // state 135
+                {36, 3},
+            },
+            { // state 136
+                {36, 3},
+            },
+            { // state 137
+                {35, 3},
+            },
+            { // state 138
+                {34, 3},
+            },
+            { // state 139
+                {34, 3},
+            },
+            { // state 140
+                {34, 3},
+            },
+            { // state 141
+                {34, 3},
+            },
+            { // state 142
+                {34, 3},
+            },
+            {}, // state 143
+            { // state 144
+                {44, 5},
+            },
+            { // state 145
+                {31, 0},
+            },
+            { // state 146
+                {31, 1},
+            },
+            {}, // state 147
+            { // state 148
+                {31, 0},
+            },
+            { // state 149
+                {31, 1},
+            },
+            {}, // state 150
+            { // state 151
+                {38, 6},
+            },
+            { // state 152
+                {38, 4},
+            },
+            {}, // state 153
+            { // state 154
+                {44, 3},
+            },
+            { // state 155
+                {39, 2},
+            },
+            { // state 156
+                {30, 1},
+            },
+            { // state 157
+                {47, 0},
+            },
+            { // state 158
+                {47, 1},
+            },
+            {}, // state 159
+            { // state 160
+                {39, 4},
+            },
+            { // state 161
+                {30, 3},
+            },
+            { // state 162
+                {37, 2},
+            },
+            {}, // state 163
+            {}, // state 164
+            { // state 165
+                {39, 3},
+            },
+            { // state 166
+                {47, 0},
+            },
+            {}, // state 167
+            { // state 168
+                {39, 6},
+            },
+            { // state 169
+                {37, 2},
+            },
+            { // state 170
+                {29, 1},
+            },
+            { // state 171
+                {29, 1},
+            },
+            { // state 172
+                {29, 1},
+            },
+            {}, // state 173
+            { // state 174
+                {29, 1},
+            },
+            {}, // state 175
+            { // state 176
+                {29, 1},
+            },
+            {}, // state 177
+            { // state 178
+                {29, 1},
+            },
+            {}, // state 179
+            { // state 180
+                {29, 1},
+            },
+            {}, // state 181
+            {}, // state 182
+            { // state 183
+                {39, 4},
+            },
+            {}, // state 184
+            {}, // state 185
+            {}, // state 186
+            {}, // state 187
+            {}, // state 188
+            { // state 189
+                {28, 1},
+            },
+            {}, // state 190
+            {}, // state 191
+            { // state 192
+                {29, 7},
+            },
+            { // state 193
+                {28, 3},
+            },
+            {}, // state 194
+            {}, // state 195
+            {}, // state 196
+            { // state 197
+                {29, 6},
+            },
+            { // state 198
+                {29, 2},
+            },
+            {}, // state 199
+            { // state 200
+                {29, 2},
+            },
+            { // state 201
+                {29, 3},
+            },
+            { // state 202
+                {29, 2},
+            },
+            {}, // state 203
+            {}, // state 204
+            {}, // state 205
+            {}, // state 206
+            {}, // state 207
+            {}, // state 208
+            { // state 209
+                {29, 7},
+            },
+            {}, // state 210
+            {}, // state 211
+            {}, // state 212
+            { // state 213
+                {29, 6},
+            },
+            { // state 214
+                {29, 2},
+            },
+            {}, // state 215
+            { // state 216
+                {29, 2},
+            },
+            { // state 217
+                {29, 3},
+            },
+            { // state 218
+                {29, 2},
+            },
+            { // state 219
+                {29, 2},
+            },
+            { // state 220
+                {29, 2},
+            },
+            { // state 221
+                {39, 2},
+            },
+            { // state 222
+                {30, 1},
+            },
+            { // state 223
+                {47, 0},
+            },
+            { // state 224
+                {47, 0},
+            },
+            { // state 225
+                {47, 1},
+            },
+            {}, // state 226
+            { // state 227
+                {39, 4},
+            },
+            {}, // state 228
+            {}, // state 229
+            { // state 230
+                {40, 5},
+            },
+            {}, // state 231
+            { // state 232
+                {39, 4},
+            },
+            {}, // state 233
+            { // state 234
+                {40, 3},
+            },
+            { // state 235
+                {37, 2},
+            },
+        };
+    }
+
+    /** See {@code Parser.reducibleNonTerminalsReduced}. */
+    private static final class ReducibleNonTerminalsReduced {
+        /** See {@code Parser.reducibleNonTerminalsReduced}. */
+        private static final int[][][] REDUCIBLE_NON_TERMINALS_REDUCED = new int[][][] {
+            { // state 0
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {4, 43, 0},
+                {43, 42, 0},
+                {46, 42, 0},
+            },
+            {}, // state 1
+            {}, // state 2
+            {}, // state 3
+            {}, // state 4
+            {}, // state 5
+            {}, // state 6
+            {}, // state 7
+            {}, // state 8
+            {}, // state 9
+            {}, // state 10
+            {}, // state 11
+            {}, // state 12
+            {}, // state 13
+            {}, // state 14
+            {}, // state 15
+            {}, // state 16
+            {}, // state 17
+            {}, // state 18
+            {}, // state 19
+            {}, // state 20
+            {}, // state 21
+            {}, // state 22
+            {}, // state 23
+            {}, // state 24
+            {}, // state 25
+            {}, // state 26
+            {}, // state 27
+            {}, // state 28
+            {}, // state 29
+            {}, // state 30
+            {}, // state 31
+            {}, // state 32
+            {}, // state 33
+            {}, // state 34
+            {}, // state 35
+            {}, // state 36
+            {}, // state 37
+            {}, // state 38
+            {}, // state 39
+            {}, // state 40
+            {}, // state 41
+            {}, // state 42
+            {}, // state 43
+            {}, // state 44
+            {}, // state 45
+            {}, // state 46
+            {}, // state 47
+            {}, // state 48
+            {}, // state 49
+            {}, // state 50
+            {}, // state 51
+            {}, // state 52
+            {}, // state 53
+            {}, // state 54
+            {}, // state 55
+            {}, // state 56
+            {}, // state 57
+            {}, // state 58
+            {}, // state 59
+            {}, // state 60
+            {}, // state 61
+            {}, // state 62
+            {}, // state 63
+            {}, // state 64
+            {}, // state 65
+            {}, // state 66
+            {}, // state 67
+            {}, // state 68
+            {}, // state 69
+            {}, // state 70
+            {}, // state 71
+            {}, // state 72
+            {}, // state 73
+            {}, // state 74
+            {}, // state 75
+            {}, // state 76
+            {}, // state 77
+            {}, // state 78
+            {}, // state 79
+            {}, // state 80
+            {}, // state 81
+            {}, // state 82
+            { // state 83
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {32, 44, 0},
+                {33, 32, 0},
+                {34, 33, 0},
+                {35, 34, 0},
+                {36, 35, 0},
+                {37, 36, 0},
+                {38, 37, 0},
+                {39, 38, 0},
+                {4, 43, 0},
+                {41, 39, 0},
+                {43, 42, 0},
+                {46, 39, 0},
+                {46, 42, 0},
+            },
+            {}, // state 84
+            {}, // state 85
+            {}, // state 86
+            { // state 87
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {37, 37, 1},
+                {38, 37, 0},
+                {39, 38, 0},
+                {4, 43, 0},
+                {41, 39, 0},
+                {43, 42, 0},
+                {46, 39, 0},
+                {46, 42, 0},
+            },
+            { // state 88
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {32, 30, 0},
+                {33, 32, 0},
+                {34, 33, 0},
+                {35, 34, 0},
+                {36, 35, 0},
+                {37, 36, 0},
+                {38, 37, 0},
+                {39, 38, 0},
+                {4, 43, 0},
+                {41, 39, 0},
+                {43, 42, 0},
+                {46, 39, 0},
+                {46, 42, 0},
+            },
+            { // state 89
+                {46, 29, 0},
+            },
+            { // state 90
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {37, 37, 1},
+                {38, 37, 0},
+                {39, 38, 0},
+                {4, 43, 0},
+                {41, 39, 0},
+                {43, 42, 0},
+                {46, 39, 0},
+                {46, 42, 0},
+            },
+            {}, // state 91
+            { // state 92
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {33, 32, 0},
+                {34, 33, 0},
+                {35, 34, 0},
+                {36, 35, 0},
+                {37, 36, 0},
+                {38, 37, 0},
+                {39, 38, 0},
+                {4, 43, 0},
+                {41, 39, 0},
+                {43, 42, 0},
+                {46, 39, 0},
+                {46, 42, 0},
+            },
+            { // state 93
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {37, 37, 1},
+                {38, 37, 0},
+                {39, 38, 0},
+                {4, 43, 0},
+                {41, 39, 0},
+                {43, 42, 0},
+                {46, 39, 0},
+                {46, 42, 0},
+            },
+            { // state 94
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {32, 30, 0},
+                {33, 32, 0},
+                {34, 33, 0},
+                {35, 34, 0},
+                {36, 35, 0},
+                {37, 36, 0},
+                {38, 37, 0},
+                {39, 38, 0},
+                {4, 43, 0},
+                {41, 39, 0},
+                {43, 42, 0},
+                {46, 39, 0},
+                {46, 42, 0},
+            },
+            {}, // state 95
+            {}, // state 96
+            {}, // state 97
+            {}, // state 98
+            {}, // state 99
+            {}, // state 100
+            {}, // state 101
+            {}, // state 102
+            {}, // state 103
+            {}, // state 104
+            {}, // state 105
+            {}, // state 106
+            {}, // state 107
+            {}, // state 108
+            {}, // state 109
+            { // state 110
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {32, 44, 2},
+                {33, 32, 0},
+                {34, 33, 0},
+                {35, 34, 0},
+                {36, 35, 0},
+                {37, 36, 0},
+                {38, 37, 0},
+                {39, 38, 0},
+                {4, 43, 0},
+                {41, 39, 0},
+                {43, 42, 0},
+                {46, 39, 0},
+                {46, 42, 0},
+            },
+            {}, // state 111
+            {}, // state 112
+            {}, // state 113
+            {}, // state 114
+            { // state 115
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {33, 32, 2},
+                {34, 33, 0},
+                {35, 34, 0},
+                {36, 35, 0},
+                {37, 36, 0},
+                {38, 37, 0},
+                {39, 38, 0},
+                {4, 43, 0},
+                {41, 39, 0},
+                {43, 42, 0},
+                {46, 39, 0},
+                {46, 42, 0},
+            },
+            {}, // state 116
+            { // state 117
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {34, 33, 2},
+                {35, 34, 0},
+                {36, 35, 0},
+                {37, 36, 0},
+                {38, 37, 0},
+                {39, 38, 0},
+                {4, 43, 0},
+                {41, 39, 0},
+                {43, 42, 0},
+                {46, 39, 0},
+                {46, 42, 0},
+            },
+            {}, // state 118
+            { // state 119
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {35, 34, 2},
+                {36, 35, 0},
+                {37, 36, 0},
+                {38, 37, 0},
+                {39, 38, 0},
+                {4, 43, 0},
+                {41, 39, 0},
+                {43, 42, 0},
+                {46, 39, 0},
+                {46, 42, 0},
+            },
+            { // state 120
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {35, 34, 2},
+                {36, 35, 0},
+                {37, 36, 0},
+                {38, 37, 0},
+                {39, 38, 0},
+                {4, 43, 0},
+                {41, 39, 0},
+                {43, 42, 0},
+                {46, 39, 0},
+                {46, 42, 0},
+            },
+            { // state 121
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {35, 34, 2},
+                {36, 35, 0},
+                {37, 36, 0},
+                {38, 37, 0},
+                {39, 38, 0},
+                {4, 43, 0},
+                {41, 39, 0},
+                {43, 42, 0},
+                {46, 39, 0},
+                {46, 42, 0},
+            },
+            { // state 122
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {35, 34, 2},
+                {36, 35, 0},
+                {37, 36, 0},
+                {38, 37, 0},
+                {39, 38, 0},
+                {4, 43, 0},
+                {41, 39, 0},
+                {43, 42, 0},
+                {46, 39, 0},
+                {46, 42, 0},
+            },
+            { // state 123
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {35, 34, 2},
+                {36, 35, 0},
+                {37, 36, 0},
+                {38, 37, 0},
+                {39, 38, 0},
+                {4, 43, 0},
+                {41, 39, 0},
+                {43, 42, 0},
+                {46, 39, 0},
+                {46, 42, 0},
+            },
+            { // state 124
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {35, 34, 2},
+                {36, 35, 0},
+                {37, 36, 0},
+                {38, 37, 0},
+                {39, 38, 0},
+                {4, 43, 0},
+                {41, 39, 0},
+                {43, 42, 0},
+                {46, 39, 0},
+                {46, 42, 0},
+            },
+            {}, // state 125
+            { // state 126
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {36, 35, 2},
+                {37, 36, 0},
+                {38, 37, 0},
+                {39, 38, 0},
+                {4, 43, 0},
+                {41, 39, 0},
+                {43, 42, 0},
+                {46, 39, 0},
+                {46, 42, 0},
+            },
+            { // state 127
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {36, 35, 2},
+                {37, 36, 0},
+                {38, 37, 0},
+                {39, 38, 0},
+                {4, 43, 0},
+                {41, 39, 0},
+                {43, 42, 0},
+                {46, 39, 0},
+                {46, 42, 0},
+            },
+            {}, // state 128
+            { // state 129
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {37, 36, 2},
+                {38, 37, 0},
+                {39, 38, 0},
+                {4, 43, 0},
+                {41, 39, 0},
+                {43, 42, 0},
+                {46, 39, 0},
+                {46, 42, 0},
+            },
+            { // state 130
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {37, 36, 2},
+                {38, 37, 0},
+                {39, 38, 0},
+                {4, 43, 0},
+                {41, 39, 0},
+                {43, 42, 0},
+                {46, 39, 0},
+                {46, 42, 0},
+            },
+            { // state 131
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {37, 36, 2},
+                {38, 37, 0},
+                {39, 38, 0},
+                {4, 43, 0},
+                {41, 39, 0},
+                {43, 42, 0},
+                {46, 39, 0},
+                {46, 42, 0},
+            },
+            { // state 132
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {37, 36, 2},
+                {38, 37, 0},
+                {39, 38, 0},
+                {4, 43, 0},
+                {41, 39, 0},
+                {43, 42, 0},
+                {46, 39, 0},
+                {46, 42, 0},
+            },
+            {}, // state 133
+            {}, // state 134
+            {}, // state 135
+            {}, // state 136
+            {}, // state 137
+            {}, // state 138
+            {}, // state 139
+            {}, // state 140
+            {}, // state 141
+            {}, // state 142
+            { // state 143
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {32, 44, 4},
+                {33, 32, 0},
+                {34, 33, 0},
+                {35, 34, 0},
+                {36, 35, 0},
+                {37, 36, 0},
+                {38, 37, 0},
+                {39, 38, 0},
+                {4, 43, 0},
+                {41, 39, 0},
+                {43, 42, 0},
+                {46, 39, 0},
+                {46, 42, 0},
+            },
+            {}, // state 144
+            { // state 145
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {32, 31, 0},
+                {33, 32, 0},
+                {34, 33, 0},
+                {35, 34, 0},
+                {36, 35, 0},
+                {37, 36, 0},
+                {38, 37, 0},
+                {39, 38, 0},
+                {4, 43, 0},
+                {41, 39, 0},
+                {43, 42, 0},
+                {46, 39, 0},
+                {46, 42, 0},
+            },
+            {}, // state 146
+            {}, // state 147
+            { // state 148
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {32, 31, 0},
+                {33, 32, 0},
+                {34, 33, 0},
+                {35, 34, 0},
+                {36, 35, 0},
+                {37, 36, 0},
+                {38, 37, 0},
+                {39, 38, 0},
+                {4, 43, 0},
+                {41, 39, 0},
+                {43, 42, 0},
+                {46, 39, 0},
+                {46, 42, 0},
+            },
+            {}, // state 149
+            {}, // state 150
+            {}, // state 151
+            {}, // state 152
+            { // state 153
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {32, 44, 2},
+                {33, 32, 0},
+                {34, 33, 0},
+                {35, 34, 0},
+                {36, 35, 0},
+                {37, 36, 0},
+                {38, 37, 0},
+                {39, 38, 0},
+                {4, 43, 0},
+                {41, 39, 0},
+                {43, 42, 0},
+                {46, 39, 0},
+                {46, 42, 0},
+            },
+            {}, // state 154
+            {}, // state 155
+            {}, // state 156
+            {}, // state 157
+            { // state 158
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {32, 30, 2},
+                {33, 32, 0},
+                {34, 33, 0},
+                {35, 34, 0},
+                {36, 35, 0},
+                {37, 36, 0},
+                {38, 37, 0},
+                {39, 38, 0},
+                {4, 43, 0},
+                {41, 39, 0},
+                {43, 42, 0},
+                {46, 39, 0},
+                {46, 42, 0},
+            },
+            {}, // state 159
+            {}, // state 160
+            {}, // state 161
+            {}, // state 162
+            {}, // state 163
+            { // state 164
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {32, 30, 0},
+                {33, 32, 0},
+                {34, 33, 0},
+                {35, 34, 0},
+                {36, 35, 0},
+                {37, 36, 0},
+                {38, 37, 0},
+                {39, 38, 0},
+                {4, 43, 0},
+                {41, 39, 0},
+                {43, 42, 0},
+                {46, 39, 0},
+                {46, 42, 0},
+            },
+            {}, // state 165
+            {}, // state 166
+            {}, // state 167
+            {}, // state 168
+            {}, // state 169
+            {}, // state 170
+            {}, // state 171
+            {}, // state 172
+            { // state 173
+                {29, 29, 1},
+                {46, 29, 0},
+            },
+            {}, // state 174
+            {}, // state 175
+            {}, // state 176
+            { // state 177
+                {29, 29, 1},
+                {46, 29, 0},
+            },
+            {}, // state 178
+            {}, // state 179
+            {}, // state 180
+            {}, // state 181
+            { // state 182
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {39, 39, 3},
+                {4, 43, 0},
+                {41, 39, 0},
+                {43, 42, 0},
+                {46, 39, 0},
+                {46, 42, 0},
+            },
+            {}, // state 183
+            { // state 184
+                {46, 29, 0},
+            },
+            {}, // state 185
+            { // state 186
+                {46, 29, 0},
+            },
+            {}, // state 187
+            { // state 188
+                {29, 28, 0},
+                {46, 29, 0},
+            },
+            {}, // state 189
+            {}, // state 190
+            { // state 191
+                {29, 28, 2},
+                {46, 29, 0},
+            },
+            {}, // state 192
+            {}, // state 193
+            {}, // state 194
+            { // state 195
+                {29, 28, 0},
+                {46, 29, 0},
+            },
+            {}, // state 196
+            {}, // state 197
+            {}, // state 198
+            { // state 199
+                {29, 29, 2},
+                {46, 29, 0},
+            },
+            {}, // state 200
+            {}, // state 201
+            {}, // state 202
+            { // state 203
+                {46, 29, 0},
+            },
+            {}, // state 204
+            { // state 205
+                {46, 29, 0},
+            },
+            {}, // state 206
+            { // state 207
+                {46, 29, 0},
+            },
+            {}, // state 208
+            {}, // state 209
+            {}, // state 210
+            { // state 211
+                {46, 29, 0},
+            },
+            {}, // state 212
+            {}, // state 213
+            {}, // state 214
+            { // state 215
+                {29, 29, 2},
+                {46, 29, 0},
+            },
+            {}, // state 216
+            {}, // state 217
+            {}, // state 218
+            {}, // state 219
+            {}, // state 220
+            {}, // state 221
+            {}, // state 222
+            {}, // state 223
+            {}, // state 224
+            { // state 225
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {33, 32, 0},
+                {34, 33, 0},
+                {35, 34, 0},
+                {36, 35, 0},
+                {37, 36, 0},
+                {38, 37, 0},
+                {39, 38, 0},
+                {4, 43, 0},
+                {41, 39, 0},
+                {43, 42, 0},
+                {46, 39, 0},
+                {46, 42, 0},
+            },
+            {}, // state 226
+            {}, // state 227
+            {}, // state 228
+            { // state 229
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {32, 40, 4},
+                {33, 32, 0},
+                {34, 33, 0},
+                {35, 34, 0},
+                {36, 35, 0},
+                {37, 36, 0},
+                {38, 37, 0},
+                {39, 38, 0},
+                {4, 43, 0},
+                {41, 39, 0},
+                {43, 42, 0},
+                {46, 39, 0},
+                {46, 42, 0},
+            },
+            {}, // state 230
+            {}, // state 231
+            {}, // state 232
+            { // state 233
+                {0, 43, 0},
+                {1, 43, 0},
+                {2, 43, 0},
+                {3, 43, 0},
+                {32, 40, 2},
+                {33, 32, 0},
+                {34, 33, 0},
+                {35, 34, 0},
+                {36, 35, 0},
+                {37, 36, 0},
+                {38, 37, 0},
+                {39, 38, 0},
+                {4, 43, 0},
+                {41, 39, 0},
+                {43, 42, 0},
+                {46, 39, 0},
+                {46, 42, 0},
+            },
+            {}, // state 234
+            {}, // state 235
+        };
+    }
+
+    /** Parser call back hooks for {@link ToolDefInvokeParser}. */
+    public interface Hooks extends ParserHooksBase {
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInIoTool : @ERRKW;}</p>
+         *
+         * @param t1 {@code ERRKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInIoTool1(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInIoTool : @ERRLNKW;}</p>
+         *
+         * @param t1 {@code ERRLNKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInIoTool2(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInIoTool : @OUTKW;}</p>
+         *
+         * @param t1 {@code OUTKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInIoTool3(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInIoTool : @OUTLNKW;}</p>
+         *
+         * @param t1 {@code OUTLNKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInIoTool4(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInGenericTool : @APPKW;}</p>
+         *
+         * @param t1 {@code APPKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInGenericTool1(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInGenericTool : @EXECKW;}</p>
+         *
+         * @param t1 {@code EXECKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInGenericTool2(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInGenericTool : @TOOLDEFKW;}</p>
+         *
+         * @param t1 {@code TOOLDEFKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInGenericTool3(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInPathTool : @ABSPATHKW;}</p>
+         *
+         * @param t1 {@code ABSPATHKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInPathTool01(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInPathTool : @BASENAMEKW;}</p>
+         *
+         * @param t1 {@code BASENAMEKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInPathTool02(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInPathTool : @CHDIRKW;}</p>
+         *
+         * @param t1 {@code CHDIRKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInPathTool03(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInPathTool : @CHFILEEXTKW;}</p>
+         *
+         * @param t1 {@code CHFILEEXTKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInPathTool04(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInPathTool : @CURDIRKW;}</p>
+         *
+         * @param t1 {@code CURDIRKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInPathTool05(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInPathTool : @DIRNAMEKW;}</p>
+         *
+         * @param t1 {@code DIRNAMEKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInPathTool06(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInPathTool : @FILEEXTKW;}</p>
+         *
+         * @param t1 {@code FILEEXTKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInPathTool07(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInPathTool : @HASFILEEXTKW;}</p>
+         *
+         * @param t1 {@code HASFILEEXTKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInPathTool08(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInPathTool : @PATHJOINKW;}</p>
+         *
+         * @param t1 {@code PATHJOINKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInPathTool09(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInPathTool : @SCRIPTPATHKW;}</p>
+         *
+         * @param t1 {@code SCRIPTPATHKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInPathTool10(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInFileTool : @CPDIRKW;}</p>
+         *
+         * @param t1 {@code CPDIRKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInFileTool01(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInFileTool : @CPFILEKW;}</p>
+         *
+         * @param t1 {@code CPFILEKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInFileTool02(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInFileTool : @DIFFKW;}</p>
+         *
+         * @param t1 {@code DIFFKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInFileTool03(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInFileTool : @EXISTSKW;}</p>
+         *
+         * @param t1 {@code EXISTSKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInFileTool04(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInFileTool : @FILENEWERKW;}</p>
+         *
+         * @param t1 {@code FILENEWERKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInFileTool05(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInFileTool : @FILESIZEKW;}</p>
+         *
+         * @param t1 {@code FILESIZEKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInFileTool06(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInFileTool : @FINDKW;}</p>
+         *
+         * @param t1 {@code FINDKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInFileTool07(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInFileTool : @ISDIRKW;}</p>
+         *
+         * @param t1 {@code ISDIRKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInFileTool08(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInFileTool : @ISFILEKW;}</p>
+         *
+         * @param t1 {@code ISFILEKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInFileTool09(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInFileTool : @MKDIRKW;}</p>
+         *
+         * @param t1 {@code MKDIRKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInFileTool10(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInFileTool : @MVDIRKW;}</p>
+         *
+         * @param t1 {@code MVDIRKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInFileTool11(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInFileTool : @MVFILEKW;}</p>
+         *
+         * @param t1 {@code MVFILEKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInFileTool12(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInFileTool : @READLINESKW;}</p>
+         *
+         * @param t1 {@code READLINESKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInFileTool13(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInFileTool : @RMDIRKW;}</p>
+         *
+         * @param t1 {@code RMDIRKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInFileTool14(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInFileTool : @RMFILEKW;}</p>
+         *
+         * @param t1 {@code RMFILEKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInFileTool15(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInFileTool : @WRITEFILEKW;}</p>
+         *
+         * @param t1 {@code WRITEFILEKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInFileTool16(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @ABSKW;}</p>
+         *
+         * @param t1 {@code ABSKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool01(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @CEILKW;}</p>
+         *
+         * @param t1 {@code CEILKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool02(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @CONTAINSKW;}</p>
+         *
+         * @param t1 {@code CONTAINSKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool03(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @DELKW;}</p>
+         *
+         * @param t1 {@code DELKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool04(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @DELIDXKW;}</p>
+         *
+         * @param t1 {@code DELIDXKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool05(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @EMPTYKW;}</p>
+         *
+         * @param t1 {@code EMPTYKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool06(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @ENDSWITHKW;}</p>
+         *
+         * @param t1 {@code ENDSWITHKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool07(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @ENTRIESKW;}</p>
+         *
+         * @param t1 {@code ENTRIESKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool08(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @ENUMERATEKW;}</p>
+         *
+         * @param t1 {@code ENUMERATEKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool09(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @FLOORKW;}</p>
+         *
+         * @param t1 {@code FLOORKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool10(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @FMTKW;}</p>
+         *
+         * @param t1 {@code FMTKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool11(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @INDEXOFKW;}</p>
+         *
+         * @param t1 {@code INDEXOFKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool12(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @JOINKW;}</p>
+         *
+         * @param t1 {@code JOINKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool13(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @KEYSKW;}</p>
+         *
+         * @param t1 {@code KEYSKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool14(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @LASTINDEXOFKW;}</p>
+         *
+         * @param t1 {@code LASTINDEXOFKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool15(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @LNKW;}</p>
+         *
+         * @param t1 {@code LNKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool16(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @LOGKW;}</p>
+         *
+         * @param t1 {@code LOGKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool17(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @LOWERKW;}</p>
+         *
+         * @param t1 {@code LOWERKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool18(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @LTRIMKW;}</p>
+         *
+         * @param t1 {@code LTRIMKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool19(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @MAXKW;}</p>
+         *
+         * @param t1 {@code MAXKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool20(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @MINKW;}</p>
+         *
+         * @param t1 {@code MINKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool21(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @POWKW;}</p>
+         *
+         * @param t1 {@code POWKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool22(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @RANGEKW;}</p>
+         *
+         * @param t1 {@code RANGEKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool23(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @REPLACEKW;}</p>
+         *
+         * @param t1 {@code REPLACEKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool24(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @REVERSEKW;}</p>
+         *
+         * @param t1 {@code REVERSEKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool25(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @ROUNDKW;}</p>
+         *
+         * @param t1 {@code ROUNDKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool26(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @RTRIMKW;}</p>
+         *
+         * @param t1 {@code RTRIMKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool27(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @SIZEKW;}</p>
+         *
+         * @param t1 {@code SIZEKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool28(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @SORTEDKW;}</p>
+         *
+         * @param t1 {@code SORTEDKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool29(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @SPLITKW;}</p>
+         *
+         * @param t1 {@code SPLITKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool30(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @SQRTKW;}</p>
+         *
+         * @param t1 {@code SQRTKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool31(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @STARTSWITHKW;}</p>
+         *
+         * @param t1 {@code STARTSWITHKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool32(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @STRKW;}</p>
+         *
+         * @param t1 {@code STRKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool33(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @STRDUPKW;}</p>
+         *
+         * @param t1 {@code STRDUPKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool34(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @SUBSETKW;}</p>
+         *
+         * @param t1 {@code SUBSETKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool35(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @TRIMKW;}</p>
+         *
+         * @param t1 {@code TRIMKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool36(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @UPPERKW;}</p>
+         *
+         * @param t1 {@code UPPERKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool37(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInDataTool : @VALUESKW;}</p>
+         *
+         * @param t1 {@code VALUESKW}.
+         * @return The parser call back hook result.
+         */
+        public Token parseBuiltInDataTool38(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code Types : Type;}</p>
+         *
+         * @param t1 {@code Type}.
+         * @return The parser call back hook result.
+         */
+        public List<ToolDefType> parseTypes1(ToolDefType t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code Types : Types COMMATK Type;}</p>
+         *
+         * @param l1 {@code Types}.
+         * @param t3 {@code Type}.
+         * @return The parser call back hook result.
+         */
+        public List<ToolDefType> parseTypes2(List<ToolDefType> l1, ToolDefType t3);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code Type : @BOOLKW;}</p>
+         *
+         * @param t1 {@code BOOLKW}.
+         * @return The parser call back hook result.
+         */
+        public ToolDefType parseType01(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code Type : @BOOLKW QUESTIONTK;}</p>
+         *
+         * @param t1 {@code BOOLKW}.
+         * @return The parser call back hook result.
+         */
+        public ToolDefType parseType02(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code Type : @INTKW;}</p>
+         *
+         * @param t1 {@code INTKW}.
+         * @return The parser call back hook result.
+         */
+        public ToolDefType parseType03(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code Type : @INTKW QUESTIONTK;}</p>
+         *
+         * @param t1 {@code INTKW}.
+         * @return The parser call back hook result.
+         */
+        public ToolDefType parseType04(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code Type : @LONGKW;}</p>
+         *
+         * @param t1 {@code LONGKW}.
+         * @return The parser call back hook result.
+         */
+        public ToolDefType parseType05(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code Type : @LONGKW QUESTIONTK;}</p>
+         *
+         * @param t1 {@code LONGKW}.
+         * @return The parser call back hook result.
+         */
+        public ToolDefType parseType06(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code Type : @DOUBLEKW;}</p>
+         *
+         * @param t1 {@code DOUBLEKW}.
+         * @return The parser call back hook result.
+         */
+        public ToolDefType parseType07(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code Type : @DOUBLEKW QUESTIONTK;}</p>
+         *
+         * @param t1 {@code DOUBLEKW}.
+         * @return The parser call back hook result.
+         */
+        public ToolDefType parseType08(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code Type : @STRINGKW;}</p>
+         *
+         * @param t1 {@code STRINGKW}.
+         * @return The parser call back hook result.
+         */
+        public ToolDefType parseType09(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code Type : @STRINGKW QUESTIONTK;}</p>
+         *
+         * @param t1 {@code STRINGKW}.
+         * @return The parser call back hook result.
+         */
+        public ToolDefType parseType10(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code Type : @LISTKW Type;}</p>
+         *
+         * @param t1 {@code LISTKW}.
+         * @param t2 {@code Type}.
+         * @return The parser call back hook result.
+         */
+        public ToolDefType parseType11(Token t1, ToolDefType t2);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code Type : @LISTKW QUESTIONTK Type;}</p>
+         *
+         * @param t1 {@code LISTKW}.
+         * @param t3 {@code Type}.
+         * @return The parser call back hook result.
+         */
+        public ToolDefType parseType12(Token t1, ToolDefType t3);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code Type : @SETKW Type;}</p>
+         *
+         * @param t1 {@code SETKW}.
+         * @param t2 {@code Type}.
+         * @return The parser call back hook result.
+         */
+        public ToolDefType parseType13(Token t1, ToolDefType t2);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code Type : @SETKW QUESTIONTK Type;}</p>
+         *
+         * @param t1 {@code SETKW}.
+         * @param t3 {@code Type}.
+         * @return The parser call back hook result.
+         */
+        public ToolDefType parseType14(Token t1, ToolDefType t3);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code Type : @MAPKW PAROPENTK Type COLONTK Type PARCLOSETK;}</p>
+         *
+         * @param t1 {@code MAPKW}.
+         * @param t3 {@code Type}.
+         * @param t5 {@code Type}.
+         * @return The parser call back hook result.
+         */
+        public ToolDefType parseType15(Token t1, ToolDefType t3, ToolDefType t5);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code Type : @MAPKW QUESTIONTK PAROPENTK Type COLONTK Type PARCLOSETK;}</p>
+         *
+         * @param t1 {@code MAPKW}.
+         * @param t4 {@code Type}.
+         * @param t6 {@code Type}.
+         * @return The parser call back hook result.
+         */
+        public ToolDefType parseType16(Token t1, ToolDefType t4, ToolDefType t6);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code Type : @TUPLEKW PAROPENTK Type COMMATK Types PARCLOSETK;}</p>
+         *
+         * @param t1 {@code TUPLEKW}.
+         * @param t3 {@code Type}.
+         * @param l5 {@code Types}.
+         * @return The parser call back hook result.
+         */
+        public ToolDefType parseType17(Token t1, ToolDefType t3, List<ToolDefType> l5);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code Type : @TUPLEKW QUESTIONTK PAROPENTK Type COMMATK Types PARCLOSETK;}</p>
+         *
+         * @param t1 {@code TUPLEKW}.
+         * @param t4 {@code Type}.
+         * @param l6 {@code Types}.
+         * @return The parser call back hook result.
+         */
+        public ToolDefType parseType18(Token t1, ToolDefType t4, List<ToolDefType> l6);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code Type : @OBJECTKW;}</p>
+         *
+         * @param t1 {@code OBJECTKW}.
+         * @return The parser call back hook result.
+         */
+        public ToolDefType parseType19(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code Type : @OBJECTKW QUESTIONTK;}</p>
+         *
+         * @param t1 {@code OBJECTKW}.
+         * @return The parser call back hook result.
+         */
+        public ToolDefType parseType20(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code Type : Name;}</p>
+         *
+         * @param t1 {@code Name}.
+         * @return The parser call back hook result.
+         */
+        public ToolDefType parseType21(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code Expressions : Expression;}</p>
+         *
+         * @param e1 {@code Expression}.
+         * @return The parser call back hook result.
+         */
+        public List<Expression> parseExpressions1(Expression e1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code Expressions : Expressions COMMATK Expression;}</p>
+         *
+         * @param l1 {@code Expressions}.
+         * @param e3 {@code Expression}.
+         * @return The parser call back hook result.
+         */
+        public List<Expression> parseExpressions2(List<Expression> l1, Expression e3);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code OptExpression : ;}</p>
+         *
+         * @return The parser call back hook result.
+         */
+        public Expression parseOptExpression1();
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code OptExpression : Expression;}</p>
+         *
+         * @param e1 {@code Expression}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseOptExpression2(Expression e1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code Expression : AndExpression;}</p>
+         *
+         * @param e1 {@code AndExpression}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseExpression1(Expression e1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code Expression : Expression @ORKW AndExpression;}</p>
+         *
+         * @param e1 {@code Expression}.
+         * @param t2 {@code ORKW}.
+         * @param e3 {@code AndExpression}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseExpression2(Expression e1, Token t2, Expression e3);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code AndExpression : CompareExpression;}</p>
+         *
+         * @param e1 {@code CompareExpression}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseAndExpression1(Expression e1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code AndExpression : AndExpression @ANDKW CompareExpression;}</p>
+         *
+         * @param e1 {@code AndExpression}.
+         * @param t2 {@code ANDKW}.
+         * @param e3 {@code CompareExpression}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseAndExpression2(Expression e1, Token t2, Expression e3);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code CompareExpression : AddExpression;}</p>
+         *
+         * @param e1 {@code AddExpression}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseCompareExpression1(Expression e1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code CompareExpression : CompareExpression @LTTK AddExpression;}</p>
+         *
+         * @param e1 {@code CompareExpression}.
+         * @param t2 {@code LTTK}.
+         * @param e3 {@code AddExpression}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseCompareExpression2(Expression e1, Token t2, Expression e3);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code CompareExpression : CompareExpression @LETK AddExpression;}</p>
+         *
+         * @param e1 {@code CompareExpression}.
+         * @param t2 {@code LETK}.
+         * @param e3 {@code AddExpression}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseCompareExpression3(Expression e1, Token t2, Expression e3);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code CompareExpression : CompareExpression @EQEQTK AddExpression;}</p>
+         *
+         * @param e1 {@code CompareExpression}.
+         * @param t2 {@code EQEQTK}.
+         * @param e3 {@code AddExpression}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseCompareExpression4(Expression e1, Token t2, Expression e3);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code CompareExpression : CompareExpression @NETK AddExpression;}</p>
+         *
+         * @param e1 {@code CompareExpression}.
+         * @param t2 {@code NETK}.
+         * @param e3 {@code AddExpression}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseCompareExpression5(Expression e1, Token t2, Expression e3);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code CompareExpression : CompareExpression @GETK AddExpression;}</p>
+         *
+         * @param e1 {@code CompareExpression}.
+         * @param t2 {@code GETK}.
+         * @param e3 {@code AddExpression}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseCompareExpression6(Expression e1, Token t2, Expression e3);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code CompareExpression : CompareExpression @GTTK AddExpression;}</p>
+         *
+         * @param e1 {@code CompareExpression}.
+         * @param t2 {@code GTTK}.
+         * @param e3 {@code AddExpression}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseCompareExpression7(Expression e1, Token t2, Expression e3);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code AddExpression : MulExpression;}</p>
+         *
+         * @param e1 {@code MulExpression}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseAddExpression1(Expression e1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code AddExpression : AddExpression @MINUSTK MulExpression;}</p>
+         *
+         * @param e1 {@code AddExpression}.
+         * @param t2 {@code MINUSTK}.
+         * @param e3 {@code MulExpression}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseAddExpression2(Expression e1, Token t2, Expression e3);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code AddExpression : AddExpression @PLUSTK MulExpression;}</p>
+         *
+         * @param e1 {@code AddExpression}.
+         * @param t2 {@code PLUSTK}.
+         * @param e3 {@code MulExpression}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseAddExpression3(Expression e1, Token t2, Expression e3);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code MulExpression : UnaryExpression;}</p>
+         *
+         * @param e1 {@code UnaryExpression}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseMulExpression1(Expression e1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code MulExpression : MulExpression @ASTERISKTK UnaryExpression;}</p>
+         *
+         * @param e1 {@code MulExpression}.
+         * @param t2 {@code ASTERISKTK}.
+         * @param e3 {@code UnaryExpression}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseMulExpression2(Expression e1, Token t2, Expression e3);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code MulExpression : MulExpression @SLASHTK UnaryExpression;}</p>
+         *
+         * @param e1 {@code MulExpression}.
+         * @param t2 {@code SLASHTK}.
+         * @param e3 {@code UnaryExpression}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseMulExpression3(Expression e1, Token t2, Expression e3);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code MulExpression : MulExpression @DIVKW UnaryExpression;}</p>
+         *
+         * @param e1 {@code MulExpression}.
+         * @param t2 {@code DIVKW}.
+         * @param e3 {@code UnaryExpression}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseMulExpression4(Expression e1, Token t2, Expression e3);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code MulExpression : MulExpression @MODKW UnaryExpression;}</p>
+         *
+         * @param e1 {@code MulExpression}.
+         * @param t2 {@code MODKW}.
+         * @param e3 {@code UnaryExpression}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseMulExpression5(Expression e1, Token t2, Expression e3);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code UnaryExpression : ProjExpression;}</p>
+         *
+         * @param e1 {@code ProjExpression}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseUnaryExpression1(Expression e1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code UnaryExpression : @MINUSTK UnaryExpression;}</p>
+         *
+         * @param t1 {@code MINUSTK}.
+         * @param e2 {@code UnaryExpression}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseUnaryExpression2(Token t1, Expression e2);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code UnaryExpression : @PLUSTK UnaryExpression;}</p>
+         *
+         * @param t1 {@code PLUSTK}.
+         * @param e2 {@code UnaryExpression}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseUnaryExpression3(Token t1, Expression e2);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code UnaryExpression : @NOTKW UnaryExpression;}</p>
+         *
+         * @param t1 {@code NOTKW}.
+         * @param e2 {@code UnaryExpression}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseUnaryExpression4(Token t1, Expression e2);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code ProjExpression : ExpressionFactor;}</p>
+         *
+         * @param e1 {@code ExpressionFactor}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseProjExpression1(Expression e1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code ProjExpression : ProjExpression @SQOPENTK Expression SQCLOSETK;}</p>
+         *
+         * @param e1 {@code ProjExpression}.
+         * @param t2 {@code SQOPENTK}.
+         * @param e3 {@code Expression}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseProjExpression2(Expression e1, Token t2, Expression e3);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code ProjExpression : ProjExpression @SQOPENTK OptExpression COLONTK OptExpression SQCLOSETK;}</p>
+         *
+         * @param e1 {@code ProjExpression}.
+         * @param t2 {@code SQOPENTK}.
+         * @param e3 {@code OptExpression}.
+         * @param e5 {@code OptExpression}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseProjExpression3(Expression e1, Token t2, Expression e3, Expression e5);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code ExpressionFactor : @TRUEKW;}</p>
+         *
+         * @param t1 {@code TRUEKW}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseExpressionFactor01(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code ExpressionFactor : @FALSEKW;}</p>
+         *
+         * @param t1 {@code FALSEKW}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseExpressionFactor02(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code ExpressionFactor : @NUMBERTK;}</p>
+         *
+         * @param t1 {@code NUMBERTK}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseExpressionFactor03(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code ExpressionFactor : @DOUBLETK;}</p>
+         *
+         * @param t1 {@code DOUBLETK}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseExpressionFactor04(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code ExpressionFactor : @NULLKW;}</p>
+         *
+         * @param t1 {@code NULLKW}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseExpressionFactor05(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code ExpressionFactor : @STRINGTK;}</p>
+         *
+         * @param t1 {@code STRINGTK}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseExpressionFactor06(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code ExpressionFactor : @LTTK Type GTTK ExpressionFactor;}</p>
+         *
+         * @param t1 {@code LTTK}.
+         * @param t2 {@code Type}.
+         * @param e4 {@code ExpressionFactor}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseExpressionFactor07(Token t1, ToolDefType t2, Expression e4);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code ExpressionFactor : @SQOPENTK SQCLOSETK;}</p>
+         *
+         * @param t1 {@code SQOPENTK}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseExpressionFactor08(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code ExpressionFactor : @SQOPENTK Expressions OptComma SQCLOSETK;}</p>
+         *
+         * @param t1 {@code SQOPENTK}.
+         * @param l2 {@code Expressions}.
+         * @param t3 {@code OptComma}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseExpressionFactor09(Token t1, List<Expression> l2, Token t3);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code ExpressionFactor : @CUROPENTK CURCLOSETK;}</p>
+         *
+         * @param t1 {@code CUROPENTK}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseExpressionFactor10(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code ExpressionFactor : @CUROPENTK Expressions OptComma CURCLOSETK;}</p>
+         *
+         * @param t1 {@code CUROPENTK}.
+         * @param l2 {@code Expressions}.
+         * @param t3 {@code OptComma}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseExpressionFactor11(Token t1, List<Expression> l2, Token t3);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code ExpressionFactor : @CUROPENTK MapEntries OptComma CURCLOSETK;}</p>
+         *
+         * @param t1 {@code CUROPENTK}.
+         * @param l2 {@code MapEntries}.
+         * @param t3 {@code OptComma}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseExpressionFactor12(Token t1, List<MapEntry> l2, Token t3);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code ExpressionFactor : @PAROPENTK Expression COMMATK Expressions OptComma PARCLOSETK;}</p>
+         *
+         * @param t1 {@code PAROPENTK}.
+         * @param e2 {@code Expression}.
+         * @param l4 {@code Expressions}.
+         * @param t5 {@code OptComma}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseExpressionFactor13(Token t1, Expression e2, List<Expression> l4, Token t5);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code ExpressionFactor : PAROPENTK Expression PARCLOSETK;}</p>
+         *
+         * @param e2 {@code Expression}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseExpressionFactor14(Expression e2);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code ExpressionFactor : ToolInvokeExpression;}</p>
+         *
+         * @param t1 {@code ToolInvokeExpression}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseExpressionFactor15(ToolInvokeExpression t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code ExpressionFactor : Name;}</p>
+         *
+         * @param t1 {@code Name}.
+         * @return The parser call back hook result.
+         */
+        public Expression parseExpressionFactor16(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code MapEntries : Expression @COLONTK Expression;}</p>
+         *
+         * @param e1 {@code Expression}.
+         * @param t2 {@code COLONTK}.
+         * @param e3 {@code Expression}.
+         * @return The parser call back hook result.
+         */
+        public List<MapEntry> parseMapEntries1(Expression e1, Token t2, Expression e3);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code MapEntries : MapEntries COMMATK Expression @COLONTK Expression;}</p>
+         *
+         * @param l1 {@code MapEntries}.
+         * @param e3 {@code Expression}.
+         * @param t4 {@code COLONTK}.
+         * @param e5 {@code Expression}.
+         * @return The parser call back hook result.
+         */
+        public List<MapEntry> parseMapEntries2(List<MapEntry> l1, Expression e3, Token t4, Expression e5);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code ToolInvokeExpression : ToolRef @PAROPENTK ToolArgs OptComma PARCLOSETK;}</p>
+         *
+         * @param t1 {@code ToolRef}.
+         * @param t2 {@code PAROPENTK}.
+         * @param l3 {@code ToolArgs}.
+         * @param t4 {@code OptComma}.
+         * @return The parser call back hook result.
+         */
+        public ToolInvokeExpression parseToolInvokeExpression1(ToolRef t1, Token t2, List<ToolArgument> l3, Token t4);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code ToolInvokeExpression : ToolRef @PAROPENTK PARCLOSETK;}</p>
+         *
+         * @param t1 {@code ToolRef}.
+         * @param t2 {@code PAROPENTK}.
+         * @return The parser call back hook result.
+         */
+        public ToolInvokeExpression parseToolInvokeExpression2(ToolRef t1, Token t2);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code ToolRef : BuiltInTool;}</p>
+         *
+         * @param t1 {@code BuiltInTool}.
+         * @return The parser call back hook result.
+         */
+        public ToolRef parseToolRef1(ToolRef t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code ToolRef : Name;}</p>
+         *
+         * @param t1 {@code Name}.
+         * @return The parser call back hook result.
+         */
+        public ToolRef parseToolRef2(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInTool : BuiltInIoTool;}</p>
+         *
+         * @param t1 {@code BuiltInIoTool}.
+         * @return The parser call back hook result.
+         */
+        public ToolRef parseBuiltInTool1(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInTool : BuiltInGenericTool;}</p>
+         *
+         * @param t1 {@code BuiltInGenericTool}.
+         * @return The parser call back hook result.
+         */
+        public ToolRef parseBuiltInTool2(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInTool : BuiltInPathTool;}</p>
+         *
+         * @param t1 {@code BuiltInPathTool}.
+         * @return The parser call back hook result.
+         */
+        public ToolRef parseBuiltInTool3(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInTool : BuiltInFileTool;}</p>
+         *
+         * @param t1 {@code BuiltInFileTool}.
+         * @return The parser call back hook result.
+         */
+        public ToolRef parseBuiltInTool4(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code BuiltInTool : BuiltInDataTool;}</p>
+         *
+         * @param t1 {@code BuiltInDataTool}.
+         * @return The parser call back hook result.
+         */
+        public ToolRef parseBuiltInTool5(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code ToolArgs : Expression;}</p>
+         *
+         * @param e1 {@code Expression}.
+         * @return The parser call back hook result.
+         */
+        public List<ToolArgument> parseToolArgs1(Expression e1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code ToolArgs : @IDENTIFIERTK EQTK Expression;}</p>
+         *
+         * @param t1 {@code IDENTIFIERTK}.
+         * @param e3 {@code Expression}.
+         * @return The parser call back hook result.
+         */
+        public List<ToolArgument> parseToolArgs2(Token t1, Expression e3);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code ToolArgs : ToolArgs COMMATK Expression;}</p>
+         *
+         * @param l1 {@code ToolArgs}.
+         * @param e3 {@code Expression}.
+         * @return The parser call back hook result.
+         */
+        public List<ToolArgument> parseToolArgs3(List<ToolArgument> l1, Expression e3);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code ToolArgs : ToolArgs COMMATK @IDENTIFIERTK EQTK Expression;}</p>
+         *
+         * @param l1 {@code ToolArgs}.
+         * @param t3 {@code IDENTIFIERTK}.
+         * @param e5 {@code Expression}.
+         * @return The parser call back hook result.
+         */
+        public List<ToolArgument> parseToolArgs4(List<ToolArgument> l1, Token t3, Expression e5);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code Name : @IDENTIFIERTK;}</p>
+         *
+         * @param t1 {@code IDENTIFIERTK}.
+         * @return The parser call back hook result.
+         */
+        public Token parseName1(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code Name : @RELATIVENAMETK;}</p>
+         *
+         * @param t1 {@code RELATIVENAMETK}.
+         * @return The parser call back hook result.
+         */
+        public Token parseName2(Token t1);
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code OptComma : ;}</p>
+         *
+         * @return The parser call back hook result.
+         */
+        public Token parseOptComma1();
+
+        /**
+         * Parser call back hook for rule/production:
+         *
+         * <p>{@code OptComma : @COMMATK;}</p>
+         *
+         * @param t1 {@code COMMATK}.
+         * @return The parser call back hook result.
+         */
+        public Token parseOptComma2(Token t1);
+    }
+}
diff --git a/tooldef/org.eclipse.escet.tooldef.parser/src/org/eclipse/escet/tooldef/parser/ToolDefHooks.java b/tooldef/org.eclipse.escet.tooldef.parser/src/org/eclipse/escet/tooldef/parser/ToolDefHooks.java
index 46805b9172f784ef6d0d3379af20f2643166df21..f4e0cc222348aa7a6a804d1eb9934c35d61daf1c 100644
--- a/tooldef/org.eclipse.escet.tooldef.parser/src/org/eclipse/escet/tooldef/parser/ToolDefHooks.java
+++ b/tooldef/org.eclipse.escet.tooldef.parser/src/org/eclipse/escet/tooldef/parser/ToolDefHooks.java
@@ -97,9 +97,10 @@ import org.eclipse.escet.tooldef.metamodel.tooldef.types.ToolDefType;
  * <ul>
  * <li>{@link ToolDefScanner}</li>
  * <li>{@link ToolDefParser}</li>
+ * <li>{@link ToolDefInvokeParser}</li>
  * </ul>
  */
-public final class ToolDefHooks implements ToolDefScanner.Hooks, ToolDefParser.Hooks {
+public final class ToolDefHooks implements ToolDefScanner.Hooks, ToolDefParser.Hooks, ToolDefInvokeParser.Hooks {
     /** The parser that owns the call back hooks. */
     private Parser<?> parser;
 
diff --git a/tooldef/org.eclipse.escet.tooldef.parser/src/org/eclipse/escet/tooldef/parser/tooldef.setext b/tooldef/org.eclipse.escet.tooldef.parser/src/org/eclipse/escet/tooldef/parser/tooldef.setext
index 4e50e825d8c0036cabf3d246ad10094b83a71e7b..bf54a4022417a5aaf634462c0168dd13a3779cd8 100644
--- a/tooldef/org.eclipse.escet.tooldef.parser/src/org/eclipse/escet/tooldef/parser/tooldef.setext
+++ b/tooldef/org.eclipse.escet.tooldef.parser/src/org/eclipse/escet/tooldef/parser/tooldef.setext
@@ -188,6 +188,7 @@ end
 end
 
 @main Script : org.eclipse.escet.tooldef.parser.ToolDefParser;
+@start ToolInvokeExpression: org.eclipse.escet.tooldef.parser.ToolDefInvokeParser;
 
 @import java.util.List;
 @import org.eclipse.escet.tooldef.metamodel.tooldef;
diff --git a/tooldef/org.eclipse.escet.tooldef.runtime/.settings/org.eclipse.jdt.core.prefs b/tooldef/org.eclipse.escet.tooldef.runtime/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/tooldef/org.eclipse.escet.tooldef.runtime/.settings/org.eclipse.jdt.core.prefs
+++ b/tooldef/org.eclipse.escet.tooldef.runtime/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/tooldef/org.eclipse.escet.tooldef.runtime/.settings/org.eclipse.jdt.ui.prefs b/tooldef/org.eclipse.escet.tooldef.runtime/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/tooldef/org.eclipse.escet.tooldef.runtime/.settings/org.eclipse.jdt.ui.prefs
+++ b/tooldef/org.eclipse.escet.tooldef.runtime/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/tooldef/org.eclipse.escet.tooldef.runtime/.settings/org.eclipse.ltk.core.refactoring.prefs b/tooldef/org.eclipse.escet.tooldef.runtime/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/tooldef/org.eclipse.escet.tooldef.runtime/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/tooldef/org.eclipse.escet.tooldef.runtime/META-INF/MANIFEST.MF b/tooldef/org.eclipse.escet.tooldef.runtime/META-INF/MANIFEST.MF
index 1c13e03a078f2ee2e0be832c10d8ed3a2cdd6655..ce550ed13376df8c52cf0e5d5f89eb94b4f38118 100644
--- a/tooldef/org.eclipse.escet.tooldef.runtime/META-INF/MANIFEST.MF
+++ b/tooldef/org.eclipse.escet.tooldef.runtime/META-INF/MANIFEST.MF
@@ -2,15 +2,15 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET ToolDef Runtime (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.tooldef.runtime;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
  org.apache.commons.lang3;bundle-version="3.1.0",
- org.eclipse.escet.tooldef.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.tooldef.metamodel.java;bundle-version="0.9.0",
- org.eclipse.escet.tooldef.common;bundle-version="0.9.0",
+ org.eclipse.escet.tooldef.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.tooldef.metamodel.java;bundle-version="0.10.0",
+ org.eclipse.escet.tooldef.common;bundle-version="0.10.0",
  org.eclipse.core.runtime;bundle-version="3.17.0",
  org.apache.commons.exec;bundle-version="1.1.0",
  org.apache.commons.io;bundle-version="2.6.0",
diff --git a/tooldef/org.eclipse.escet.tooldef.runtime/src/org/eclipse/escet/tooldef/runtime/builtins/BuiltInFileTools.java b/tooldef/org.eclipse.escet.tooldef.runtime/src/org/eclipse/escet/tooldef/runtime/builtins/BuiltInFileTools.java
index 3a68611b81401c229d9a6f687fec34b269c65a24..46653e05f8c01a6d3b4c232b96baf0583b81693d 100644
--- a/tooldef/org.eclipse.escet.tooldef.runtime/src/org/eclipse/escet/tooldef/runtime/builtins/BuiltInFileTools.java
+++ b/tooldef/org.eclipse.escet.tooldef.runtime/src/org/eclipse/escet/tooldef/runtime/builtins/BuiltInFileTools.java
@@ -27,6 +27,7 @@ import java.io.BufferedReader;
 import java.io.FileNotFoundException;
 import java.io.FileReader;
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 import java.nio.file.CopyOption;
 import java.nio.file.FileAlreadyExistsException;
 import java.nio.file.FileSystemLoopException;
@@ -879,44 +880,24 @@ public class BuiltInFileTools {
         // Get absolute local file system path.
         String abspath = Paths.resolve(path);
 
-        // Open file for reading.
-        FileReader fileReader;
-        try {
-            fileReader = new FileReader(abspath);
+        // Read the lines.
+        List<String> lines = new ToolDefList<>();
+        try (FileReader fileReader = new FileReader(abspath, StandardCharsets.UTF_8);
+             BufferedReader bufferedReader = new BufferedReader(fileReader))
+        {
+            String line;
+            while ((line = bufferedReader.readLine()) != null) {
+                lines.add(line);
+            }
         } catch (FileNotFoundException ex) {
             String msg = fmt(
                     "Failed to read file \"%s\": the file does not exist, is a directory rather than a file, or "
                             + "for some other reason could not be opened for reading.",
                     path);
             throw new ToolDefException(msg, ex);
-        }
-
-        // Read the file into a list of strings.
-        BufferedReader bufferedReader = new BufferedReader(fileReader);
-        List<String> lines = new ToolDefList<>();
-        ToolDefException error = null;
-
-        try {
-            String line;
-            while ((line = bufferedReader.readLine()) != null) {
-                lines.add(line);
-            }
         } catch (IOException ex) {
             String msg = fmt("Failed to read file \"%s\": an I/O error occurred.", path);
-            error = new ToolDefException(msg, ex);
-        } finally {
-            try {
-                bufferedReader.close();
-            } catch (IOException ex) {
-                if (error == null) {
-                    String msg = fmt("Failed to read file \"%s\": could not close the file.", path);
-                    error = new ToolDefException(msg, ex);
-                }
-            }
-        }
-
-        if (error != null) {
-            throw error;
+            throw new ToolDefException(msg, ex);
         }
 
         // Return the read lines.
@@ -1084,37 +1065,30 @@ public class BuiltInFileTools {
      * @param text The text to write to the file.
      * @param append Whether to append the text to the file if it already exists ({@code true}), or overwrite the file
      *     if it already exists ({@code false}).
+     * @param newline Indicates how to handle new lines. Use {@code "preserve"} to write the text 'as is', preserving
+     *     the new lines as they are in the given text. Use {@code "platform"} to write the text with platform-specific
+     *     new lines, replacing all new lines by the new line of the current platform. Use any other string to write the
+     *     text with specific given new line, replacing all new lines in the given text by the given new line.
      */
-    public static void writefile(String path, String text, boolean append) {
-        // Create file stream.
-        FileAppStream stream;
-        try {
-            stream = new FileAppStream(path, append);
-        } catch (InputOutputException ex) {
-            String msg = fmt("Failed to open file \"%s\" for writing.", path);
-            throw new ToolDefException(msg, ex);
-        }
-
-        // Write to the file.
-        ToolDefException error = null;
-        try {
+    public static void writefile(String path, String text, boolean append, String newline) {
+        try (FileAppStream stream = new FileAppStream(path, append)) {
+            switch (newline) {
+                case "preserve":
+                    stream.setConvertNewLines(false);
+                    break;
+                case "platform":
+                    stream.setConvertNewLines(true);
+                    stream.setPlatformNewLineBytes();
+                    break;
+                default:
+                    stream.setConvertNewLines(true);
+                    stream.setNewLineBytes(newline.getBytes(stream.getCharset()));
+                    break;
+            }
             stream.print(text);
         } catch (InputOutputException ex) {
             String msg = fmt("Failed to write to file \"%s\".", path);
-            error = new ToolDefException(msg, ex);
-        } finally {
-            try {
-                stream.close();
-            } catch (InputOutputException ex) {
-                if (error != null) {
-                    String msg = fmt("Failed to close file \"%s\".", path);
-                    error = new ToolDefException(msg, ex);
-                }
-            }
-        }
-
-        if (error != null) {
-            throw error;
+            throw new ToolDefException(msg, ex);
         }
     }
 
@@ -1123,45 +1097,40 @@ public class BuiltInFileTools {
      *
      * @param path The absolute or relative local file system path of the file. May contain both {@code "\"} and
      *     {@code "/"} as file separators.
-     * @param lines The lines of text to write to the file.
+     * @param lines The lines of text to write to the file. A new line will additionally be written after each line of
+     *     text.
      * @param append Whether to append the lines text to the file if it already exists ({@code true}), or overwrite the
      *     file if it already exists ({@code false}).
+     * @param newline Indicates how to handle new lines. Use {@code "platform"} to write the text with platform-specific
+     *     new lines, replacing all new lines by the new line of the current platform. Use any other string to write the
+     *     text with specific given new line, replacing all new lines in the given text by the given new line. Using
+     *     {@code "preserve"} is not supported.
      * @throws ToolDefException If the path exists but is a directory rather than a regular file, the file does not
      *     exist, but cannot be created, the file could not be opened for writing for any other reason, writing to the
-     *     file failed due to an I/O error, or closing the file failed.
+     *     file failed due to an I/O error, closing the file failed, or {@code "preserve"} is given for {@code newline}.
      */
-    public static void writefile(String path, List<String> lines, boolean append) {
-        // Create file stream.
-        FileAppStream stream;
-        try {
-            stream = new FileAppStream(path, append);
-        } catch (InputOutputException ex) {
-            String msg = fmt("Failed to open file \"%s\" for writing.", path);
-            throw new ToolDefException(msg, ex);
-        }
-
-        // Write to the file.
-        ToolDefException error = null;
-        try {
+    public static void writefile(String path, List<String> lines, boolean append, String newline) {
+        if ("preserve".equals(newline)) {
+            throw new ToolDefException(
+                    "Using \"preserve\" for \"newline\" is not supported when writing lines of text.");
+        }
+
+        try (FileAppStream stream = new FileAppStream(path, append)) {
+            stream.setConvertNewLines(true);
+            switch (newline) {
+                case "platform":
+                    stream.setPlatformNewLineBytes();
+                    break;
+                default:
+                    stream.setNewLineBytes(newline.getBytes(stream.getCharset()));
+                    break;
+            }
             for (String line: lines) {
                 stream.println(line);
             }
         } catch (InputOutputException ex) {
             String msg = fmt("Failed to write to file \"%s\".", path);
-            error = new ToolDefException(msg, ex);
-        } finally {
-            try {
-                stream.close();
-            } catch (InputOutputException ex) {
-                if (error != null) {
-                    String msg = fmt("Failed to close file \"%s\".", path);
-                    error = new ToolDefException(msg, ex);
-                }
-            }
-        }
-
-        if (error != null) {
-            throw error;
+            throw new ToolDefException(msg, ex);
         }
     }
 }
diff --git a/tooldef/org.eclipse.escet.tooldef.runtime/src/org/eclipse/escet/tooldef/runtime/builtins/builtins_file.tooldef b/tooldef/org.eclipse.escet.tooldef.runtime/src/org/eclipse/escet/tooldef/runtime/builtins/builtins_file.tooldef
index 9608e480562bdbd220da32b563094d3438af1f6a..ae648206f4836b216387bd2aa6318becafa8659d 100644
--- a/tooldef/org.eclipse.escet.tooldef.runtime/src/org/eclipse/escet/tooldef/runtime/builtins/builtins_file.tooldef
+++ b/tooldef/org.eclipse.escet.tooldef.runtime/src/org/eclipse/escet/tooldef/runtime/builtins/builtins_file.tooldef
@@ -96,10 +96,10 @@ tool bool _rmdir(string path, bool force = false):
     return $rmdir(path, force);
 end
 
-tool _writefile(string path, string text, bool append = false):
-    $writefile(path, text, append);
+tool _writefile(string path, string text, bool append = false, string newline = "platform"):
+    $writefile(path, text, append, newline);
 end
 
-tool _writefile(string path, list string lines, bool append = false):
-    $writefile(path, lines, append);
+tool _writefile(string path, list string lines, bool append = false, string newline = "platform"):
+    $writefile(path, lines, append, newline);
 end
diff --git a/tooldef/org.eclipse.escet.tooldef.tests/.settings/org.eclipse.jdt.core.prefs b/tooldef/org.eclipse.escet.tooldef.tests/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/tooldef/org.eclipse.escet.tooldef.tests/.settings/org.eclipse.jdt.core.prefs
+++ b/tooldef/org.eclipse.escet.tooldef.tests/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/tooldef/org.eclipse.escet.tooldef.tests/.settings/org.eclipse.jdt.ui.prefs b/tooldef/org.eclipse.escet.tooldef.tests/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/tooldef/org.eclipse.escet.tooldef.tests/.settings/org.eclipse.jdt.ui.prefs
+++ b/tooldef/org.eclipse.escet.tooldef.tests/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/tooldef/org.eclipse.escet.tooldef.tests/.settings/org.eclipse.ltk.core.refactoring.prefs b/tooldef/org.eclipse.escet.tooldef.tests/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/tooldef/org.eclipse.escet.tooldef.tests/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/tooldef/org.eclipse.escet.tooldef.tests/META-INF/MANIFEST.MF b/tooldef/org.eclipse.escet.tooldef.tests/META-INF/MANIFEST.MF
index 02d4813e23b794dacaccf75d4f63b50c16154f84..256126696624f302123db92ffd8f8525ce8d2db2 100644
--- a/tooldef/org.eclipse.escet.tooldef.tests/META-INF/MANIFEST.MF
+++ b/tooldef/org.eclipse.escet.tooldef.tests/META-INF/MANIFEST.MF
@@ -2,14 +2,14 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET ToolDef Tests (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.tooldef.tests;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.tooldef.runtime;bundle-version="0.9.0",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.tooldef.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
  org.junit;bundle-version="4.12.0",
- org.eclipse.escet.tooldef.interpreter;bundle-version="0.9.0"
+ org.eclipse.escet.tooldef.interpreter;bundle-version="0.10.0"
 Export-Package: org.eclipse.escet.tooldef.tests
 Automatic-Module-Name: org.eclipse.escet.tooldef.tests
diff --git a/tooldef/org.eclipse.escet.tooldef.tests/tests/interpreter/tool_invoke_option_invoke1.tooldef b/tooldef/org.eclipse.escet.tooldef.tests/tests/interpreter/tool_invoke_option_invoke1.tooldef
new file mode 100644
index 0000000000000000000000000000000000000000..150190304a0838e63d4e56c9dc725738836b166d
--- /dev/null
+++ b/tooldef/org.eclipse.escet.tooldef.tests/tests/interpreter/tool_invoke_option_invoke1.tooldef
@@ -0,0 +1,39 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+outln("a");
+
+tool int tool1(int x):
+    outln("t1a");
+    return x;
+end
+
+tool int tool1(int x, bool y):
+    outln("t1b");
+    if y:
+        return x;
+    else
+        return x + 1;
+    end
+end
+
+tool bool tool2(bool x):
+    outln("t2");
+    return x;
+end
+
+outln(str(tool1(1)));
+outln(str(tool1(1, true)));
+outln(str(tool2(false)));
+
+outln("b");
diff --git a/tooldef/org.eclipse.escet.tooldef.tests/tests/interpreter/tool_invoke_option_invoke1.tooldef.out b/tooldef/org.eclipse.escet.tooldef.tests/tests/interpreter/tool_invoke_option_invoke1.tooldef.out
new file mode 100644
index 0000000000000000000000000000000000000000..1c802f3ffb47871dfcdd5f4be1a9e34c6c43f784
--- /dev/null
+++ b/tooldef/org.eclipse.escet.tooldef.tests/tests/interpreter/tool_invoke_option_invoke1.tooldef.out
@@ -0,0 +1 @@
+t1a
diff --git a/tooldef/org.eclipse.escet.tooldef.tests/tests/interpreter/tool_invoke_option_invoke2.tooldef b/tooldef/org.eclipse.escet.tooldef.tests/tests/interpreter/tool_invoke_option_invoke2.tooldef
new file mode 100644
index 0000000000000000000000000000000000000000..150190304a0838e63d4e56c9dc725738836b166d
--- /dev/null
+++ b/tooldef/org.eclipse.escet.tooldef.tests/tests/interpreter/tool_invoke_option_invoke2.tooldef
@@ -0,0 +1,39 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+outln("a");
+
+tool int tool1(int x):
+    outln("t1a");
+    return x;
+end
+
+tool int tool1(int x, bool y):
+    outln("t1b");
+    if y:
+        return x;
+    else
+        return x + 1;
+    end
+end
+
+tool bool tool2(bool x):
+    outln("t2");
+    return x;
+end
+
+outln(str(tool1(1)));
+outln(str(tool1(1, true)));
+outln(str(tool2(false)));
+
+outln("b");
diff --git a/tooldef/org.eclipse.escet.tooldef.tests/tests/interpreter/tool_invoke_option_invoke2.tooldef.out b/tooldef/org.eclipse.escet.tooldef.tests/tests/interpreter/tool_invoke_option_invoke2.tooldef.out
new file mode 100644
index 0000000000000000000000000000000000000000..69966aa1f4e642d63fb9779e691120e608dc98e2
--- /dev/null
+++ b/tooldef/org.eclipse.escet.tooldef.tests/tests/interpreter/tool_invoke_option_invoke2.tooldef.out
@@ -0,0 +1 @@
+t1b
diff --git a/tooldef/org.eclipse.escet.tooldef.tests/tests/interpreter/tool_invoke_option_invoke3.tooldef b/tooldef/org.eclipse.escet.tooldef.tests/tests/interpreter/tool_invoke_option_invoke3.tooldef
new file mode 100644
index 0000000000000000000000000000000000000000..150190304a0838e63d4e56c9dc725738836b166d
--- /dev/null
+++ b/tooldef/org.eclipse.escet.tooldef.tests/tests/interpreter/tool_invoke_option_invoke3.tooldef
@@ -0,0 +1,39 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+outln("a");
+
+tool int tool1(int x):
+    outln("t1a");
+    return x;
+end
+
+tool int tool1(int x, bool y):
+    outln("t1b");
+    if y:
+        return x;
+    else
+        return x + 1;
+    end
+end
+
+tool bool tool2(bool x):
+    outln("t2");
+    return x;
+end
+
+outln(str(tool1(1)));
+outln(str(tool1(1, true)));
+outln(str(tool2(false)));
+
+outln("b");
diff --git a/tooldef/org.eclipse.escet.tooldef.tests/tests/interpreter/tool_invoke_option_invoke3.tooldef.out b/tooldef/org.eclipse.escet.tooldef.tests/tests/interpreter/tool_invoke_option_invoke3.tooldef.out
new file mode 100644
index 0000000000000000000000000000000000000000..9bc7ad0d42bb3581c31ef220203f8d951552b94f
--- /dev/null
+++ b/tooldef/org.eclipse.escet.tooldef.tests/tests/interpreter/tool_invoke_option_invoke3.tooldef.out
@@ -0,0 +1 @@
+t2
diff --git a/tooldef/org.eclipse.escet.tooldef.tests/tests/interpreter/tool_invoke_option_script.tooldef b/tooldef/org.eclipse.escet.tooldef.tests/tests/interpreter/tool_invoke_option_script.tooldef
new file mode 100644
index 0000000000000000000000000000000000000000..150190304a0838e63d4e56c9dc725738836b166d
--- /dev/null
+++ b/tooldef/org.eclipse.escet.tooldef.tests/tests/interpreter/tool_invoke_option_script.tooldef
@@ -0,0 +1,39 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+outln("a");
+
+tool int tool1(int x):
+    outln("t1a");
+    return x;
+end
+
+tool int tool1(int x, bool y):
+    outln("t1b");
+    if y:
+        return x;
+    else
+        return x + 1;
+    end
+end
+
+tool bool tool2(bool x):
+    outln("t2");
+    return x;
+end
+
+outln(str(tool1(1)));
+outln(str(tool1(1, true)));
+outln(str(tool2(false)));
+
+outln("b");
diff --git a/tooldef/org.eclipse.escet.tooldef.tests/tests/interpreter/tool_invoke_option_script.tooldef.out b/tooldef/org.eclipse.escet.tooldef.tests/tests/interpreter/tool_invoke_option_script.tooldef.out
new file mode 100644
index 0000000000000000000000000000000000000000..0519fa728be974a6861c2f7168541de6f1f63fd6
--- /dev/null
+++ b/tooldef/org.eclipse.escet.tooldef.tests/tests/interpreter/tool_invoke_option_script.tooldef.out
@@ -0,0 +1,8 @@
+a
+t1a
+1
+t1b
+1
+t2
+false
+b
diff --git a/tooldef/org.eclipse.escet.tooldef.tests/tests/interpreter/tool_invoke_option_self.tooldef b/tooldef/org.eclipse.escet.tooldef.tests/tests/interpreter/tool_invoke_option_self.tooldef
new file mode 100644
index 0000000000000000000000000000000000000000..a590100e7f8cff608c6b3f87ac44a00a6d531362
--- /dev/null
+++ b/tooldef/org.eclipse.escet.tooldef.tests/tests/interpreter/tool_invoke_option_self.tooldef
@@ -0,0 +1,27 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+outln("a");
+
+tool int t(int x):
+    outln("t1a %d", x);
+    return x;
+end
+
+outln("b");
+
+outln(str(t(1)));
+
+string p = replace(scriptpath(), "\\", "/");
+outln(str(tooldef(p, "--invoke=t(2)")));
+outln(str(tooldef(p, "--invoke=t(3)")));
diff --git a/tooldef/org.eclipse.escet.tooldef.tests/tests/interpreter/tool_invoke_option_self.tooldef.out b/tooldef/org.eclipse.escet.tooldef.tests/tests/interpreter/tool_invoke_option_self.tooldef.out
new file mode 100644
index 0000000000000000000000000000000000000000..de491f4d4e433ec45bc88ce3ed6c5667b07ccea8
--- /dev/null
+++ b/tooldef/org.eclipse.escet.tooldef.tests/tests/interpreter/tool_invoke_option_self.tooldef.out
@@ -0,0 +1,8 @@
+a
+b
+t1a 1
+1
+t1a 2
+0
+t1a 3
+0
diff --git a/tooldef/org.eclipse.escet.tooldef.tests/tests/tchecker/tool_invoke_option_parse_err.tooldef b/tooldef/org.eclipse.escet.tooldef.tests/tests/tchecker/tool_invoke_option_parse_err.tooldef
new file mode 100644
index 0000000000000000000000000000000000000000..1d001866eb30f0a24d5f503dbb8cedf30ee4388d
--- /dev/null
+++ b/tooldef/org.eclipse.escet.tooldef.tests/tests/tchecker/tool_invoke_option_parse_err.tooldef
@@ -0,0 +1,16 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+tool int t(int x):
+    return x;
+end
diff --git a/tooldef/org.eclipse.escet.tooldef.tests/tests/tchecker/tool_invoke_option_parse_err.tooldef.err b/tooldef/org.eclipse.escet.tooldef.tests/tests/tchecker/tool_invoke_option_parse_err.tooldef.err
new file mode 100644
index 0000000000000000000000000000000000000000..4470cee4bd4357a09398cc75ce7c6e4ffb6d351e
--- /dev/null
+++ b/tooldef/org.eclipse.escet.tooldef.tests/tests/tchecker/tool_invoke_option_parse_err.tooldef.err
@@ -0,0 +1,2 @@
+ERROR: The tool invocation provided via the 'Tool invocation' option is invalid: "t())".
+CAUSE: Parsing failed at line 1, column 4, at or near ")" (found ")", expected end-of-file).
diff --git a/tooldef/org.eclipse.escet.tooldef.tests/tests/tchecker/tool_invoke_option_scan_err.tooldef b/tooldef/org.eclipse.escet.tooldef.tests/tests/tchecker/tool_invoke_option_scan_err.tooldef
new file mode 100644
index 0000000000000000000000000000000000000000..1d001866eb30f0a24d5f503dbb8cedf30ee4388d
--- /dev/null
+++ b/tooldef/org.eclipse.escet.tooldef.tests/tests/tchecker/tool_invoke_option_scan_err.tooldef
@@ -0,0 +1,16 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+tool int t(int x):
+    return x;
+end
diff --git a/tooldef/org.eclipse.escet.tooldef.tests/tests/tchecker/tool_invoke_option_scan_err.tooldef.err b/tooldef/org.eclipse.escet.tooldef.tests/tests/tchecker/tool_invoke_option_scan_err.tooldef.err
new file mode 100644
index 0000000000000000000000000000000000000000..775193d73822ae3235fa113d4a8caa3ddc1430ec
--- /dev/null
+++ b/tooldef/org.eclipse.escet.tooldef.tests/tests/tchecker/tool_invoke_option_scan_err.tooldef.err
@@ -0,0 +1,2 @@
+ERROR: The tool invocation provided via the 'Tool invocation' option is invalid: "%".
+CAUSE: Scanning failed for character "%" (Unicode U+25) at line 1, column 1.
diff --git a/tooldef/org.eclipse.escet.tooldef.tests/tests/tchecker/tool_invoke_option_tcheck_err.tooldef b/tooldef/org.eclipse.escet.tooldef.tests/tests/tchecker/tool_invoke_option_tcheck_err.tooldef
new file mode 100644
index 0000000000000000000000000000000000000000..1d001866eb30f0a24d5f503dbb8cedf30ee4388d
--- /dev/null
+++ b/tooldef/org.eclipse.escet.tooldef.tests/tests/tchecker/tool_invoke_option_tcheck_err.tooldef
@@ -0,0 +1,16 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2023 Contributors to the Eclipse Foundation
+//
+// See the NOTICE file(s) distributed with this work for additional
+// information regarding copyright ownership.
+//
+// This program and the accompanying materials are made available
+// under the terms of the MIT License which is available at
+// https://opensource.org/licenses/MIT
+//
+// SPDX-License-Identifier: MIT
+//////////////////////////////////////////////////////////////////////////////
+
+tool int t(int x):
+    return x;
+end
diff --git a/tooldef/org.eclipse.escet.tooldef.tests/tests/tchecker/tool_invoke_option_tcheck_err.tooldef.err b/tooldef/org.eclipse.escet.tooldef.tests/tests/tchecker/tool_invoke_option_tcheck_err.tooldef.err
new file mode 100644
index 0000000000000000000000000000000000000000..b1f635634aec87fb823bedeb5ef0d71833abc64c
--- /dev/null
+++ b/tooldef/org.eclipse.escet.tooldef.tests/tests/tchecker/tool_invoke_option_tcheck_err.tooldef.err
@@ -0,0 +1,2 @@
+ERROR: The tool invocation provided via the 'Tool invocation' option is invalid: "t()":
+ - Semantic error at line 1, column 2: Cannot invoke tool "t" (1 overload) for the given arguments: no argument for mandatory parameter "x".
diff --git a/tooldef/org.eclipse.escet.tooldef.tests/tests/test_interpreter.tooldef b/tooldef/org.eclipse.escet.tooldef.tests/tests/test_interpreter.tooldef
index 26de232671b189553c24b9dfa3436a2eca4a5ac8..b4445b9d3ca685c2fe5ed0d319d362c64d8d984e 100644
--- a/tooldef/org.eclipse.escet.tooldef.tests/tests/test_interpreter.tooldef
+++ b/tooldef/org.eclipse.escet.tooldef.tests/tests/test_interpreter.tooldef
@@ -18,11 +18,14 @@ string test_path = "interpreter";
 string test_pattern = "*.tooldef";
 list string default_options = ["--devmode=1"];
 map(string:list string) test_options = {
-    "interpreter/debug_output.tooldef":  ["-mdebug"],
-    "interpreter/exit0.tooldef":         ["-mdebug"],
-    "interpreter/exit1.tooldef":         ["-mdebug"],
-    "interpreter/exit_deep.tooldef":     ["-mdebug"],
-    "interpreter/exit_no_value.tooldef": ["-mdebug"]
+    "interpreter/debug_output.tooldef":               ["-mdebug"],
+    "interpreter/exit0.tooldef":                      ["-mdebug"],
+    "interpreter/exit1.tooldef":                      ["-mdebug"],
+    "interpreter/exit_deep.tooldef":                  ["-mdebug"],
+    "interpreter/exit_no_value.tooldef":              ["-mdebug"],
+    "interpreter/tool_invoke_option_invoke1.tooldef": ["--invoke=tool1(5)"],
+    "interpreter/tool_invoke_option_invoke2.tooldef": ["--invoke='tool1(6, true)'"],
+    "interpreter/tool_invoke_option_invoke3.tooldef": ["--invoke=tool2(false)"],
 };
 set string test_skip = {
     "interpreter/err_java_method_rslt_nan.tooldef",
diff --git a/tooldef/org.eclipse.escet.tooldef.tests/tests/test_tchecker.tooldef b/tooldef/org.eclipse.escet.tooldef.tests/tests/test_tchecker.tooldef
index c526c1a3f1e063d3ac55098e1cf15e96c3c5dac8..17984858ae5c75cf3a9ce06b5dbb66b9ca5296fc 100644
--- a/tooldef/org.eclipse.escet.tooldef.tests/tests/test_tchecker.tooldef
+++ b/tooldef/org.eclipse.escet.tooldef.tests/tests/test_tchecker.tooldef
@@ -17,7 +17,11 @@ string class = "org.eclipse.escet.tooldef.interpreter.ToolDefInterpreterApp";
 string test_path = "tchecker";
 string test_pattern = "*.tooldef";
 list string default_options = ["--devmode=1"];
-map(string:list string) test_options = {};
+map(string:list string) test_options = {
+    "tchecker/tool_invoke_option_parse_err.tooldef":  ["--invoke=t())"],
+    "tchecker/tool_invoke_option_scan_err.tooldef":   ["--invoke=%"],
+    "tchecker/tool_invoke_option_tcheck_err.tooldef": ["--invoke=t()"],
+};
 set string test_skip = {};
 
 // Initialize counts.
diff --git a/tooldef/org.eclipse.escet.tooldef.texteditor/.settings/org.eclipse.jdt.core.prefs b/tooldef/org.eclipse.escet.tooldef.texteditor/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/tooldef/org.eclipse.escet.tooldef.texteditor/.settings/org.eclipse.jdt.core.prefs
+++ b/tooldef/org.eclipse.escet.tooldef.texteditor/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/tooldef/org.eclipse.escet.tooldef.texteditor/.settings/org.eclipse.jdt.ui.prefs b/tooldef/org.eclipse.escet.tooldef.texteditor/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/tooldef/org.eclipse.escet.tooldef.texteditor/.settings/org.eclipse.jdt.ui.prefs
+++ b/tooldef/org.eclipse.escet.tooldef.texteditor/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/tooldef/org.eclipse.escet.tooldef.texteditor/.settings/org.eclipse.ltk.core.refactoring.prefs b/tooldef/org.eclipse.escet.tooldef.texteditor/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/tooldef/org.eclipse.escet.tooldef.texteditor/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/tooldef/org.eclipse.escet.tooldef.texteditor/META-INF/MANIFEST.MF b/tooldef/org.eclipse.escet.tooldef.texteditor/META-INF/MANIFEST.MF
index 2bcfcbbc28bae6c6ff3a583494ecaea02ce8a449..d138f38670f03abb9f783850c1a9344266da36c2 100644
--- a/tooldef/org.eclipse.escet.tooldef.texteditor/META-INF/MANIFEST.MF
+++ b/tooldef/org.eclipse.escet.tooldef.texteditor/META-INF/MANIFEST.MF
@@ -2,24 +2,24 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET ToolDef Text Editor (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.tooldef.texteditor;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.tooldef.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.tooldef.parser;bundle-version="0.9.0",
- org.eclipse.escet.setext.texteditorbase;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.tooldef.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.tooldef.parser;bundle-version="0.10.0",
+ org.eclipse.escet.setext.texteditorbase;bundle-version="0.10.0",
  org.eclipse.jface.text;bundle-version="3.16.100",
  org.eclipse.ui;bundle-version="3.115.0",
  org.eclipse.core.runtime;bundle-version="3.17.0",
  org.eclipse.core.resources;bundle-version="3.13.600",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
  org.eclipse.ui.editors;bundle-version="3.13.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
  org.apache.commons.lang3;bundle-version="3.1.0",
- org.eclipse.escet.tooldef.typechecker;bundle-version="0.9.0",
+ org.eclipse.escet.tooldef.typechecker;bundle-version="0.10.0",
  org.eclipse.ui.ide;bundle-version="3.18.200",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0"
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0"
 Automatic-Module-Name: org.eclipse.escet.tooldef.texteditor
 Export-Package: org.eclipse.escet.tooldef.texteditor
diff --git a/tooldef/org.eclipse.escet.tooldef.typechecker/.settings/org.eclipse.jdt.core.prefs b/tooldef/org.eclipse.escet.tooldef.typechecker/.settings/org.eclipse.jdt.core.prefs
index 9fada7373de94117c3331dc552232c6f03245ae3..0a19dd9b3d5281a1e5da73b9acbe22db5824b958 100644
--- a/tooldef/org.eclipse.escet.tooldef.typechecker/.settings/org.eclipse.jdt.core.prefs
+++ b/tooldef/org.eclipse.escet.tooldef.typechecker/.settings/org.eclipse.jdt.core.prefs
@@ -184,6 +184,7 @@ org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_record_components=16
 org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=82
diff --git a/tooldef/org.eclipse.escet.tooldef.typechecker/.settings/org.eclipse.jdt.ui.prefs b/tooldef/org.eclipse.escet.tooldef.typechecker/.settings/org.eclipse.jdt.ui.prefs
index ef25197a5e52eef2e22b5d4de48612b2f48b1064..ef8223ff450cf757af28aab8760feee79e503261 100644
--- a/tooldef/org.eclipse.escet.tooldef.typechecker/.settings/org.eclipse.jdt.ui.prefs
+++ b/tooldef/org.eclipse.escet.tooldef.typechecker/.settings/org.eclipse.jdt.ui.prefs
@@ -1,7 +1,8 @@
 eclipse.preferences.version=1
 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-formatter_settings_version=22
+formatter_settings_version=23
 org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_all=false
 sp_cleanup.add_default_serial_version_id=true
 sp_cleanup.add_generated_serial_version_id=false
 sp_cleanup.add_missing_annotations=false
@@ -15,42 +16,129 @@ sp_cleanup.always_use_blocks=true
 sp_cleanup.always_use_parentheses_in_expressions=false
 sp_cleanup.always_use_this_for_non_static_field_access=false
 sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.array_with_curly=false
+sp_cleanup.arrays_fill=false
+sp_cleanup.bitwise_conditional_expression=false
+sp_cleanup.boolean_literal=false
+sp_cleanup.boolean_value_rather_than_comparison=false
+sp_cleanup.break_loop=false
+sp_cleanup.collection_cloning=false
+sp_cleanup.comparing_on_criteria=false
+sp_cleanup.comparison_statement=false
+sp_cleanup.controlflow_merge=false
+sp_cleanup.convert_functional_interfaces=false
 sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.convert_to_switch_expressions=false
 sp_cleanup.correct_indentation=false
+sp_cleanup.do_while_rather_than_while=false
+sp_cleanup.double_negation=false
+sp_cleanup.else_if=false
+sp_cleanup.embedded_if=false
+sp_cleanup.evaluate_nullable=false
+sp_cleanup.extract_increment=false
 sp_cleanup.format_source_code=false
 sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.hash=false
+sp_cleanup.if_condition=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.instanceof=false
+sp_cleanup.instanceof_keyword=false
+sp_cleanup.invert_equals=false
+sp_cleanup.join=false
+sp_cleanup.lazy_logical_operator=false
 sp_cleanup.make_local_variable_final=false
 sp_cleanup.make_parameters_final=false
 sp_cleanup.make_private_fields_final=true
 sp_cleanup.make_type_abstract_if_missing_method=false
 sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.map_cloning=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.multi_catch=false
 sp_cleanup.never_use_blocks=false
 sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.no_string_creation=false
+sp_cleanup.no_super=false
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
 sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false
+sp_cleanup.operand_factorization=false
 sp_cleanup.organize_imports=false
+sp_cleanup.overridden_assignment=false
+sp_cleanup.overridden_assignment_move_decl=false
+sp_cleanup.plain_replacement=false
+sp_cleanup.precompile_regex=false
+sp_cleanup.primitive_comparison=false
+sp_cleanup.primitive_parsing=false
+sp_cleanup.primitive_rather_than_wrapper=false
+sp_cleanup.primitive_serialization=false
+sp_cleanup.pull_out_if_from_if_else=false
+sp_cleanup.pull_up_assignment=false
+sp_cleanup.push_down_negation=false
 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.reduce_indentation=false
+sp_cleanup.redundant_comparator=false
+sp_cleanup.redundant_falling_through_block_end=false
 sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=false
+sp_cleanup.remove_redundant_semicolons=false
+sp_cleanup.remove_redundant_type_arguments=false
 sp_cleanup.remove_trailing_whitespaces=true
 sp_cleanup.remove_trailing_whitespaces_all=true
 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_array_creation=false
 sp_cleanup.remove_unnecessary_casts=false
 sp_cleanup.remove_unnecessary_nls_tags=false
 sp_cleanup.remove_unused_imports=false
 sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_method_parameters=false
 sp_cleanup.remove_unused_private_fields=true
 sp_cleanup.remove_unused_private_members=false
 sp_cleanup.remove_unused_private_methods=true
 sp_cleanup.remove_unused_private_types=true
+sp_cleanup.return_expression=false
+sp_cleanup.simplify_lambda_expression_and_method_ref=false
+sp_cleanup.single_used_field=false
 sp_cleanup.sort_members=false
 sp_cleanup.sort_members_all=false
+sp_cleanup.standard_comparison=false
+sp_cleanup.static_inner_class=false
+sp_cleanup.strictly_equal_or_different=false
+sp_cleanup.stringbuffer_to_stringbuilder=false
+sp_cleanup.stringbuilder=false
+sp_cleanup.stringbuilder_for_local_vars=false
+sp_cleanup.stringconcat_to_textblock=false
+sp_cleanup.substring=false
+sp_cleanup.switch=false
+sp_cleanup.system_property=false
+sp_cleanup.system_property_boolean=false
+sp_cleanup.system_property_file_encoding=false
+sp_cleanup.system_property_file_separator=false
+sp_cleanup.system_property_line_separator=false
+sp_cleanup.system_property_path_separator=false
+sp_cleanup.ternary_operator=false
+sp_cleanup.try_with_resource=false
+sp_cleanup.unlooped_while=false
+sp_cleanup.unreachable_block=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
 sp_cleanup.use_blocks=false
 sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=false
+sp_cleanup.use_lambda=false
 sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_string_is_blank=false
 sp_cleanup.use_this_for_non_static_field_access=false
 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
 sp_cleanup.use_this_for_non_static_method_access=false
 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
+sp_cleanup.useless_continue=false
+sp_cleanup.useless_return=false
+sp_cleanup.valueof_rather_than_instantiation=false
diff --git a/tooldef/org.eclipse.escet.tooldef.typechecker/.settings/org.eclipse.ltk.core.refactoring.prefs b/tooldef/org.eclipse.escet.tooldef.typechecker/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000000000000000000000000000000000000..b196c64a3418b865f0476d2e21d11eae3dd4b2da
--- /dev/null
+++ b/tooldef/org.eclipse.escet.tooldef.typechecker/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/tooldef/org.eclipse.escet.tooldef.typechecker/META-INF/MANIFEST.MF b/tooldef/org.eclipse.escet.tooldef.typechecker/META-INF/MANIFEST.MF
index 107107ec6cc1dd329a04377dca0fa9a94c9c17ac..aed6f57bfae5dddd045b20fecf4821d6eefa7e13 100644
--- a/tooldef/org.eclipse.escet.tooldef.typechecker/META-INF/MANIFEST.MF
+++ b/tooldef/org.eclipse.escet.tooldef.typechecker/META-INF/MANIFEST.MF
@@ -2,23 +2,23 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: ESCET ToolDef Typechecker (Incubation)
 Bundle-SymbolicName: org.eclipse.escet.tooldef.typechecker;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.10.0.qualifier
 Bundle-Vendor: Eclipse ESCET
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-ActivationPolicy: lazy
-Require-Bundle: org.eclipse.escet.tooldef.metamodel;bundle-version="0.9.0",
- org.eclipse.escet.tooldef.metamodel.java;bundle-version="0.9.0",
- org.eclipse.escet.setext.runtime;bundle-version="0.9.0",
- org.eclipse.escet.common.java;bundle-version="0.9.0",
- org.eclipse.escet.common.emf;bundle-version="0.9.0",
- org.eclipse.escet.common.typechecker;bundle-version="0.9.0",
+Require-Bundle: org.eclipse.escet.tooldef.metamodel;bundle-version="0.10.0",
+ org.eclipse.escet.tooldef.metamodel.java;bundle-version="0.10.0",
+ org.eclipse.escet.setext.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.common.java;bundle-version="0.10.0",
+ org.eclipse.escet.common.emf;bundle-version="0.10.0",
+ org.eclipse.escet.common.typechecker;bundle-version="0.10.0",
  org.apache.commons.lang3;bundle-version="3.1.0",
- org.eclipse.escet.tooldef.common;bundle-version="0.9.0",
+ org.eclipse.escet.tooldef.common;bundle-version="0.10.0",
  org.eclipse.core.runtime;bundle-version="3.17.0",
- org.eclipse.escet.common.app.framework;bundle-version="0.9.0",
- org.eclipse.escet.tooldef.parser;bundle-version="0.9.0",
- org.eclipse.escet.tooldef.runtime;bundle-version="0.9.0",
- org.eclipse.escet.common.position.common;bundle-version="0.9.0",
+ org.eclipse.escet.common.app.framework;bundle-version="0.10.0",
+ org.eclipse.escet.tooldef.parser;bundle-version="0.10.0",
+ org.eclipse.escet.tooldef.runtime;bundle-version="0.10.0",
+ org.eclipse.escet.common.position.common;bundle-version="0.10.0",
  org.eclipse.ui;bundle-version="3.115.0"
 Export-Package: org.eclipse.escet.tooldef.typechecker
 Automatic-Module-Name: org.eclipse.escet.tooldef.typechecker
diff --git a/tooldef/org.eclipse.escet.tooldef.typechecker/src/org/eclipse/escet/tooldef/typechecker/CheckerContext.java b/tooldef/org.eclipse.escet.tooldef.typechecker/src/org/eclipse/escet/tooldef/typechecker/CheckerContext.java
index 591bfb00bc8fc1b429de324ec361d93ed38fcacb..18e0bd30586d8573f4a3422ace42e8954786a807 100644
--- a/tooldef/org.eclipse.escet.tooldef.typechecker/src/org/eclipse/escet/tooldef/typechecker/CheckerContext.java
+++ b/tooldef/org.eclipse.escet.tooldef.typechecker/src/org/eclipse/escet/tooldef/typechecker/CheckerContext.java
@@ -57,6 +57,9 @@ import org.eclipse.escet.tooldef.metamodel.tooldef.types.ToolDefType;
 
 /** ToolDef type checker context/scope. */
 public class CheckerContext extends PositionObjectImpl {
+    /** The location for tool invocations provided via the 'Tool invocation' option of the ToolDef interpreter. */
+    public static final String TOOL_INVOCATION_LOCATION = "/<invoke>";
+
     /** The ToolDef type checker to use. */
     public final ToolDefTypeChecker tchecker;
 
@@ -160,8 +163,10 @@ public class CheckerContext extends PositionObjectImpl {
      * @param args The message arguments.
      */
     public void addProblem(Message msg, TextPosition position, String... args) {
-        // Make sure the position information is valid for the current file.
-        if (position == null || !position.location.equals(tchecker.getSourceFilePath())) {
+        // Make sure the position information is valid for the current file or tool invocation.
+        if (position != null && position.location.equals(TOOL_INVOCATION_LOCATION)) {
+            // Error in tool invocation provided via the ToolDef interpreter's 'Tool invocation' option.
+        } else if (position == null || !position.location.equals(tchecker.getSourceFilePath())) {
             String inMsg = msg.severity.toString() + ": " + msg.format(args);
             Exception inner = new RuntimeException(inMsg);
             String exMsg = (position == null) ? "Missing position info" : "Position info wrong file";
diff --git a/tooldef/org.eclipse.escet.tooldef.typechecker/src/org/eclipse/escet/tooldef/typechecker/ToolDefTypeChecker.java b/tooldef/org.eclipse.escet.tooldef.typechecker/src/org/eclipse/escet/tooldef/typechecker/ToolDefTypeChecker.java
index b6f62357ea534ca6d210f2c3a33666f17f28e2d1..4414122147f7083e6f28041ff46c14ac613df8a0 100644
--- a/tooldef/org.eclipse.escet.tooldef.typechecker/src/org/eclipse/escet/tooldef/typechecker/ToolDefTypeChecker.java
+++ b/tooldef/org.eclipse.escet.tooldef.typechecker/src/org/eclipse/escet/tooldef/typechecker/ToolDefTypeChecker.java
@@ -33,6 +33,7 @@ import org.eclipse.escet.common.java.Strings;
 import org.eclipse.escet.common.java.TextPosition;
 import org.eclipse.escet.common.position.metamodel.position.PositionObject;
 import org.eclipse.escet.common.typechecker.SemanticException;
+import org.eclipse.escet.common.typechecker.SemanticProblem;
 import org.eclipse.escet.common.typechecker.TypeChecker;
 import org.eclipse.escet.setext.runtime.Token;
 import org.eclipse.escet.tooldef.common.ToolDefTextUtils;
@@ -45,6 +46,7 @@ import org.eclipse.escet.tooldef.metamodel.tooldef.ToolDefImport;
 import org.eclipse.escet.tooldef.metamodel.tooldef.ToolDefTool;
 import org.eclipse.escet.tooldef.metamodel.tooldef.TypeDecl;
 import org.eclipse.escet.tooldef.metamodel.tooldef.statements.Statement;
+import org.eclipse.escet.tooldef.metamodel.tooldef.statements.ToolInvokeStatement;
 
 /** ToolDef type checker. */
 public class ToolDefTypeChecker extends TypeChecker<Script, Script> {
@@ -95,6 +97,7 @@ public class ToolDefTypeChecker extends TypeChecker<Script, Script> {
     protected Script transRoot(Script script) {
         // Sanity checking.
         Assert.check(script.getName() == null);
+        Assert.check(rootCtxt == null);
 
         // Initialize context.
         CheckerContext ctxt = new CheckerContext(this, script);
@@ -127,6 +130,24 @@ public class ToolDefTypeChecker extends TypeChecker<Script, Script> {
         return script;
     }
 
+    /**
+     * Type check a tool invocation statement. A script must have been type checked by invoking
+     * {@link #typeCheck(Script)} prior to invoking this method. The tool to is resolved within that script.
+     *
+     * @param invocation The tool invocation statement to be type checked. Is modified in-place.
+     * @return Any problems found by the type checker.
+     */
+    public List<SemanticProblem> typeCheck(ToolInvokeStatement invocation) {
+        preparePostUse();
+        try {
+            tcheck(invocation, rootCtxt);
+        } catch (SemanticException e) {
+            // Ignore type checking finding a problem. The problems are reported back to the caller.
+        }
+        List<SemanticProblem> problems = finalizePostUse();
+        return problems;
+    }
+
     /**
      * Type check a ToolDef declaration.
      *