You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by hu...@apache.org on 2023/05/17 04:15:30 UTC

[plc4x] branch develop updated (d89e40f73f -> e8baa8e27f)

This is an automated email from the ASF dual-hosted git repository.

hutcheb pushed a change to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git


    from d89e40f73f refactor(plc4go): streamline imports
     new 3f7001b184 feat(plc4py): WriteBuffer Add local byte_order check
     new 3cbd8f52e0 feat(plc4py): migrated the python helper to be based on the go helper
     new e8baa8e27f Merge remote-tracking branch 'origin/develop' into develop

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../python/PythonLanguageTemplateHelper.java       | 2028 ++++++++++++--------
 .../python/complex-type-template.python.ftlh       |   51 +-
 .../templates/python/enum-template.python.ftlh     |    4 +-
 .../plc4py/protocols/modbus/readwrite/DataItem.py  |  346 ++--
 .../protocols/modbus/readwrite/DriverType.py       |    4 +-
 .../plc4py/protocols/modbus/readwrite/ModbusADU.py |   16 +-
 .../protocols/modbus/readwrite/ModbusAsciiADU.py   |   37 +-
 .../protocols/modbus/readwrite/ModbusConstants.py  |   16 +-
 .../protocols/modbus/readwrite/ModbusDataType.py   |    6 +-
 .../ModbusDeviceInformationConformityLevel.py      |    4 +-
 .../readwrite/ModbusDeviceInformationLevel.py      |    4 +-
 .../ModbusDeviceInformationMoreFollows.py          |    4 +-
 .../readwrite/ModbusDeviceInformationObject.py     |   20 +-
 .../protocols/modbus/readwrite/ModbusErrorCode.py  |    4 +-
 .../plc4py/protocols/modbus/readwrite/ModbusPDU.py |  172 +-
 .../modbus/readwrite/ModbusPDUDiagnosticRequest.py |   17 +-
 .../readwrite/ModbusPDUDiagnosticResponse.py       |   17 +-
 .../protocols/modbus/readwrite/ModbusPDUError.py   |   22 +-
 .../ModbusPDUGetComEventCounterRequest.py          |   11 +-
 .../ModbusPDUGetComEventCounterResponse.py         |   17 +-
 .../readwrite/ModbusPDUGetComEventLogRequest.py    |   11 +-
 .../readwrite/ModbusPDUGetComEventLogResponse.py   |   32 +-
 .../ModbusPDUMaskWriteHoldingRegisterRequest.py    |   23 +-
 .../ModbusPDUMaskWriteHoldingRegisterResponse.py   |   23 +-
 .../modbus/readwrite/ModbusPDUReadCoilsRequest.py  |   21 +-
 .../modbus/readwrite/ModbusPDUReadCoilsResponse.py |   19 +-
 .../ModbusPDUReadDeviceIdentificationRequest.py    |   34 +-
 .../ModbusPDUReadDeviceIdentificationResponse.py   |   76 +-
 .../ModbusPDUReadDiscreteInputsRequest.py          |   21 +-
 .../ModbusPDUReadDiscreteInputsResponse.py         |   19 +-
 .../ModbusPDUReadExceptionStatusRequest.py         |   11 +-
 .../ModbusPDUReadExceptionStatusResponse.py        |   13 +-
 .../readwrite/ModbusPDUReadFifoQueueRequest.py     |   17 +-
 .../readwrite/ModbusPDUReadFifoQueueResponse.py    |   31 +-
 .../readwrite/ModbusPDUReadFileRecordRequest.py    |   19 +-
 .../ModbusPDUReadFileRecordRequestItem.py          |   24 +-
 .../readwrite/ModbusPDUReadFileRecordResponse.py   |   19 +-
 .../ModbusPDUReadFileRecordResponseItem.py         |   23 +-
 .../ModbusPDUReadHoldingRegistersRequest.py        |   21 +-
 .../ModbusPDUReadHoldingRegistersResponse.py       |   19 +-
 .../ModbusPDUReadInputRegistersRequest.py          |   21 +-
 .../ModbusPDUReadInputRegistersResponse.py         |   19 +-
 ...sPDUReadWriteMultipleHoldingRegistersRequest.py |   39 +-
 ...PDUReadWriteMultipleHoldingRegistersResponse.py |   19 +-
 .../readwrite/ModbusPDUReportServerIdRequest.py    |   11 +-
 .../readwrite/ModbusPDUReportServerIdResponse.py   |   19 +-
 .../readwrite/ModbusPDUWriteFileRecordRequest.py   |   19 +-
 .../ModbusPDUWriteFileRecordRequestItem.py         |   33 +-
 .../readwrite/ModbusPDUWriteFileRecordResponse.py  |   19 +-
 .../ModbusPDUWriteFileRecordResponseItem.py        |   30 +-
 .../ModbusPDUWriteMultipleCoilsRequest.py          |   29 +-
 .../ModbusPDUWriteMultipleCoilsResponse.py         |   21 +-
 ...odbusPDUWriteMultipleHoldingRegistersRequest.py |   29 +-
 ...dbusPDUWriteMultipleHoldingRegistersResponse.py |   21 +-
 .../readwrite/ModbusPDUWriteSingleCoilRequest.py   |   17 +-
 .../readwrite/ModbusPDUWriteSingleCoilResponse.py  |   17 +-
 .../ModbusPDUWriteSingleRegisterRequest.py         |   17 +-
 .../ModbusPDUWriteSingleRegisterResponse.py        |   17 +-
 .../protocols/modbus/readwrite/ModbusRtuADU.py     |   37 +-
 .../protocols/modbus/readwrite/ModbusTcpADU.py     |   52 +-
 .../protocols/simulated/readwrite/DataItem.py      |  174 +-
 .../plc4py/protocols/simulated/readwrite/Dummy.py  |   17 +-
 .../simulated/readwrite/SimulatedDataTypeSizes.py  |    6 +-
 .../plc4py/plc4py/spi/generation/WriteBuffer.py    |  149 +-
 sandbox/plc4py/plc4py/spi/generation/__init__.py   |    1 -
 sandbox/plc4py/plc4py/spi/values/Common.py         |    3 +-
 sandbox/plc4py/setup.py                            |    2 +-
 .../tests/unit/plc4py/spi/test_write_buffer.py     |  102 +-
 68 files changed, 2279 insertions(+), 1937 deletions(-)


[plc4x] 02/03: feat(plc4py): migrated the python helper to be based on the go helper

Posted by hu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

hutcheb pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit 3cbd8f52e09763f277940777b512370c63b06ef5
Author: Ben Hutcheson <be...@gmail.com>
AuthorDate: Wed May 17 06:09:51 2023 +0200

    feat(plc4py): migrated the python helper to be based on the go helper
---
 .../python/PythonLanguageTemplateHelper.java       | 2028 ++++++++++++--------
 .../python/complex-type-template.python.ftlh       |   51 +-
 .../templates/python/enum-template.python.ftlh     |    4 +-
 .../plc4py/protocols/modbus/readwrite/DataItem.py  |  346 ++--
 .../protocols/modbus/readwrite/DriverType.py       |    4 +-
 .../plc4py/protocols/modbus/readwrite/ModbusADU.py |   16 +-
 .../protocols/modbus/readwrite/ModbusAsciiADU.py   |   37 +-
 .../protocols/modbus/readwrite/ModbusConstants.py  |   16 +-
 .../protocols/modbus/readwrite/ModbusDataType.py   |    6 +-
 .../ModbusDeviceInformationConformityLevel.py      |    4 +-
 .../readwrite/ModbusDeviceInformationLevel.py      |    4 +-
 .../ModbusDeviceInformationMoreFollows.py          |    4 +-
 .../readwrite/ModbusDeviceInformationObject.py     |   20 +-
 .../protocols/modbus/readwrite/ModbusErrorCode.py  |    4 +-
 .../plc4py/protocols/modbus/readwrite/ModbusPDU.py |  172 +-
 .../modbus/readwrite/ModbusPDUDiagnosticRequest.py |   17 +-
 .../readwrite/ModbusPDUDiagnosticResponse.py       |   17 +-
 .../protocols/modbus/readwrite/ModbusPDUError.py   |   22 +-
 .../ModbusPDUGetComEventCounterRequest.py          |   11 +-
 .../ModbusPDUGetComEventCounterResponse.py         |   17 +-
 .../readwrite/ModbusPDUGetComEventLogRequest.py    |   11 +-
 .../readwrite/ModbusPDUGetComEventLogResponse.py   |   32 +-
 .../ModbusPDUMaskWriteHoldingRegisterRequest.py    |   23 +-
 .../ModbusPDUMaskWriteHoldingRegisterResponse.py   |   23 +-
 .../modbus/readwrite/ModbusPDUReadCoilsRequest.py  |   21 +-
 .../modbus/readwrite/ModbusPDUReadCoilsResponse.py |   19 +-
 .../ModbusPDUReadDeviceIdentificationRequest.py    |   34 +-
 .../ModbusPDUReadDeviceIdentificationResponse.py   |   76 +-
 .../ModbusPDUReadDiscreteInputsRequest.py          |   21 +-
 .../ModbusPDUReadDiscreteInputsResponse.py         |   19 +-
 .../ModbusPDUReadExceptionStatusRequest.py         |   11 +-
 .../ModbusPDUReadExceptionStatusResponse.py        |   13 +-
 .../readwrite/ModbusPDUReadFifoQueueRequest.py     |   17 +-
 .../readwrite/ModbusPDUReadFifoQueueResponse.py    |   31 +-
 .../readwrite/ModbusPDUReadFileRecordRequest.py    |   19 +-
 .../ModbusPDUReadFileRecordRequestItem.py          |   24 +-
 .../readwrite/ModbusPDUReadFileRecordResponse.py   |   19 +-
 .../ModbusPDUReadFileRecordResponseItem.py         |   23 +-
 .../ModbusPDUReadHoldingRegistersRequest.py        |   21 +-
 .../ModbusPDUReadHoldingRegistersResponse.py       |   19 +-
 .../ModbusPDUReadInputRegistersRequest.py          |   21 +-
 .../ModbusPDUReadInputRegistersResponse.py         |   19 +-
 ...sPDUReadWriteMultipleHoldingRegistersRequest.py |   39 +-
 ...PDUReadWriteMultipleHoldingRegistersResponse.py |   19 +-
 .../readwrite/ModbusPDUReportServerIdRequest.py    |   11 +-
 .../readwrite/ModbusPDUReportServerIdResponse.py   |   19 +-
 .../readwrite/ModbusPDUWriteFileRecordRequest.py   |   19 +-
 .../ModbusPDUWriteFileRecordRequestItem.py         |   33 +-
 .../readwrite/ModbusPDUWriteFileRecordResponse.py  |   19 +-
 .../ModbusPDUWriteFileRecordResponseItem.py        |   30 +-
 .../ModbusPDUWriteMultipleCoilsRequest.py          |   29 +-
 .../ModbusPDUWriteMultipleCoilsResponse.py         |   21 +-
 ...odbusPDUWriteMultipleHoldingRegistersRequest.py |   29 +-
 ...dbusPDUWriteMultipleHoldingRegistersResponse.py |   21 +-
 .../readwrite/ModbusPDUWriteSingleCoilRequest.py   |   17 +-
 .../readwrite/ModbusPDUWriteSingleCoilResponse.py  |   17 +-
 .../ModbusPDUWriteSingleRegisterRequest.py         |   17 +-
 .../ModbusPDUWriteSingleRegisterResponse.py        |   17 +-
 .../protocols/modbus/readwrite/ModbusRtuADU.py     |   37 +-
 .../protocols/modbus/readwrite/ModbusTcpADU.py     |   52 +-
 .../protocols/simulated/readwrite/DataItem.py      |  174 +-
 .../plc4py/protocols/simulated/readwrite/Dummy.py  |   17 +-
 .../simulated/readwrite/SimulatedDataTypeSizes.py  |    6 +-
 .../plc4py/plc4py/spi/generation/WriteBuffer.py    |  143 +-
 sandbox/plc4py/plc4py/spi/generation/__init__.py   |    1 -
 sandbox/plc4py/plc4py/spi/values/Common.py         |    3 +-
 sandbox/plc4py/setup.py                            |    2 +-
 .../tests/unit/plc4py/spi/test_write_buffer.py     |  102 +-
 68 files changed, 2276 insertions(+), 1934 deletions(-)

diff --git a/code-generation/language-python/src/main/java/org/apache/plc4x/language/python/PythonLanguageTemplateHelper.java b/code-generation/language-python/src/main/java/org/apache/plc4x/language/python/PythonLanguageTemplateHelper.java
index c5ae583d3d..56e1534400 100644
--- a/code-generation/language-python/src/main/java/org/apache/plc4x/language/python/PythonLanguageTemplateHelper.java
+++ b/code-generation/language-python/src/main/java/org/apache/plc4x/language/python/PythonLanguageTemplateHelper.java
@@ -20,41 +20,55 @@ package org.apache.plc4x.language.python;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.math.NumberUtils;
-import org.apache.commons.text.WordUtils;
+import org.apache.commons.text.CaseUtils;
+import org.apache.plc4x.plugins.codegenerator.language.mspec.model.definitions.DefaultArgument;
+import org.apache.plc4x.plugins.codegenerator.language.mspec.model.references.*;
 import org.apache.plc4x.plugins.codegenerator.language.mspec.model.terms.DefaultStringLiteral;
 import org.apache.plc4x.plugins.codegenerator.protocol.freemarker.BaseFreemarkerLanguageTemplateHelper;
 import org.apache.plc4x.plugins.codegenerator.protocol.freemarker.FreemarkerException;
 import org.apache.plc4x.plugins.codegenerator.protocol.freemarker.Tracer;
 import org.apache.plc4x.plugins.codegenerator.types.definitions.*;
+import org.apache.plc4x.plugins.codegenerator.types.enums.EnumValue;
 import org.apache.plc4x.plugins.codegenerator.types.fields.*;
 import org.apache.plc4x.plugins.codegenerator.types.references.*;
 import org.apache.plc4x.plugins.codegenerator.types.terms.*;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.util.*;
-import java.util.function.Function;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.*;
+
 @SuppressWarnings({"unused", "WeakerAccess"})
 public class PythonLanguageTemplateHelper extends BaseFreemarkerLanguageTemplateHelper {
 
-    private static final Logger LOGGER = LoggerFactory.getLogger(PythonLanguageTemplateHelper.class);
+    private static final Logger LOGGER = LoggerFactory.getLogger(BaseFreemarkerLanguageTemplateHelper.class);
 
-    private final Map<String, String> options;
+    // TODO: we could condense it to one import set as these can be emitted per template and are not hardcoded anymore
 
-    public SortedSet<String> requiredImports = new TreeSet<>();
+    public final SortedSet<String> requiredImports = new TreeSet<>();
 
-    public SortedSet<String> requiredImportsForDataIo = new TreeSet<>();
+    public final SortedSet<String> requiredImportsForDataIo = new TreeSet<>();
 
-    public PythonLanguageTemplateHelper(TypeDefinition thisType, String protocolName, String flavorName, Map<String, TypeDefinition> types,
-                                      Map<String, String> options) {
+    public PythonLanguageTemplateHelper(TypeDefinition thisType, String protocolName, String flavorName, Map<String, TypeDefinition> types) {
         super(thisType, protocolName, flavorName, types);
-        this.options = options;
+    }
+
+    public String fileName(String protocolName, String languageName, String languageFlavorName) {
+        return String.join("", protocolName.split("\\-")) + "." +
+            String.join("", languageFlavorName.split("\\-"));
+    }
+
+    public String getSanitizedPackageName() {
+        String sanitizedName = getProtocolName().replaceAll("-", "");
+        sanitizedName = sanitizedName.replaceAll("\\.", "/");
+        sanitizedName = sanitizedName.toLowerCase();
+        return sanitizedName;
+    }
+
+    // TODO: check if protocol name can be enforced to only contain valid chars
+    public String getSanitizedProtocolName() {
+        String sanitizedName = getProtocolName().replaceAll("-", "");
+        sanitizedName = CaseUtils.toCamelCase(sanitizedName, false, '.');
+        return sanitizedName;
     }
 
     public String packageName() {
@@ -62,46 +76,51 @@ public class PythonLanguageTemplateHelper extends BaseFreemarkerLanguageTemplate
     }
 
     public String packageName(String protocolName, String languageName, String languageFlavorName) {
-        return Optional.ofNullable(options.get("package")).orElseGet(() ->
-                String.join("", protocolName.split("-")) + "." +
-                String.join("", languageFlavorName.split("-")));
-    }
-
-    public String packageName(String languageFlavorName) {
-        return String.join("", languageFlavorName.split("\\-"));
+        return String.join("", protocolName.split("-")) + "." +
+                String.join("", languageFlavorName.split("-"));
     }
 
     @Override
     public String getLanguageTypeNameForField(Field field) {
+        boolean optional = field instanceof OptionalField;
         // If the referenced type is a DataIo type, the value is of type PlcValue.
-        if (field.isPropertyField()) {
-            PropertyField propertyField = field.asPropertyField().orElseThrow(IllegalStateException::new);
-            if (propertyField.getType().isComplexTypeReference()) {
-                ComplexTypeReference complexTypeReference = propertyField.getType().asComplexTypeReference().orElseThrow(IllegalStateException::new);
-                final TypeDefinition typeDefinition = getTypeDefinitions().get(complexTypeReference.getName());
+        if (field instanceof PropertyField) {
+            PropertyField propertyField = (PropertyField) field;
+            if (propertyField.getType() instanceof ComplexTypeReference) {
+                ComplexTypeReference complexTypeReference = (ComplexTypeReference) propertyField.getType();
+                final TypeDefinition typeDefinition = complexTypeReference.getTypeDefinition();
                 if (typeDefinition instanceof DataIoTypeDefinition) {
-                    emitRequiredImport(complexTypeReference.getName());
                     return "PlcValue";
                 }
             }
         }
-        return getLanguageTypeNameForTypeReference(((TypedField) field).getType(), !field.isOptionalField());
-    }
-
-    public String getNonPrimitiveLanguageTypeNameForField(TypedField field) {
-        return getLanguageTypeNameForTypeReference(field.getType(), false);
+        TypedField typedField = field.asTypedField().orElseThrow();
+        String encoding = null;
+        Optional<Term> encodingAttribute = field.getAttribute("encoding");
+        if(encodingAttribute.isPresent()) {
+            encoding = encodingAttribute.get().toString();
+        }
+        return getLanguageTypeNameForTypeReference(typedField.getType(), encoding);
     }
 
-    public String getLanguageTypeNameForSpecType(TypeReference typeReference) {
-        return getLanguageTypeNameForTypeReference(typeReference, true);
+    public boolean isComplex(Field field) {
+        return field instanceof PropertyField && ((PropertyField) field).getType() instanceof NonSimpleTypeReference;
     }
 
     @Override
     public String getLanguageTypeNameForTypeReference(TypeReference typeReference) {
-        return getLanguageTypeNameForTypeReference(typeReference, false);
+        return getLanguageTypeNameForTypeReference(typeReference, null);
+    }
+
+    public String getNonPrimitiveLanguageTypeNameForField(TypedField field) {
+        return getLanguageTypeNameForTypeReference(field.getType(), false);
+    }
+
+    public String getLanguageTypeNameForTypeReference(TypeReference typeReference, boolean allowPrimitives) {
+        return getLanguageTypeNameForTypeReference(typeReference, null);
     }
 
-    public String getLanguageTypeNameForTypeReference(TypeReference typeReference, boolean allowPrimitive) {
+    public String getLanguageTypeNameForTypeReference(TypeReference typeReference, String encoding) {
         if (typeReference == null) {
             // TODO: shouldn't this be an error case
             return "";
@@ -116,6 +135,9 @@ public class PythonLanguageTemplateHelper extends BaseFreemarkerLanguageTemplate
             emitRequiredImport("from plc4py.protocols." + protocolName + "." + flavorName.replace("-", "") + "." + typeReference.asNonSimpleTypeReference().orElseThrow().getName() + " import " + typeReference.asNonSimpleTypeReference().orElseThrow().getName());
             return typeReference.asNonSimpleTypeReference().orElseThrow().getName();
         }
+        if (typeReference instanceof ByteOrderTypeReference) {
+            return "binary.byteOrder";
+        }
         SimpleTypeReference simpleTypeReference = typeReference.asSimpleTypeReference().orElseThrow();
         switch (simpleTypeReference.getBaseType()) {
             case BIT:
@@ -190,200 +212,19 @@ public class PythonLanguageTemplateHelper extends BaseFreemarkerLanguageTemplate
         }
     }
 
-    public String getPlcValueTypeForTypeReference(TypeReference typeReference) {
-        if (!(typeReference instanceof SimpleTypeReference)) {
-            return "PlcStruct";
-        }
-        SimpleTypeReference simpleTypeReference = (SimpleTypeReference) typeReference;
-        switch (simpleTypeReference.getBaseType()) {
-            case BIT:
-                return "PlcBOOL";
-            case BYTE:
-                return "PlcSINT";
-            case UINT:
-                IntegerTypeReference unsignedIntegerTypeReference = (IntegerTypeReference) simpleTypeReference;
-                if (unsignedIntegerTypeReference.getSizeInBits() <= 4) {
-                    return "PlcUSINT";
-                }
-                if (unsignedIntegerTypeReference.getSizeInBits() <= 8) {
-                    return "PlcUINT";
-                }
-                if (unsignedIntegerTypeReference.getSizeInBits() <= 16) {
-                    return "PlcUDINT";
-                }
-                if (unsignedIntegerTypeReference.getSizeInBits() <= 32) {
-                    return "PlcULINT";
-                }
-            case INT:
-                IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
-                if (integerTypeReference.getSizeInBits() <= 8) {
-                    return "PlcSINT";
-                }
-                if (integerTypeReference.getSizeInBits() <= 16) {
-                    return "PlcINT";
-                }
-                if (integerTypeReference.getSizeInBits() <= 32) {
-                    return "PlcDINT";
-                }
-                if (integerTypeReference.getSizeInBits() <= 64) {
-                    return "PlcLINT";
-                }
-
-            case FLOAT:
-            case UFLOAT:
-                FloatTypeReference floatTypeReference = (FloatTypeReference) simpleTypeReference;
-                int sizeInBits = floatTypeReference.getSizeInBits();
-                if (sizeInBits <= 32) {
-                    return "PlcREAL";
-                }
-                if (sizeInBits <= 64) {
-                    return "PlcLREAL";
-                }
-            case STRING:
-            case VSTRING:
-                return "PlcSTRING";
-            case TIME:
-            case DATE:
-            case DATETIME:
-                return "PlcTIME";
-        }
-        throw new RuntimeException("Unsupported simple type");
-    }
-
-    @Override
-    public String getNullValueForTypeReference(TypeReference typeReference) {
-        if (typeReference instanceof SimpleTypeReference) {
-            SimpleTypeReference simpleTypeReference = (SimpleTypeReference) typeReference;
-            switch (simpleTypeReference.getBaseType()) {
-                case BIT:
-                    return "False";
-                case BYTE:
-                    return "0";
-                case UINT:
-                    IntegerTypeReference unsignedIntegerTypeReference = (IntegerTypeReference) simpleTypeReference;
-                    if (unsignedIntegerTypeReference.getSizeInBits() <= 16) {
-                        return "0";
-                    }
-                    if (unsignedIntegerTypeReference.getSizeInBits() <= 32) {
-                        return "0l";
-                    }
-                    return "None";
-                case INT:
-                    IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
-                    if (integerTypeReference.getSizeInBits() <= 32) {
-                        return "0";
-                    }
-                    if (integerTypeReference.getSizeInBits() <= 64) {
-                        return "0l";
-                    }
-                    return "None";
-                case FLOAT:
-                    FloatTypeReference floatTypeReference = (FloatTypeReference) simpleTypeReference;
-                    int sizeInBits = floatTypeReference.getSizeInBits();
-                    if (sizeInBits <= 32) {
-                        return "0.0f";
-                    }
-                    if (sizeInBits <= 64) {
-                        return "0.0";
-                    }
-                    return "None";
-                case STRING:
-                case VSTRING:
-                    return "None";
-            }
-            throw new FreemarkerException("Unmapped base-type" + simpleTypeReference.getBaseType());
-        } else {
-            return "None";
-        }
-    }
-
-    public int getNumBits(SimpleTypeReference simpleTypeReference) {
-        switch (simpleTypeReference.getBaseType()) {
-            case BIT:
-                return 1;
-            case BYTE:
-                return 8;
-            case UINT:
-            case INT:
-                IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
-                return integerTypeReference.getSizeInBits();
-            case FLOAT:
-                FloatTypeReference floatTypeReference = (FloatTypeReference) simpleTypeReference;
-                return floatTypeReference.getSizeInBits();
-            case STRING:
-                StringTypeReference stringTypeReference = (StringTypeReference) simpleTypeReference;
-                return stringTypeReference.getSizeInBits();
-            case VSTRING:
-                throw new IllegalArgumentException("getSizeInBits doesn't work for 'vstring' fields");
-            default:
-                return 0;
+    public String getFieldOptions(TypedField field, List<Argument> parserArguments) {
+        StringBuilder sb = new StringBuilder();
+        final Optional<Term> encodingOptional = field.getEncoding();
+        if (encodingOptional.isPresent()) {
+            final String encoding = toParseExpression(field, field.getType(), encodingOptional.get(), parserArguments);
+            sb.append(", WithOption.WithEncoding(").append(encoding).append(")");
         }
-    }
-
-    @Deprecated
-    @Override
-    public String getReadBufferReadMethodCall(SimpleTypeReference simpleTypeReference, String valueString, TypedField field) {
-        return getReadBufferReadMethodCall("", simpleTypeReference, valueString, field);
-    }
-
-    @Deprecated
-    public String getReadBufferReadMethodCall(String logicalName, SimpleTypeReference simpleTypeReference, String valueString, TypedField field) {
-        switch (simpleTypeReference.getBaseType()) {
-            case BIT:
-                String bitType = "Bit";
-                return "read_buffer.read" + bitType + "(\"" + logicalName + "\")";
-            case BYTE:
-                String byteType = "Byte";
-                return "read_buffer.read" + byteType + "(\"" + logicalName + "\")";
-            case UINT:
-                String unsignedIntegerType;
-                IntegerTypeReference unsignedIntegerTypeReference = (IntegerTypeReference) simpleTypeReference;
-                if (unsignedIntegerTypeReference.getSizeInBits() <= 4) {
-                    unsignedIntegerType = "UnsignedByte";
-                } else if (unsignedIntegerTypeReference.getSizeInBits() <= 8) {
-                    unsignedIntegerType = "UnsignedShort";
-                } else if (unsignedIntegerTypeReference.getSizeInBits() <= 16) {
-                    unsignedIntegerType = "UnsignedInt";
-                } else if (unsignedIntegerTypeReference.getSizeInBits() <= 32) {
-                    unsignedIntegerType = "UnsignedLong";
-                } else {
-                    unsignedIntegerType = "UnsignedBigInteger";
-                }
-                return "read_buffer.read" + unsignedIntegerType + "(\"" + logicalName + "\", " + simpleTypeReference.getSizeInBits() + ")";
-            case INT:
-                String integerType;
-                if (simpleTypeReference.getSizeInBits() <= 8) {
-                    integerType = "SignedByte";
-                } else if (simpleTypeReference.getSizeInBits() <= 16) {
-                    integerType = "Short";
-                } else if (simpleTypeReference.getSizeInBits() <= 32) {
-                    integerType = "Int";
-                } else if (simpleTypeReference.getSizeInBits() <= 64) {
-                    integerType = "Long";
-                } else {
-                    integerType = "BigInteger";
-                }
-                return "read_buffer.read" + integerType + "(\"" + logicalName + "\", " + simpleTypeReference.getSizeInBits() + ")";
-            case FLOAT:
-                String floatType = (simpleTypeReference.getSizeInBits() <= 32) ? "Float" : "Double";
-                return "read_buffer.read" + floatType + "(\"" + logicalName + "\", " + simpleTypeReference.getSizeInBits() + ")";
-            case STRING:
-            case VSTRING:
-                String stringType = "String";
-                final Term encodingTerm = field.getEncoding().orElse(new DefaultStringLiteral("UTF-8"));
-                if (!(encodingTerm instanceof StringLiteral)) {
-                    throw new RuntimeException("Encoding must be a quoted string value");
-                }
-                String encoding = ((StringLiteral) encodingTerm).getValue();
-                String length = Integer.toString(simpleTypeReference.getSizeInBits());
-                if (simpleTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.VSTRING) {
-                    VstringTypeReference vstringTypeReference = (VstringTypeReference) simpleTypeReference;
-                    length = toParseExpression(field, INT_TYPE_REFERENCE, vstringTypeReference.getLengthExpression(), null);
-                }
-                return "read_buffer.read" + stringType + "(\"" + logicalName + "\", " + length + ", \"" +
-                    encoding + "\")";
+        final Optional<Term> byteOrderOptional = field.getByteOrder();
+        if (byteOrderOptional.isPresent()) {
+            final String byteOrder = toParseExpression(field, field.getType(), byteOrderOptional.get(), parserArguments);
+            sb.append(", WithOption.WithByteOrder(").append(byteOrder).append(")");
         }
-        return "# TODO: migrate me " + "";
+        return sb.toString();
     }
 
     public String getDataReaderCall(TypeReference typeReference) {
@@ -502,488 +343,767 @@ public class PythonLanguageTemplateHelper extends BaseFreemarkerLanguageTemplate
         final int sizeInBits = simpleTypeReference.getSizeInBits();
         switch (simpleTypeReference.getBaseType()) {
             case BIT:
-                return "write_boolean(write_buffer)";
+                return "write_boolean";
             case BYTE:
-                return "write_byte(write_buffer, " + sizeInBits + ")";
+                return "write_byte";
             case UINT:
-                if (sizeInBits <= 4) return "write_unsigned_byte(write_buffer, " + sizeInBits + ")";
-                if (sizeInBits <= 8) return "write_unsigned_short(write_buffer, " + sizeInBits + ")";
-                if (sizeInBits <= 16) return "write_unsigned_int(write_buffer, " + sizeInBits + ")";
-                if (sizeInBits <= 32) return "write_unsigned_long(write_buffer, " + sizeInBits + ")";
-                return "write_unsigned_big_integer(write_buffer, " + sizeInBits + ")";
+                if (sizeInBits <= 8) return "write_unsigned_byte";
+                if (sizeInBits <= 16) return "write_unsigned_short";
+                if (sizeInBits <= 32) return "write_unsigned_int";
+                return "write_unsigned_long";
             case INT:
-                if (sizeInBits <= 8) return "write_signed_byte(write_buffer, " + sizeInBits + ")";
-                if (sizeInBits <= 16) return "write_signed_short(write_buffer, " + sizeInBits + ")";
-                if (sizeInBits <= 32) return "write_signed_int(write_buffer, " + sizeInBits + ")";
-                if (sizeInBits <= 64) return "write_signed_long(write_buffer, " + sizeInBits + ")";
-                return "write_signed_big_integer(write_buffer, " + sizeInBits + ")";
+                if (sizeInBits <= 8) return "write_signed_byte";
+                if (sizeInBits <= 16) return "write_signed_short";
+                if (sizeInBits <= 32) return "write_signed_int";
+                return "write_signed_long";
             case FLOAT:
-                if (sizeInBits <= 32) return "write_float(write_buffer, " + sizeInBits + ")";
-                if (sizeInBits <= 64) return "write_double(write_buffer, " + sizeInBits + ")";
-                return "write_big_decimal(write_buffer, " + sizeInBits + ")";
+                if (sizeInBits <= 32) return "write_float";
+                return "write_double";
             case STRING:
-                return "write_string(write_buffer, " + sizeInBits + ")";
+                return "write_string";
             case VSTRING:
                 VstringTypeReference vstringTypeReference = (VstringTypeReference) simpleTypeReference;
-                return "write_string(write_buffer, " + toParseExpression(null, INT_TYPE_REFERENCE, vstringTypeReference.getLengthExpression(), null) + ")";
+                return "write_string";
             case TIME:
-                return "write_time(write_buffer)";
+                return "write_time";
             case DATE:
-                return "write_date(write_buffer)";
+                return "write_date";
             case DATETIME:
-                return "write_date_time(write_buffer)";
+                return "write_date_time";
             default:
-                throw new UnsupportedOperationException("Unsupported type " + simpleTypeReference.getBaseType());
+                return "";
         }
     }
 
-    @Deprecated
-    @Override
-    public String getWriteBufferWriteMethodCall(SimpleTypeReference simpleTypeReference, String fieldName, TypedField field) {
-        return getWriteBufferWriteMethodCall("", simpleTypeReference, fieldName, field);
-    }
-
-    @Deprecated
-    public String getWriteBufferWriteMethodCall(String logicalName, SimpleTypeReference simpleTypeReference, String fieldName, TypedField field, String... writerArgs) {
-        String writerArgsString = "";
-        if (writerArgs.length > 0) {
-            writerArgsString += ", " + StringUtils.join(writerArgs, ", ");
+    public String getPlcValueTypeForTypeReference(TypeReference typeReference) {
+        if (typeReference == null) {
+            // TODO: shouldn't this be an error case
+            return "";
+        }
+        if (typeReference.isNonSimpleTypeReference()) {
+            return ((NonSimpleTypeReference) typeReference).getName();
         }
+        SimpleTypeReference simpleTypeReference = (SimpleTypeReference) typeReference;
         switch (simpleTypeReference.getBaseType()) {
             case BIT:
-                return "writeBuffer.writeBit(\"" + logicalName + "\", bool( " + fieldName + "" + writerArgsString + "))";
+                return "PlcBOOL";
             case BYTE:
-                ByteTypeReference byteTypeReference = (ByteTypeReference) simpleTypeReference;
-                return "writeBuffer.writeByte(\"" + logicalName + "\", (" + fieldName + ").byteValue()" + writerArgsString + ")";
+                return "PlcSINT";
             case UINT:
                 IntegerTypeReference unsignedIntegerTypeReference = (IntegerTypeReference) simpleTypeReference;
                 if (unsignedIntegerTypeReference.getSizeInBits() <= 4) {
-                    return "writeBuffer.writeUnsignedByte(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + ", " + fieldName + ".byteValue()" + writerArgsString + ")";
+                    return "PlcUSINT";
                 }
                 if (unsignedIntegerTypeReference.getSizeInBits() <= 8) {
-                    return "writeBuffer.writeUnsignedShort(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + ", " + fieldName + ".shortValue()" + writerArgsString + ")";
+                    return "PlcUINT";
                 }
                 if (unsignedIntegerTypeReference.getSizeInBits() <= 16) {
-                    return "writeBuffer.writeUnsignedInt(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + ", " + fieldName + ".intValue()" + writerArgsString + ")";
+                    return "PlcUDINT";
                 }
                 if (unsignedIntegerTypeReference.getSizeInBits() <= 32) {
-                    return "writeBuffer.writeUnsignedLong(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + ", " + fieldName + ".longValue()" + writerArgsString + ")";
+                    return "PlcULINT";
                 }
-                return "writeBuffer.writeUnsignedBigInteger(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + ", " + fieldName + "" + writerArgsString + ")";
             case INT:
                 IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
                 if (integerTypeReference.getSizeInBits() <= 8) {
-                    return "writeBuffer.writeSignedByte(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + ", " + fieldName + ".byteValue()" + writerArgsString + ")";
+                    return "PlcSINT";
                 }
                 if (integerTypeReference.getSizeInBits() <= 16) {
-                    return "writeBuffer.writeShort(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + ", " + fieldName + ".shortValue()" + writerArgsString + ")";
+                    return "PlcINT";
                 }
                 if (integerTypeReference.getSizeInBits() <= 32) {
-                    return "writeBuffer.writeInt(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + ", " + fieldName + ".intValue()" + writerArgsString + ")";
+                    return "PlcDINT";
                 }
                 if (integerTypeReference.getSizeInBits() <= 64) {
-                    return "writeBuffer.writeLong(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + ", " + fieldName + ".longValue()" + writerArgsString + ")";
+                    return "PlcLINT";
                 }
-                return "writeBuffer.writeBigInteger(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + ", " + fieldName + "" + writerArgsString + ")";
+
             case FLOAT:
             case UFLOAT:
                 FloatTypeReference floatTypeReference = (FloatTypeReference) simpleTypeReference;
-                if (floatTypeReference.getSizeInBits() <= 32) {
-                    return "writeBuffer.writeFloat(\"" + logicalName + "\", " + floatTypeReference.getSizeInBits() + "," + fieldName + "" + writerArgsString + ")";
-                } else if (floatTypeReference.getSizeInBits() <= 64) {
-                    return "writeBuffer.writeDouble(\"" + logicalName + "\", " + floatTypeReference.getSizeInBits() + "," + fieldName + "" + writerArgsString + ")";
-                } else {
-                    throw new RuntimeException("Unsupported float type");
+                int sizeInBits = floatTypeReference.getSizeInBits();
+                if (sizeInBits <= 32) {
+                    return "PlcREAL";
+                }
+                if (sizeInBits <= 64) {
+                    return "PlcLREAL";
                 }
             case STRING:
             case VSTRING:
-                final Term encodingTerm = field.getEncoding().orElse(new DefaultStringLiteral("UTF-8"));
-                if (!(encodingTerm instanceof StringLiteral)) {
-                    throw new RuntimeException("Encoding must be a quoted string value");
-                }
-                String encoding = ((StringLiteral) encodingTerm).getValue();
-                String length = Integer.toString(simpleTypeReference.getSizeInBits());
-                if (simpleTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.VSTRING) {
-                    VstringTypeReference vstringTypeReference = (VstringTypeReference) simpleTypeReference;
-                    length = toSerializationExpression(field, INT_TYPE_REFERENCE, vstringTypeReference.getLengthExpression(), thisType.getParserArguments().orElse(Collections.emptyList()));
-                }
-                return "writeBuffer.writeString(\"" + logicalName + "\", " + length + ", \"" +
-                    encoding + "\", (String) " + fieldName + "" + writerArgsString + ")";
+                return "PlcSTRING";
+            case TIME:
+            case DATE:
+            case DATETIME:
+                return "PlcTIME";
+            default:
+                return "";
         }
-        throw new FreemarkerException("Unmapped basetype" + simpleTypeReference.getBaseType());
     }
 
-    public String getReservedValue(ReservedField reservedField) {
-        final String languageTypeName = getLanguageTypeNameForTypeReference(reservedField.getType(), true);
-        return languageTypeName + "(" + reservedField.getReferenceValue() + ")";
-    }
-
-    /**
-     * @param field           this generally only is needed in order to access field attributes such as encoding etc.
-     * @param resultType      the type the resulting expression should have
-     * @param term            the term representing the expression
-     * @param parserArguments any parser arguments, which could be referenced in expressions (Needed for getting the type)
-     * @return Java code which does the things defined in 'term'
-     */
-    public String toParseExpression(Field field, TypeReference resultType, Term term, List<Argument> parserArguments) {
-        Tracer tracer = Tracer.start("toParseExpression");
-        return tracer + toExpression(field, resultType, term, variableLiteral -> tracer.dive("variableExpressionGenerator") + toVariableParseExpression(field, resultType, variableLiteral, parserArguments));
-    }
+    @Override
+    public String getNullValueForTypeReference(TypeReference typeReference) {
+        if (typeReference instanceof SimpleTypeReference) {
+            SimpleTypeReference simpleTypeReference = (SimpleTypeReference) typeReference;
+            switch (simpleTypeReference.getBaseType()) {
+                case BIT:
+                    return "False";
+                case BYTE:
+                case UINT:
+                case INT:
+                    return "0";
+                case FLOAT:
+                    return "0.0";
+                case STRING:
+                case VSTRING:
+                    return "\"\"";
+            }
+        } else if (typeReference.isEnumTypeReference()) {
+            return "0";
+        }
+        return "None";
+    }
 
-    /**
-     * @param field               this generally only is needed in order to access field attributes such as encoding etc.
-     * @param resultType          the type the resulting expression should have
-     * @param term                the term representing the expression
-     * @param serializerArguments any serializer arguments, which could be referenced in expressions (Needed for getting the type)
-     * @return Java code which does the things defined in 'term'
-     */
-    public String toSerializationExpression(Field field, TypeReference resultType, Term term, List<Argument> serializerArguments) {
-        Tracer tracer = Tracer.start("toSerializationExpression");
-        return tracer + toExpression(field, resultType, term, variableLiteral -> tracer.dive("variableExpressionGenerator") + toVariableSerializationExpression(field, resultType, variableLiteral, serializerArguments));
+    public int getNumBits(SimpleTypeReference simpleTypeReference) {
+        switch (simpleTypeReference.getBaseType()) {
+            case BIT:
+                return 1;
+            case BYTE:
+                return 8;
+            case UINT:
+            case INT:
+                IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                return integerTypeReference.getSizeInBits();
+            case FLOAT:
+                FloatTypeReference floatTypeReference = (FloatTypeReference) simpleTypeReference;
+                return floatTypeReference.getSizeInBits();
+            case STRING:
+            case VSTRING:
+                StringTypeReference stringTypeReference = (StringTypeReference) simpleTypeReference;
+                return stringTypeReference.getSizeInBits();
+            default:
+                return 0;
+        }
     }
 
-    private String toExpression(Field field, TypeReference resultType, Term term, Function<VariableLiteral, String> variableExpressionGenerator) {
-        Tracer tracer = Tracer.start("toExpression");
-        if (term == null) {
-            return tracer + "";
+    public boolean needsPointerAccess(PropertyField field) {
+        boolean isAnTypeOfOptional = "optional".equals(field.getTypeName());
+        return isAnTypeOfOptional && needPointerAccess(field.getType());
+    }
+
+    public boolean needPointerAccess(TypeReference typeReference) {
+        boolean isNotAnComplexTypeReference = !typeReference.isComplexTypeReference();
+        boolean arrayTypeIsNotAnComplexTypeReference = !(typeReference.isArrayTypeReference() && typeReference.asArrayTypeReference().orElseThrow().getElementTypeReference().isComplexTypeReference());
+        return isNotAnComplexTypeReference && arrayTypeIsNotAnComplexTypeReference;
+    }
+
+    public String getSpecialReadBufferReadMethodCall(String logicalName, SimpleTypeReference simpleTypeReference, TypedField field) {
+        return getReadBufferReadMethodCall(logicalName, simpleTypeReference, null, field);
+    }
+
+    public String getReadBufferReadMethodCall(String logicalName, SimpleTypeReference simpleTypeReference, TypedField field) {
+        return getReadBufferReadMethodCall(logicalName, simpleTypeReference, null, field);
+    }
+
+    @Override
+    public String getReadBufferReadMethodCall(SimpleTypeReference simpleTypeReference, String valueString, TypedField field) {
+        return getReadBufferReadMethodCall("", simpleTypeReference, valueString, field);
+    }
+
+    public String getReadBufferReadMethodCall(String logicalName, SimpleTypeReference simpleTypeReference, String valueString, TypedField field) {
+        switch (simpleTypeReference.getBaseType()) {
+            case BIT:
+                String bitType = "Bit";
+                return "read_buffer.read" + bitType + "(\"" + logicalName + "\")";
+            case BYTE:
+                String byteType = "Byte";
+                return "read_buffer.read" + byteType + "(\"" + logicalName + "\")";
+            case UINT:
+                String unsignedIntegerType;
+                IntegerTypeReference unsignedIntegerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                if (unsignedIntegerTypeReference.getSizeInBits() <= 4) {
+                    unsignedIntegerType = "UnsignedByte";
+                } else if (unsignedIntegerTypeReference.getSizeInBits() <= 8) {
+                    unsignedIntegerType = "UnsignedShort";
+                } else if (unsignedIntegerTypeReference.getSizeInBits() <= 16) {
+                    unsignedIntegerType = "UnsignedInt";
+                } else if (unsignedIntegerTypeReference.getSizeInBits() <= 32) {
+                    unsignedIntegerType = "UnsignedLong";
+                } else {
+                    unsignedIntegerType = "UnsignedBigInteger";
+                }
+                return "read_buffer.read" + unsignedIntegerType + "(\"" + logicalName + "\", " + simpleTypeReference.getSizeInBits() + ")";
+            case INT:
+                String integerType;
+                if (simpleTypeReference.getSizeInBits() <= 8) {
+                    integerType = "SignedByte";
+                } else if (simpleTypeReference.getSizeInBits() <= 16) {
+                    integerType = "Short";
+                } else if (simpleTypeReference.getSizeInBits() <= 32) {
+                    integerType = "Int";
+                } else if (simpleTypeReference.getSizeInBits() <= 64) {
+                    integerType = "Long";
+                } else {
+                    integerType = "BigInteger";
+                }
+                return "read_buffer.read" + integerType + "(\"" + logicalName + "\", " + simpleTypeReference.getSizeInBits() + ")";
+            case FLOAT:
+                String floatType = (simpleTypeReference.getSizeInBits() <= 32) ? "Float" : "Double";
+                return "read_buffer.read" + floatType + "(\"" + logicalName + "\", " + simpleTypeReference.getSizeInBits() + ")";
+            case STRING:
+            case VSTRING:
+                String stringType = "String";
+                final Term encodingTerm = field.getEncoding().orElse(new DefaultStringLiteral("UTF-8"));
+                if (!(encodingTerm instanceof StringLiteral)) {
+                    throw new RuntimeException("Encoding must be a quoted string value");
+                }
+                String encoding = ((StringLiteral) encodingTerm).getValue();
+                String length = Integer.toString(simpleTypeReference.getSizeInBits());
+                if (simpleTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.VSTRING) {
+                    VstringTypeReference vstringTypeReference = (VstringTypeReference) simpleTypeReference;
+                    length = toParseExpression(field, INT_TYPE_REFERENCE, vstringTypeReference.getLengthExpression(), null);
+                }
+                return "read_buffer.read" + stringType + "(\"" + logicalName + "\", " + length + ", \"" +
+                    encoding + "\")";
+            default:
+                return "";
         }
-        if (term instanceof Literal) {
-            return toLiteralTermExpression(field, resultType, (Literal) term, variableExpressionGenerator, tracer);
-        } else if (term instanceof UnaryTerm) {
-            return toUnaryTermExpression(field, resultType, (UnaryTerm) term, variableExpressionGenerator, tracer);
-        } else if (term instanceof BinaryTerm) {
-            return toBinaryTermExpression(field, resultType, (BinaryTerm) term, variableExpressionGenerator, tracer);
-        } else if (term instanceof TernaryTerm) {
-            return toTernaryTermExpression(field, resultType, (TernaryTerm) term, variableExpressionGenerator, tracer);
-        } else {
-            throw new RuntimeException("Unsupported Term type " + term.getClass().getName() + ". Actual type " + resultType);
+    }
+
+    @Override
+    public String getWriteBufferWriteMethodCall(SimpleTypeReference simpleTypeReference, String fieldName, TypedField field) {
+        // Fallback if somewhere the method gets called without a name
+        String logicalName = fieldName.replaceAll("[\"()*]", "").replaceFirst("_", "");
+        return getWriteBufferWriteMethodCall(logicalName, simpleTypeReference, fieldName, field);
+    }
+
+    public String getWriteBufferWriteMethodCall(String logicalName, SimpleTypeReference simpleTypeReference, Term valueTerm, TypedField field, String... writerArgs) {
+        if (valueTerm instanceof BooleanLiteral) {
+            return getWriteBufferWriteMethodCall(logicalName, simpleTypeReference, Boolean.toString(((BooleanLiteral) valueTerm).getValue()), field, writerArgs);
         }
+        if (valueTerm instanceof NumericLiteral) {
+            return getWriteBufferWriteMethodCall(logicalName, simpleTypeReference, ((NumericLiteral) valueTerm).getNumber().toString(), field, writerArgs);
+        }
+        if (valueTerm instanceof HexadecimalLiteral) {
+            return getWriteBufferWriteMethodCall(logicalName, simpleTypeReference, ((HexadecimalLiteral) valueTerm).getHexString(), field, writerArgs);
+        }
+        if (valueTerm instanceof StringLiteral) {
+            return getWriteBufferWriteMethodCall(logicalName, simpleTypeReference, "\"" + ((StringLiteral) valueTerm).getValue() + "\"", field, writerArgs);
+        }
+        throw new RuntimeException("Outputting " + valueTerm.toString() + " not implemented yet. Please continue defining other types in the PythonLanguageHelper.getWriteBufferWriteMethodCall.");
     }
 
-    private String toLiteralTermExpression(Field field, TypeReference resultType, Literal literal, Function<VariableLiteral, String> variableExpressionGenerator, Tracer tracer) {
-        tracer = tracer.dive("literal term instanceOf");
-        if (literal instanceof NullLiteral) {
-            tracer = tracer.dive("null literal instanceOf");
-            return tracer + "null";
-        } else if (literal instanceof BooleanLiteral) {
-            tracer = tracer.dive("boolean literal instanceOf");
-            String bool = Boolean.toString(((BooleanLiteral) literal).getValue());
-            return tracer + bool.substring(0,1).toUpperCase() + bool.substring(1);
-        } else if (literal instanceof NumericLiteral) {
-            tracer = tracer.dive("numeric literal instanceOf");
-            final String numberString = ((NumericLiteral) literal).getNumber().toString();
-            if (resultType.isIntegerTypeReference()) {
-                final IntegerTypeReference integerTypeReference = resultType.asIntegerTypeReference().orElseThrow(RuntimeException::new);
-                if (integerTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.UINT && integerTypeReference.getSizeInBits() >= 32) {
-                    tracer = tracer.dive("uint >= 32bit");
-                    return tracer + numberString + "L";
-                } else if (integerTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.INT && integerTypeReference.getSizeInBits() > 32) {
-                    tracer = tracer.dive("int > 32bit");
-                    return tracer + numberString + "L";
+    public String getWriteBufferWriteMethodCall(String logicalName, SimpleTypeReference simpleTypeReference, String fieldName, TypedField field, String... writerArgs) {
+        String writerArgsString = "";
+        if (writerArgs.length > 0) {
+            writerArgsString += ", " + StringUtils.join(writerArgs, ", ");
+        }
+        switch (simpleTypeReference.getBaseType()) {
+            case BIT:
+                return "writeBuffer.WriteBit(\"" + logicalName + "\", " + fieldName + writerArgsString + ")";
+            case BYTE:
+                return "writeBuffer.WriteByte(\"" + logicalName + "\", " + fieldName + writerArgsString + ")";
+            case UINT:
+                IntegerTypeReference unsignedIntegerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                if (unsignedIntegerTypeReference.getSizeInBits() <= 8) {
+                    return "writeBuffer.WriteUint8(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + ", " + fieldName + writerArgsString + ")";
+                }
+                if (unsignedIntegerTypeReference.getSizeInBits() <= 16) {
+                    return "writeBuffer.WriteUint16(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + ", " + fieldName + writerArgsString + ")";
+                }
+                if (unsignedIntegerTypeReference.getSizeInBits() <= 32) {
+                    return "writeBuffer.WriteUint32(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + ", " + fieldName + writerArgsString + ")";
                 }
-            } else if (resultType.isFloatTypeReference()) {
-                final FloatTypeReference floatTypeReference = resultType.asFloatTypeReference().orElseThrow(RuntimeException::new);
+                if (unsignedIntegerTypeReference.getSizeInBits() <= 64) {
+                    return "writeBuffer.WriteUint64(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + ", " + fieldName + writerArgsString + ")";
+                }
+                return "writeBuffer.WriteBigInt(\"" + logicalName + "\", " + unsignedIntegerTypeReference.getSizeInBits() + ", " + fieldName + writerArgsString + ")";
+            case INT:
+                IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
+                if (integerTypeReference.getSizeInBits() <= 8) {
+                    return "writeBuffer.WriteInt8(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + ", " + fieldName + writerArgsString + ")";
+                }
+                if (integerTypeReference.getSizeInBits() <= 16) {
+                    return "writeBuffer.WriteInt16(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + ", " + fieldName + writerArgsString + ")";
+                }
+                if (integerTypeReference.getSizeInBits() <= 32) {
+                    return "writeBuffer.WriteInt32(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + ", " + fieldName + writerArgsString + ")";
+                }
+                if (integerTypeReference.getSizeInBits() <= 64) {
+                    return "writeBuffer.WriteInt64(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + ", " + fieldName + writerArgsString + ")";
+                }
+                return "writeBuffer.WriteBigInt(\"" + logicalName + "\", " + integerTypeReference.getSizeInBits() + ", " + fieldName + writerArgsString + ")";
+            case FLOAT:
+            case UFLOAT:
+                FloatTypeReference floatTypeReference = (FloatTypeReference) simpleTypeReference;
                 if (floatTypeReference.getSizeInBits() <= 32) {
-                    tracer = tracer.dive("float < 32bit");
-                    return tracer + numberString + "F";
+                    return "writeBuffer.WriteFloat32(\"" + logicalName + "\", " + floatTypeReference.getSizeInBits() + ", " + fieldName + writerArgsString + ")";
                 }
-            }
-            return tracer + numberString;
-        } else if (literal instanceof HexadecimalLiteral) {
-            tracer = tracer.dive("hexadecimal literal instanceOf");
-            final String hexString = ((HexadecimalLiteral) literal).getHexString();
-            if (resultType.isIntegerTypeReference()) {
-                final IntegerTypeReference integerTypeReference = resultType.asIntegerTypeReference().orElseThrow(RuntimeException::new);
-                if (integerTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.UINT && integerTypeReference.getSizeInBits() >= 32) {
-                    tracer = tracer.dive("uint >= 32bit");
-                    return tracer + hexString + "L";
-                } else if (integerTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.INT && integerTypeReference.getSizeInBits() > 32) {
-                    tracer = tracer.dive("int > 32bit");
-                    return tracer + hexString + "L";
+                if (floatTypeReference.getSizeInBits() <= 64) {
+                    return "writeBuffer.WriteFloat64(\"" + logicalName + "\", " + floatTypeReference.getSizeInBits() + ", " + fieldName + writerArgsString + ")";
                 }
+                return "writeBuffer.WriteBigFloat(\"" + logicalName + "\", " + floatTypeReference.getSizeInBits() + ", " + fieldName + writerArgsString + ")";
+            case STRING: {
+                StringTypeReference stringTypeReference = (StringTypeReference) simpleTypeReference;
+                final Term encodingTerm = field.getEncoding().orElse(new DefaultStringLiteral("UTF-8"));
+                String encoding = encodingTerm.asLiteral()
+                    .orElseThrow(() -> new RuntimeException("Encoding must be a literal"))
+                    .asStringLiteral()
+                    .orElseThrow(() -> new RuntimeException("Encoding must be a quoted string value")).getValue();
+                String length = Integer.toString(simpleTypeReference.getSizeInBits());
+                return "writeBuffer.WriteString(\"" + logicalName + "\", uint32(" + length + "), \"" +
+                    encoding + "\", " + fieldName + writerArgsString + ")";
             }
-            return tracer + hexString;
-        } else if (literal instanceof StringLiteral) {
-            tracer = tracer.dive("string literal instanceOf");
-            return tracer + "\"" + ((StringLiteral) literal).getValue() + "\"";
-        } else if (literal instanceof VariableLiteral) {
-            tracer = tracer.dive("variable literal instanceOf");
-            VariableLiteral variableLiteral = (VariableLiteral) literal;
-            if ("curPos".equals(((VariableLiteral) literal).getName())) {
-                return "(positionAware.getPos() - startPos)";
-            }
-            // If this literal references an Enum type, then we have to output it differently.
-            if (getTypeDefinitions().get(variableLiteral.getName()) instanceof EnumTypeDefinition) {
-                tracer = tracer.dive("enum definition instanceOf");
-                VariableLiteral enumDefinitionChild = variableLiteral.getChild()
-                    .orElseThrow(() -> new RuntimeException("enum definitions should have childs"));
-                return tracer + variableLiteral.getName() + "." + enumDefinitionChild.getName() +
-                    enumDefinitionChild.getChild().map(child -> "." + toVariableExpressionRest(field, resultType, child)).orElse("");
-            } else {
-                return tracer + variableExpressionGenerator.apply(variableLiteral);
+            case VSTRING: {
+                VstringTypeReference vstringTypeReference = (VstringTypeReference) simpleTypeReference;
+                final Term encodingTerm = field.getEncoding().orElse(new DefaultStringLiteral("UTF-8"));
+                String encoding = encodingTerm.asLiteral()
+                    .orElseThrow(() -> new RuntimeException("Encoding must be a literal"))
+                    .asStringLiteral()
+                    .orElseThrow(() -> new RuntimeException("Encoding must be a quoted string value")).getValue();
+                String lengthExpression = toExpression(field, null, vstringTypeReference.getLengthExpression(), null, Collections.singletonList(new DefaultArgument("stringLength", new DefaultIntegerTypeReference(SimpleTypeReference.SimpleBaseType.INT, 32))), true, false);
+                String length = Integer.toString(simpleTypeReference.getSizeInBits());
+                return "writeBuffer.WriteString(\"" + logicalName + "\", uint32(" + lengthExpression + "), \"" +
+                    encoding + "\", " + fieldName + writerArgsString + ")";
             }
+            case DATE:
+            case TIME:
+            case DATETIME:
+                return "writeBuffer.WriteUint32(\"" + logicalName + "\", uint32(" + fieldName + ")" + writerArgsString + ")";
+            default:
+                throw new FreemarkerException("Unsupported base type " + simpleTypeReference.getBaseType());
+        }
+    }
+
+    public String getReservedValue(ReservedField reservedField) {
+        final String languageTypeName = getLanguageTypeNameForTypeReference(reservedField.getType());
+        switch (languageTypeName) {
+            case "*big.Int":
+                emitRequiredImport("math/big");
+                return "big.NewInt(" + reservedField.getReferenceValue() + ")";
+            case "*big.Float":
+                emitRequiredImport("math/big");
+                return "*big.Float(" + reservedField.getReferenceValue() + ")";
+            default:
+                return languageTypeName + "(" + reservedField.getReferenceValue() + ")";
+        }
+    }
+
+    public String toTypeSafeCompare(ReservedField reservedField) {
+        final String languageTypeName = getLanguageTypeNameForTypeReference(reservedField.getType());
+        switch (languageTypeName) {
+            case "*big.Int":
+            case "*big.Float":
+                emitRequiredImport("math/big");
+                return "reserved.Cmp(" + getReservedValue(reservedField) + ") != 0";
+            default:
+                return "reserved != " + getReservedValue(reservedField);
+        }
+    }
+
+    public String toParseExpression(Field field, TypeReference resultType, Term term, List<Argument> parserArguments) {
+        Tracer tracer = Tracer.start("toParseExpression");
+        return tracer + toTypedParseExpression(field, resultType, term, parserArguments);
+    }
+
+    public String toParseExpression(Field field, TypeReference resultType, Term term, List<Argument> parserArguments, boolean suppressPointerAccess) {
+        Tracer tracer = Tracer.start("toParseExpression");
+        return tracer + toTypedParseExpression(field, resultType, term, parserArguments, suppressPointerAccess);
+    }
+
+    public String toSerializationExpression(Field field, TypeReference resultType, Term term, List<Argument> serializerArguments) {
+        Tracer tracer = Tracer.start("toSerializationExpression");
+        return tracer + toTypedSerializationExpression(field, resultType, term, serializerArguments);
+    }
+
+    public String toBooleanParseExpression(Field field, Term term, List<Argument> parserArguments) {
+        Tracer tracer = Tracer.start("toBooleanParseExpression");
+        return tracer + toTypedParseExpression(field, new DefaultBooleanTypeReference(), term, parserArguments);
+    }
+
+    public String toBooleanSerializationExpression(Field field, Term term, List<Argument> serializerArguments) {
+        Tracer tracer = Tracer.start("toBooleanSerializationExpression");
+        return tracer + toTypedSerializationExpression(field, new DefaultBooleanTypeReference(), term, serializerArguments);
+    }
+
+    public String toIntegerParseExpression(Field field, int sizeInBits, Term term, List<Argument> parserArguments) {
+        Tracer tracer = Tracer.start("toIntegerParseExpression");
+        return tracer + toTypedParseExpression(field, new DefaultIntegerTypeReference(SimpleTypeReference.SimpleBaseType.UINT, sizeInBits), term, parserArguments);
+    }
+
+    public String toIntegerSerializationExpression(Field field, int sizeInBits, Term term, List<Argument> serializerArguments) {
+        Tracer tracer = Tracer.start("toIntegerSerializationExpression");
+        return tracer + toTypedSerializationExpression(field, new DefaultIntegerTypeReference(SimpleTypeReference.SimpleBaseType.UINT, sizeInBits), term, serializerArguments);
+    }
+
+    public String toTypedParseExpression(Field field, TypeReference fieldType, Term term, List<Argument> parserArguments) {
+        Tracer tracer = Tracer.start("toTypedParseExpression");
+        return tracer + toExpression(field, fieldType, term, parserArguments, null, false, fieldType != null && fieldType.isComplexTypeReference());
+    }
+
+    public String toTypedParseExpression(Field field, TypeReference fieldType, Term term, List<Argument> parserArguments, boolean suppressPointerAccess) {
+        Tracer tracer = Tracer.start("toTypedParseExpression");
+        return tracer + toExpression(field, fieldType, term, parserArguments, null, false, suppressPointerAccess);
+    }
+
+    public String toTypedSerializationExpression(Field field, TypeReference fieldType, Term term, List<Argument> serializerArguments) {
+        Tracer tracer = Tracer.start("toTypedSerializationExpression");
+        return tracer + toExpression(field, fieldType, term, null, serializerArguments, true, false);
+    }
+
+    String getCastExpressionForTypeReference(TypeReference typeReference) {
+        Tracer tracer = Tracer.start("castExpression");
+        if (typeReference instanceof SimpleTypeReference) {
+            return tracer.dive("simpleTypeRef") + getLanguageTypeNameForTypeReference(typeReference);
+        } else if (typeReference instanceof ByteOrderTypeReference) {
+            return tracer.dive( "byteOrderTypeRef") + "binary.ByteOrder";
+        } else if (typeReference != null) {
+            return tracer.dive("anyTypeRef") + "Cast" + getLanguageTypeNameForTypeReference(typeReference);
         } else {
-            throw new RuntimeException("Unsupported Literal type " + literal.getClass().getName());
+            return tracer.dive("noTypeRef") + "";
         }
     }
 
-    private String toUnaryTermExpression(Field field, TypeReference resultType, UnaryTerm unaryTerm, Function<VariableLiteral, String> variableExpressionGenerator, Tracer tracer) {
-        tracer = tracer.dive("unary term instanceOf");
-        Term a = unaryTerm.getA();
-        switch (unaryTerm.getOperation()) {
-            case "!":
-                tracer = tracer.dive("case !");
-                if ((resultType != getAnyTypeReference()) && !resultType.isBooleanTypeReference()) {
-                    throw new IllegalArgumentException("'!(...)' expression requires boolean type. Actual type " + resultType);
+    private String toExpression(Field field, TypeReference fieldType, Term term, List<Argument> parserArguments, List<Argument> serializerArguments, boolean serialize, boolean suppressPointerAccess) {
+        Tracer tracer = Tracer.start("toExpression(suppressPointerAccess=" + suppressPointerAccess + ")");
+        if (term == null) {
+            return "";
+        }
+        if (term instanceof Literal) {
+            return toLiteralTermExpression(field, fieldType, term, parserArguments, serializerArguments, serialize, suppressPointerAccess, tracer);
+        } else if (term instanceof UnaryTerm) {
+            return toUnaryTermExpression(field, fieldType, (UnaryTerm) term, parserArguments, serializerArguments, serialize, tracer);
+        } else if (term instanceof BinaryTerm) {
+            return toBinaryTermExpression(field, fieldType, (BinaryTerm) term, parserArguments, serializerArguments, serialize, tracer);
+        } else if (term instanceof TernaryTerm) {
+            return toTernaryTermExpression(field, fieldType, (TernaryTerm) term, parserArguments, serializerArguments, serialize, tracer);
+        } else {
+            throw new RuntimeException("Unsupported Term type " + term.getClass().getName());
+        }
+    }
+
+    private String toTernaryTermExpression(Field field, TypeReference fieldType, TernaryTerm ternaryTerm, List<Argument> parserArguments, List<Argument> serializerArguments, boolean serialize, Tracer tracer) {
+        tracer = tracer.dive("ternary term instanceOf");
+        if ("if".equals(ternaryTerm.getOperation())) {
+            Term a = ternaryTerm.getA();
+            Term b = ternaryTerm.getB();
+            Term c = ternaryTerm.getC();
+            String castExpressionForTypeReference = getCastExpressionForTypeReference(fieldType);
+            String inlineIf = "utils.InlineIf(" + toExpression(field, new DefaultBooleanTypeReference(), a, parserArguments, serializerArguments, serialize, false) + ", " +
+                "func() any {return " + castExpressionForTypeReference + "(" + toExpression(field, fieldType, b, parserArguments, serializerArguments, serialize, false) + ")}, " +
+                "func() any {return " + castExpressionForTypeReference + "(" + toExpression(field, fieldType, c, parserArguments, serializerArguments, serialize, false) + ")})";
+            if (fieldType != null) {
+                if (fieldType instanceof ByteOrderTypeReference) {
+                    return tracer.dive("byteordertypereference") + "(" + inlineIf + ").(binary.ByteOrder)";
                 }
-                return tracer + "!(" + toExpression(field, resultType, a, variableExpressionGenerator) + ")";
-            case "-":
-                tracer = tracer.dive("case -");
-                if ((resultType != getAnyTypeReference()) && !resultType.isIntegerTypeReference() && !resultType.isFloatTypeReference()) {
-                    throw new IllegalArgumentException("'-(...)' expression requires integer or floating-point type. Actual type " + resultType);
+                if (fieldType.isNonSimpleTypeReference()) {
+                    return tracer.dive("nonsimpletypereference") + castExpressionForTypeReference + "(" + inlineIf + ")";
                 }
-                return tracer + "-(" + toExpression(field, resultType, a, variableExpressionGenerator) + ")";
-            case "()":
-                tracer = tracer.dive("case ()");
-                return tracer + "(" + toExpression(field, resultType, a, variableExpressionGenerator) + ")";
-            default:
-                throw new RuntimeException("Unsupported unary operation type " + unaryTerm.getOperation() + ". Actual type " + resultType);
+                return tracer + inlineIf + ".(" + castExpressionForTypeReference + ")";
+            }
+            return tracer + inlineIf;
+        } else {
+            throw new RuntimeException("Unsupported ternary operation type " + ternaryTerm.getOperation());
         }
     }
 
-    private String toBinaryTermExpression(Field field, TypeReference resultType, BinaryTerm binaryTerm, Function<VariableLiteral, String> variableExpressionGenerator, Tracer tracer) {
+    private String toBinaryTermExpression(Field field, TypeReference fieldType, BinaryTerm binaryTerm, List<Argument> parserArguments, List<Argument> serializerArguments, boolean serialize, Tracer tracer) {
         tracer = tracer.dive("binary term instanceOf");
         Term a = binaryTerm.getA();
         Term b = binaryTerm.getB();
         String operation = binaryTerm.getOperation();
+        String castExpressionForTypeReference = getCastExpressionForTypeReference(fieldType);
         switch (operation) {
-            case "^": {
-                tracer = tracer.dive(operation);
-                if ((resultType != getAnyTypeReference()) && !resultType.isIntegerTypeReference() && !resultType.isFloatTypeReference()) {
-                    throw new IllegalArgumentException("'A^B' expression requires numeric result type. Actual type " + resultType);
-                }
-                return tracer + "Math.pow((" + toExpression(field, resultType, a, variableExpressionGenerator) + "), (" + toExpression(field, resultType, b, variableExpressionGenerator) + "))";
-            }
-            case "*":
-            case "/":
-            case "%":
-            case "+":
-            case "-": {
-                tracer = tracer.dive(operation);
-                if ((resultType != getAnyTypeReference()) && !resultType.isIntegerTypeReference() && !resultType.isFloatTypeReference()) {
-                    throw new IllegalArgumentException("'A" + operation + "B' expression requires numeric result type. Actual type " + resultType);
-                }
-                return tracer + "(" + toExpression(field, resultType, a, variableExpressionGenerator) + ") " + operation + " (" + toExpression(field, resultType, b, variableExpressionGenerator) + ")";
-            }
-            case ">>":
-            case "<<": {
-                tracer = tracer.dive(operation);
-                return tracer + "(" + toExpression(field, resultType, a, variableExpressionGenerator) + ") " + operation + " (" + toExpression(field, INT_TYPE_REFERENCE, b, variableExpressionGenerator) + ")";
-            }
-            case ">=":
-            case "<=":
-            case ">":
-            case "<":
+            case "^":
+                tracer = tracer.dive("^");
+                emitRequiredImport("math");
+                return tracer + "Math.pow(" +
+                    castExpressionForTypeReference + "(" + toExpression(field, fieldType, a, parserArguments, serializerArguments, serialize, false) + "), " +
+                    castExpressionForTypeReference + "(" + toExpression(field, fieldType, b, parserArguments, serializerArguments, serialize, false) + "))";
+            // If we start casting for comparisons, equals or non equals, really messy things happen.
             case "==":
             case "!=":
-                if ((resultType != getAnyTypeReference()) && !resultType.isBooleanTypeReference()) {
-                    throw new IllegalArgumentException("'A" + operation + "B' expression requires boolean result type. Actual type " + resultType);
-                }
-                // TODO: Try to infer the types of the arguments in this case
-                return tracer + "(" + toExpression(field, ANY_TYPE_REFERENCE, a, variableExpressionGenerator) + ") " + operation + " (" + toExpression(field, ANY_TYPE_REFERENCE, b, variableExpressionGenerator) + ")";
-            case "&&":
-            case "||":
-                if ((resultType != getAnyTypeReference()) && !resultType.isBooleanTypeReference()) {
-                    throw new IllegalArgumentException("'A" + operation + "B' expression requires boolean result type. Actual type " + resultType);
-                }
-                return tracer + "(" + toExpression(field, resultType, a, variableExpressionGenerator) + ") " + operation + " (" + toExpression(field, resultType, b, variableExpressionGenerator) + ")";
-            case "&":
+            case ">":
+            case "<":
+            case ">=":
+            case "<=":
+                tracer = tracer.dive("compare");
+                // For every access of optional elements we need pointer access ...
+                // Except for doing a nil or not-nil check :-(
+                // So in case of such a check, we need to suppress the pointer-access.
+                boolean suppressPointerAccessOverride = (operation.equals("==") || operation.equals("!=")) && ((a instanceof NullLiteral) || (b instanceof NullLiteral));
+                String aExpression = toExpression(field, null, a, parserArguments, serializerArguments, serialize, suppressPointerAccessOverride);
+                String bExpression = toExpression(field, null, b, parserArguments, serializerArguments, serialize, suppressPointerAccessOverride);
+                return tracer + "bool((" + aExpression + ") " + operation + " (" + bExpression + "))";
+            case ">>":
+            case "<<":
             case "|":
-                if ((resultType != getAnyTypeReference()) && !resultType.isIntegerTypeReference() && !resultType.isByteTypeReference()) {
-                    throw new IllegalArgumentException("'A" + operation + "B' expression requires byte or integer result type. Actual type " + resultType);
-                }
-                return tracer + "(" + toExpression(field, resultType, a, variableExpressionGenerator) + ") " + operation + " (" + toExpression(field, resultType, b, variableExpressionGenerator) + ")";
+            case "&":
+                tracer = tracer.dive("bitwise");
+                // We don't want casts here
+                return tracer +
+                    toExpression(field, fieldType, a, parserArguments, serializerArguments, serialize, false) +
+                    operation + " " +
+                    toExpression(field, fieldType, b, parserArguments, serializerArguments, serialize, false);
             default:
-                throw new IllegalArgumentException("Unsupported ternary operation type " + operation);
+                tracer = tracer.dive("default");
+                if (fieldType instanceof StringTypeReference) {
+                    tracer = tracer.dive("string type reference");
+                    return tracer + toExpression(field, fieldType, a, parserArguments, serializerArguments, serialize, false) +
+                        operation + " " +
+                        toExpression(field, fieldType, b, parserArguments, serializerArguments, serialize, false);
+                }
+                return tracer +
+                    castExpressionForTypeReference + "(" + toExpression(field, fieldType, a, parserArguments, serializerArguments, serialize, false) + ") " +
+                    operation + " " +
+                    castExpressionForTypeReference + "(" + toExpression(field, fieldType, b, parserArguments, serializerArguments, serialize, false) + ")";
         }
     }
 
-    private String toTernaryTermExpression(Field field, TypeReference resultType, TernaryTerm ternaryTerm, Function<VariableLiteral, String> variableExpressionGenerator, Tracer tracer) {
-        tracer = tracer.dive("ternary term instanceOf");
-        if ("if".equals(ternaryTerm.getOperation())) {
-            Term a = ternaryTerm.getA();
-            Term b = ternaryTerm.getB();
-            Term c = ternaryTerm.getC();
-            return tracer +
-                "(" +
-                "(" + toExpression(field, BOOL_TYPE_REFERENCE, a, variableExpressionGenerator) + ") ? " +
-                toExpression(field, resultType, b, variableExpressionGenerator) + " : " +
-                toExpression(field, resultType, c, variableExpressionGenerator) + "" +
-                ")";
-        } else {
-            throw new IllegalArgumentException("Unsupported ternary operation type " + ternaryTerm.getOperation() + ". Actual type " + resultType);
+    private String toUnaryTermExpression(Field field, TypeReference fieldType, UnaryTerm unaryTerm, List<Argument> parserArguments, List<Argument> serializerArguments, boolean serialize, Tracer tracer) {
+        tracer = tracer.dive("unary term instanceOf");
+        Term a = unaryTerm.getA();
+        switch (unaryTerm.getOperation()) {
+            case "!":
+                tracer = tracer.dive("case !");
+                return tracer + "!(" + toExpression(field, fieldType, a, parserArguments, serializerArguments, serialize, false) + ")";
+            case "-":
+                tracer = tracer.dive("case -");
+                return tracer + "-(" + toExpression(field, fieldType, a, parserArguments, serializerArguments, serialize, false) + ")";
+            case "()":
+                tracer = tracer.dive("case ()");
+                return tracer + "(" + toExpression(field, fieldType, a, parserArguments, serializerArguments, serialize, false) + ")";
+            default:
+                throw new RuntimeException("Unsupported unary operation type " + unaryTerm.getOperation());
         }
     }
 
-    public String toVariableEnumAccessExpression(VariableLiteral variableLiteral) {
-        return variableLiteral.getName();
-    }
-
-    private String toVariableParseExpression(Field field, TypeReference resultType, VariableLiteral variableLiteral, List<Argument> parserArguments) {
-        Tracer tracer = Tracer.start("toVariableParseExpression");
-        // CAST expressions are special as we need to add a ".class" to the second parameter in Java.
-        if ("CAST".equals(variableLiteral.getName())) {
-            return toCastVariableParseExpression(field, resultType, variableLiteral, parserArguments, tracer);
-        }
-        // Special handling for ByteOrder enums (Built in enums)
-        else if ("BIG_ENDIAN".equals(variableLiteral.getName())) {
-            return "ByteOrder.BIG_ENDIAN";
-        } else if ("LITTLE_ENDIAN".equals(variableLiteral.getName())) {
-            return "ByteOrder.LITTLE_ENDIAN";
-        }
-        // If we're referencing an implicit field, we need to handle that differently.
-        else if (isVariableLiteralImplicitField(variableLiteral)) { // If we are accessing implicit fields, we need to rely on a local variable instead.
-            return toImplicitVariableParseExpression(field, resultType, variableLiteral, tracer);
-        }
-        // Call a static function in the drivers StaticHelper
-        else if ("STATIC_CALL".equals(variableLiteral.getName())) {
-            return toStaticCallParseExpression(field, resultType, variableLiteral, parserArguments, tracer);
-        }
-        // Call a built-in global static function
-        else if (variableLiteral.getName().equals(variableLiteral.getName().toUpperCase())) { // All uppercase names are not fields, but utility methods.
-            return toFunctionCallParseExpression(field, resultType, variableLiteral, parserArguments, tracer);
-        }
-        // The synthetic checksumRawData is a local field and should not be accessed as bean property.
-        boolean isParserArg = "read_buffer".equals(variableLiteral.getName());
-        boolean isTypeArg = "_type".equals(variableLiteral.getName());
-        if (!isParserArg && !isTypeArg && parserArguments != null) {
-            for (Argument serializerArgument : parserArguments) {
-                if (serializerArgument.getName().equals(variableLiteral.getName())) {
-                    isParserArg = true;
-                    break;
-                }
+    private String toLiteralTermExpression(Field field, TypeReference fieldType, Term term, List<Argument> parserArguments, List<Argument> serializerArguments, boolean serialize, boolean suppressPointerAccess, Tracer tracer) {
+        tracer = tracer.dive("literal term instanceOf");
+        if (term instanceof NullLiteral) {
+            tracer = tracer.dive("null literal instanceOf");
+            return tracer + "None";
+        } else if (term instanceof BooleanLiteral) {
+            tracer = tracer.dive("boolean literal instanceOf");
+            return tracer + getCastExpressionForTypeReference(fieldType) + "(" + ((BooleanLiteral) term).getValue() + ")";
+        } else if (term instanceof NumericLiteral) {
+            tracer = tracer.dive("numeric literal instanceOf");
+            if (getCastExpressionForTypeReference(fieldType).equals("string")) {
+                tracer = tracer.dive("type reference string");
+                return tracer + "(" + ((NumericLiteral) term).getNumber().toString() + ")";
+            } else {
+                return tracer + getCastExpressionForTypeReference(fieldType) + "(" + ((NumericLiteral) term).getNumber().toString() + ")";
             }
-        }
-        if (isParserArg) {
-            tracer = tracer.dive("parser arg");
-            return tracer + variableLiteral.getName() + variableLiteral.getChild().map(child -> "." + toVariableExpressionRest(field, resultType, child)).orElse("");
-        } else if (isTypeArg) {
-            tracer = tracer.dive("type arg");
-            String part = variableLiteral.getChild().map(VariableLiteral::getName).orElse("");
-            switch (part) {
-                case "name":
-                    return tracer + "\"" + field.getTypeName() + "\"";
-                case "length":
-                    return tracer + "\"" + ((SimpleTypeReference) field).getSizeInBits() + "\"";
-                case "encoding":
-                    String encoding = ((StringLiteral) field.getEncoding().orElse(new DefaultStringLiteral("UTF-8"))).getValue();
-                    return tracer + "\"" + encoding + "\"";
-                default:
-                    return tracer + "";
+        } else if (term instanceof HexadecimalLiteral) {
+            tracer = tracer.dive("hexadecimal literal instanceOf");
+            return tracer + ((HexadecimalLiteral) term).getHexString();
+        } else if (term instanceof StringLiteral) {
+            tracer = tracer.dive("string literal instanceOf");
+            return tracer + "\"" + ((StringLiteral) term).getValue() + "\"";
+        } else if (term instanceof VariableLiteral) {
+            tracer = tracer.dive("variable literal instanceOf");
+            VariableLiteral variableLiteral = (VariableLiteral) term;
+            if ("curPos".equals(((VariableLiteral) term).getName())) {
+                return "(positionAware.GetPos() - startPos)";
+            } else if ("BIG_ENDIAN".equals(((VariableLiteral) term).getName()) && (fieldType instanceof ByteOrderTypeReference)) {
+                return "binary.BigEndian";
+            } else if ("LITTLE_ENDIAN".equals(((VariableLiteral) term).getName()) && (fieldType instanceof ByteOrderTypeReference)) {
+                return "binary.LittleEndian";
             }
+            return tracer + toVariableExpression(field, fieldType, (VariableLiteral) term, parserArguments, serializerArguments, serialize, suppressPointerAccess);
         } else {
-            String indexAddon = "";
-            if (variableLiteral.getIndex().isPresent()) {
-                indexAddon = ".get(" + variableLiteral.getIndex().orElseThrow() + ")";
-            }
-            return tracer + variableLiteral.getName() + indexAddon + variableLiteral.getChild().map(child -> "." + toVariableExpressionRest(field, resultType, child)).orElse("");
+            throw new RuntimeException("Unsupported Literal type " + term.getClass().getName());
         }
     }
 
-    private String toCastVariableParseExpression(Field field, TypeReference resultType, VariableLiteral variableLiteral, List<Argument> parserArguments, Tracer tracer) {
-        tracer = tracer.dive("CAST");
-        List<Term> arguments = variableLiteral.getArgs().orElseThrow(() -> new RuntimeException("A Cast expression needs arguments"));
-        if (arguments.size() != 2) {
-            throw new RuntimeException("A CAST expression expects exactly two arguments.");
-        }
-        VariableLiteral firstArgument = arguments.get(0).asLiteral()
-            .orElseThrow(() -> new RuntimeException("First argument should be a literal"))
-            .asVariableLiteral()
-            .orElseThrow(() -> new RuntimeException("First argument should be a Variable literal"));
-        StringLiteral typeArgument = arguments.get(1).asLiteral().orElseThrow(() -> new RuntimeException("Second argument should be a String literal"))
-            .asStringLiteral()
-            .orElseThrow(() -> new RuntimeException("Second argument should be a String literal"));
-        String sb = "CAST" + "(" +
-            toVariableParseExpression(field, ANY_TYPE_REFERENCE, firstArgument, parserArguments) +
-            ", " +
-            typeArgument.getValue() + ".class)";
-        return tracer + sb + variableLiteral.getChild().map(child -> "." + toVariableExpressionRest(field, resultType, child)).orElse("");
+    private String toVariableExpression(Field field, TypeReference typeReference, VariableLiteral variableLiteral, List<Argument> parserArguments, List<Argument> serializerArguments, boolean serialize, boolean suppressPointerAccess) {
+        return toVariableExpression(field, typeReference, variableLiteral, parserArguments, serializerArguments, serialize, suppressPointerAccess, false);
     }
 
-    private String toImplicitVariableParseExpression(Field field, TypeReference resultType, VariableLiteral variableLiteral, Tracer tracer) {
-        tracer = tracer.dive("implicit");
-        return tracer + variableLiteral.getName();
-    }
+    private String toVariableExpression(Field field, TypeReference typeReference, VariableLiteral variableLiteral, List<Argument> parserArguments, List<Argument> serializerArguments, boolean serialize, boolean suppressPointerAccess, boolean isChild) {
+        Tracer tracer = Tracer.start("toVariableExpression(serialize=" + serialize + ")");
+        String variableLiteralName = variableLiteral.getName();
+        boolean isEnumTypeReference = typeReference != null && typeReference.isEnumTypeReference();
+        if ("lengthInBytes".equals(variableLiteralName)) {
+            return toLengthInBytesVariableExpression(typeReference, serialize, tracer);
+        } else if ("lengthInBits".equals(variableLiteralName)) {
+            return toLengthInBitsVariableExpression(typeReference, serialize, tracer);
+        } else if ("_value".equals(variableLiteralName)) {
+            return toValueVariableExpression(field, typeReference, variableLiteral, parserArguments, serializerArguments, serialize, suppressPointerAccess, tracer);
+        }
+        if ("_lastItem".equals(variableLiteralName)) {
+            return toLastItemVariableExpression(typeReference, serialize, tracer);
+        }
+        if ("length".equals(variableLiteral.getChild().map(VariableLiteral::getName).orElse(""))) {
+            return toLengthVariableExpression(field, variableLiteral, serialize, tracer);
+        }
+        // If this literal references an Enum type, then we have to output it differently.
+        else if (getTypeDefinitions().get(variableLiteralName) instanceof EnumTypeDefinition) {
+            return toEnumVariableExpression(field, typeReference, variableLiteral, parserArguments, serializerArguments, suppressPointerAccess, tracer);
+        }
+        // If we are accessing enum constants, these also need to be output differently.
+        else if (thisType.isComplexTypeDefinition()
+            && thisType.asComplexTypeDefinition()
+            .orElseThrow(IllegalAccessError::new)
+            .getPropertyFieldByName(variableLiteralName)
+            .filter(EnumField.class::isInstance)
+            .isPresent()
+            && (variableLiteral.getChild().isPresent())
+        ) {
+            return toConstantVariableExpression(field, typeReference, variableLiteral, parserArguments, serializerArguments, suppressPointerAccess, tracer);
+        }
+        // If we are accessing optional fields, (we might need to use pointer-access).
+        else if (!serialize && thisType.isComplexTypeDefinition()
+            && thisType.asComplexTypeDefinition()
+            .orElseThrow(IllegalStateException::new)
+            .getPropertyFieldByName(variableLiteralName)
+            .filter(OptionalField.class::isInstance)
+            .isPresent()
+        ) {
+            tracer = tracer.dive("non serialize optional fields");
+            return toOptionalVariableExpression(field, typeReference, variableLiteral, parserArguments, serializerArguments, suppressPointerAccess, tracer);
+        }
+        // If we are accessing optional fields, (we might need to use pointer-access).
+        else if (thisType.isComplexTypeDefinition()
+            && thisType.asComplexTypeDefinition()
+            .orElseThrow(IllegalStateException::new)
+            .getPropertyFieldByName(variableLiteralName)
+            .filter(OptionalField.class::isInstance)
+            .isPresent()
+        ) {
+            tracer = tracer.dive("optional fields");
+            OptionalField optionalField = thisType.asComplexTypeDefinition().orElseThrow().getPropertyFieldByName(variableLiteralName).orElseThrow().asOptionalField().orElseThrow();
+            return tracer + "(" + (suppressPointerAccess || optionalField.getType().isComplexTypeReference() ? "" : "*") + "self." + camelCaseToSnakeCase(variableLiteral.getName()) + ")" +
+                variableLiteral.getChild().map(child -> "." + camelCaseToSnakeCase(toVariableExpression(field, typeReference, child, parserArguments, serializerArguments, false, suppressPointerAccess, true))).orElse("");
+        }
+        // If we are accessing implicit fields, we need to rely on local variable instead.
+        //else if (isVariableLiteralImplicitField(vl)) {
+        //    tracer = tracer.dive("implicit");
+        //    return tracer + (serialize ? vl.getName() : vl.getName()) + ((vl.getChild() != null) ?
+        //        "." + capitalize(toVariableExpression(typeReference, vl.getChild(), parserArguments, serializerArguments, false, suppressPointerAccess)) : "");
+        //}
+        // If we are accessing implicit fields, we need to rely on a local variable instead.
 
-    private String toStaticCallParseExpression(Field field, TypeReference resultType, VariableLiteral variableLiteral, List<Argument> parserArguments, Tracer tracer) {
-        tracer = tracer.dive("STATIC_CALL");
-        List<Term> arguments = variableLiteral.getArgs().orElseThrow(() -> new RuntimeException("A STATIC_CALL expression needs arguments"));
-        if (arguments.size() < 1) {
-            throw new RuntimeException("A STATIC_CALL expression expects at least one argument.");
+        // CAST expressions are special as we need to add a ".class" to the second parameter in Java.
+        else if ("CAST".equals(variableLiteralName)) {
+            return toCastVariableExpression(field, typeReference, variableLiteral, parserArguments, serializerArguments, serialize, suppressPointerAccess, tracer);
+        } else if ("STATIC_CALL".equals(variableLiteralName)) {
+            return toStaticCallVariableExpression(field, typeReference, variableLiteral, parserArguments, serializerArguments, serialize, suppressPointerAccess, tracer);
+        } else if (!isEnumTypeReference && "COUNT".equals(variableLiteralName)) {
+            return toCountVariableExpression(field, typeReference, variableLiteral, parserArguments, serializerArguments, serialize, suppressPointerAccess, tracer);
+        } else if (!isEnumTypeReference && "ARRAY_SIZE_IN_BYTES".equals(variableLiteralName)) {
+            return toArraySizeInBytesVariableExpression(field, typeReference, variableLiteral, parserArguments, serializerArguments, suppressPointerAccess, tracer);
+        } else if ("CEIL".equals(variableLiteralName)) {
+            return toCeilVariableExpression(field, variableLiteral, parserArguments, serializerArguments, serialize, suppressPointerAccess, tracer);
+        } else if ("STR_LEN".equals(variableLiteralName)) {
+            return toStrLenVariableExpression(field, typeReference, variableLiteral, parserArguments, serializerArguments, serialize, suppressPointerAccess, tracer);
         }
-        // TODO: make it as static import with a emitImport so if a static call is present a "utils" package must be present in the import
-        StringBuilder sb = new StringBuilder();
-        sb.append(packageName()).append(".utils.StaticHelper.");
-        // Get the class and method name
-        String methodName = arguments.get(0).asLiteral()
-            .orElseThrow(() -> new RuntimeException("First argument should be a literal"))
-            .asStringLiteral()
-            .orElseThrow(() -> new RuntimeException("Expecting the first argument of a 'STATIC_CALL' to be a StringLiteral")).
-            getValue();
-        sb.append(methodName).append("(");
-        for (int i = 1; i < arguments.size(); i++) {
-            Term arg = arguments.get(i);
-            if (i > 1) {
-                sb.append(", ");
-            }
-            sb.append(toParseExpression(field, ANY_TYPE_REFERENCE, arg, parserArguments));
-           /*if (arg instanceof VariableLiteral) {
-                VariableLiteral variableLiteralArg = (VariableLiteral) arg;
-                // "readBuffer" is the default name of the reader argument which is always available.
-                boolean isParserArg = "readBuffer".equals(variableLiteralArg.getName());
-                boolean isTypeArg = "_type".equals(variableLiteralArg.getName());
-                if (!isParserArg && !isTypeArg && parserArguments != null) {
-                    for (Argument parserArgument : parserArguments) {
-                        if (parserArgument.getName().equals(variableLiteralArg.getName())) {
-                            isParserArg = true;
-                            break;
-                        }
+        // All uppercase names are not fields, but utility methods.
+        // TODO: It seems we also run into this, in case of using enum constants in type-switches.
+        else if (variableLiteralName.equals(variableLiteralName.toUpperCase())) {
+            tracer = tracer.dive("utility");
+            return toUppercaseVariableExpression(field, typeReference, variableLiteral, parserArguments, serializerArguments, serialize, suppressPointerAccess, tracer);
+        }
+        // If the current property references a discriminator value, we have to serialize it differently.
+        else if (thisType.isComplexTypeDefinition() && thisType.asComplexTypeDefinition()
+            .orElseThrow(IllegalStateException::new)
+            .getPropertyFieldFromThisOrParentByName(variableLiteralName)
+            .filter(DiscriminatorField.class::isInstance)
+            .isPresent()) {
+            tracer = tracer.dive("discriminator value");
+            // TODO: Should this return something?
+        }
+        // If the variable has a child element and we're able to find a type for this ... get the type.
+        else if ((variableLiteral.getChild().isPresent()) && ((ComplexTypeDefinition) thisType).getTypeReferenceForProperty(variableLiteralName).isPresent()) {
+            tracer = tracer.dive("child element");
+            final Optional<NonSimpleTypeReference> typeReferenceForProperty = ((ComplexTypeDefinition) thisType).getTypeReferenceForProperty(variableLiteralName)
+                .flatMap(TypeReferenceConversions::asNonSimpleTypeReference);
+            if (typeReferenceForProperty.isPresent()) {
+                tracer = tracer.dive("complex");
+                final NonSimpleTypeReference nonSimpleTypeReference = typeReferenceForProperty.get();
+                TypeDefinition typeDefinition = nonSimpleTypeReference.getTypeDefinition();
+                if (typeDefinition instanceof ComplexTypeDefinition) {
+                    tracer = tracer.dive("complex");
+                    ComplexTypeDefinition complexTypeDefinition = (ComplexTypeDefinition) typeDefinition;
+                    String childProperty = variableLiteral.getChild()
+                        .orElseThrow(() -> new RuntimeException("complex needs a child"))
+                        .getName();
+                    final Optional<Field> matchingDiscriminatorField = complexTypeDefinition.getFields().stream()
+                        .filter(curField -> (curField instanceof DiscriminatorField) && ((DiscriminatorField) curField).getName().equals(childProperty))
+                        .findFirst();
+                    if (matchingDiscriminatorField.isPresent()) {
+                        return tracer + "Cast" + getLanguageTypeNameForTypeReference(nonSimpleTypeReference) + "(" + variableLiteralName + ").get_" + camelCaseToSnakeCase(childProperty) + "()";
                     }
-                }
-                if (isParserArg) {
-                    sb.append(variableLiteralArg.getName()).append(variableLiteralArg.getChild().map(child -> "." + toVariableExpressionRest(child)).orElse(""));
-                } else if (isTypeArg) {// We have to manually evaluate the type information at code-generation time.
-                    String part = variableLiteralArg.getChild().map(VariableLiteral::getName).orElse("");
-                    switch (part) {
-                        case "name":
-                            sb.append("\"").append(field.getTypeName()).append("\"");
-                            break;
-                        case "length":
-                            sb.append("\"").append(((SimpleTypeReference) field).getSizeInBits()).append("\"");
-                            break;
-                        case "encoding":
-                            String encoding = ((StringLiteral) field.getEncoding().orElse(new DefaultStringLiteral("UTF-8"))).getValue();
-                            sb.append("\"").append(encoding).append("\"");
-                            break;
+                    // TODO: is this really meant to fall through?
+                    tracer = tracer.dive("we fell through the complex complex");
+                } else if (typeDefinition instanceof EnumTypeDefinition) {
+                    tracer = tracer.dive("enum");
+                    String variableAccess = variableLiteralName;
+                    if (isChild) {
+                        variableAccess = "" + camelCaseToSnakeCase(variableLiteralName);
                     }
-                } else {
-                    sb.append(toVariableParseExpression(field, variableLiteralArg, null));
+                    return tracer + (serialize ? "self." + camelCaseToSnakeCase(variableLiteralName) + "" : variableAccess) +
+                        "." + camelCaseToSnakeCase(variableLiteral.getChild().orElseThrow(() -> new RuntimeException("enum needs a child")).getName()) + "()";
                 }
-            } else if (arg instanceof StringLiteral) {
-                sb.append(((StringLiteral) arg).getValue());
-            }*/
+            }
+            // TODO: is this really meant to fall through?
+            tracer = tracer.dive("we fell through the child complete");
+        } else if (isVariableLiteralImplicitField(variableLiteral)) {
+            tracer = tracer.dive("implicit");
+            if (serialize) {
+                tracer = tracer.dive("serialize");
+                final ImplicitField referencedImplicitField = getReferencedImplicitField(variableLiteral);
+                return tracer + toSerializationExpression(referencedImplicitField, referencedImplicitField.getType(), getReferencedImplicitField(variableLiteral).getSerializeExpression(), serializerArguments);
+            } else {
+                return tracer + variableLiteralName;
+                //return toParseExpression(getReferencedImplicitField(vl), getReferencedImplicitField(vl).getSerializeExpression(), serializerArguments);
+            }
         }
-        sb.append(")");
+
+        // This is a special case for DataIo string types, which need to access the stringLength
+        if ((serializerArguments != null) && serializerArguments.stream()
+            .anyMatch(argument -> argument.getName().equals(variableLiteralName)) && "stringLength".equals(variableLiteralName)) {
+            tracer = tracer.dive("serialization argument");
+            return tracer + variableLiteralName +
+                variableLiteral.getChild()
+                    .map(child -> "." + camelCaseToSnakeCase(toVariableExpression(field, typeReference, child, parserArguments, serializerArguments, false, suppressPointerAccess, true)))
+                    .orElse("");
+        } else if ((serializerArguments != null) && serializerArguments.stream()
+            .anyMatch(argument -> argument.getName().equals(variableLiteralName))) {
+            tracer = tracer.dive("serialization argument");
+            return tracer + "self." + camelCaseToSnakeCase(variableLiteralName) +
+                variableLiteral.getChild()
+                    .map(child -> "." + camelCaseToSnakeCase(toVariableExpression(field, typeReference, child, parserArguments, serializerArguments, false, suppressPointerAccess, true)))
+                    .orElse("");
+        }
+        if ((parserArguments != null) && parserArguments.stream()
+            .anyMatch(argument -> argument.getName().equals(variableLiteralName))) {
+            tracer = tracer.dive("parser argument");
+            return tracer + variableLiteralName +
+                variableLiteral.getChild()
+                    .map(child -> "." + camelCaseToSnakeCase(toVariableExpression(field, typeReference, child, parserArguments, serializerArguments, false, suppressPointerAccess, true)))
+                    .orElse("");
+        }
+        String indexCall = "";
         if (variableLiteral.getIndex().isPresent()) {
-            // TODO: If this is a byte typed field, this needs to be an array accessor instead.
-            sb.append(".get(").append(variableLiteral.getIndex().orElseThrow()).append(")");
+            tracer = tracer.dive("indexCall");
+            // We have a index call
+            indexCall = "[" + variableLiteral.getIndex().orElseThrow() + "]";
         }
-        return tracer + sb.toString();
+        tracer = tracer.dive("else");
+        Tracer tracer2 = tracer;
+        String variableAccess = variableLiteralName;
+        if (isChild) {
+            variableAccess = "get_" + camelCaseToSnakeCase(variableAccess) + "()";
+        }
+        return tracer + (serialize ? "self." + camelCaseToSnakeCase(variableLiteralName) + "" : variableAccess) + indexCall +
+            variableLiteral.getChild()
+                .map(child -> "." + camelCaseToSnakeCase(toVariableExpression(field, typeReference, child, parserArguments, serializerArguments, false, suppressPointerAccess, true)))
+                .orElse("");
     }
 
-    private String toFunctionCallParseExpression(Field field, TypeReference resultType, VariableLiteral variableLiteral, List<Argument> parserArguments, Tracer tracer) {
-        tracer = tracer.dive("FunctionCall");
-        StringBuilder sb = new StringBuilder(variableLiteral.getName());
+    private String toUppercaseVariableExpression(Field field, TypeReference typeReference, VariableLiteral variableLiteral, List<Argument> parserArguments, List<Argument> serializerArguments, boolean serialize, boolean suppressPointerAccess, Tracer tracer) {
+        tracer = tracer.dive("toUppercaseVariableExpression");
+        StringBuilder sb = new StringBuilder("get_" + camelCaseToSnakeCase(variableLiteral.getName()) + "()");
         if (variableLiteral.getArgs().isPresent()) {
             sb.append("(");
             boolean firstArg = true;
@@ -991,195 +1111,242 @@ public class PythonLanguageTemplateHelper extends BaseFreemarkerLanguageTemplate
                 if (!firstArg) {
                     sb.append(", ");
                 }
-                // TODO: Try to infer the type of the argument ...
-                sb.append(toParseExpression(field, ANY_TYPE_REFERENCE, arg, parserArguments));
+                sb.append(toExpression(field, typeReference, arg, parserArguments, serializerArguments, serialize, suppressPointerAccess));
                 firstArg = false;
             }
             sb.append(")");
         }
         if (variableLiteral.getIndex().isPresent()) {
-            // TODO: If this is a byte typed field, this needs to be an array accessor instead.
-            sb.append(".get(").append(variableLiteral.getIndex().orElseThrow()).append(")");
+            sb.append("[").append(variableLiteral.getIndex().orElseThrow()).append("]");
         }
-        return tracer + sb.toString() + variableLiteral.getChild().map(child -> "." + toVariableExpressionRest(field, resultType, child)).orElse("");
+        return tracer + sb.toString() + variableLiteral.getChild()
+            .map(child -> "." + toVariableExpression(field, typeReference, child, parserArguments, serializerArguments, false, suppressPointerAccess, true))
+            .orElse("");
     }
 
-    private String toVariableSerializationExpression(Field field, TypeReference resultType, VariableLiteral variableLiteral, List<Argument> serialzerArguments) {
-        Tracer tracer = Tracer.start("variable serialization expression");
-        if ("STATIC_CALL".equals(variableLiteral.getName())) {
-            return toStaticCallSerializationExpression(field, resultType, variableLiteral, serialzerArguments, tracer);
-        }
-        // All uppercase names are not fields, but utility methods.
-        else if (variableLiteral.getName().equals(variableLiteral.getName().toUpperCase())) {
-            return toGlobalFunctionCallSerializationExpression(field, resultType, variableLiteral, serialzerArguments, tracer);
-        } else if (isVariableLiteralImplicitField(variableLiteral)) { // If we are accessing implicit fields, we need to rely on a local variable instead.
-            tracer = tracer.dive("implicit field");
-            final ImplicitField referencedImplicitField = getReferencedImplicitField(variableLiteral);
-            return tracer + toSerializationExpression(referencedImplicitField, referencedImplicitField.getType(), getReferencedImplicitField(variableLiteral).getSerializeExpression(), serialzerArguments);
-        } else if (isVariableLiteralVirtualField(variableLiteral)) {
-            tracer = tracer.dive("virtual field");
-            return tracer + toVariableExpressionRest(field, resultType, variableLiteral);
-        }
-        // The synthetic checksumRawData is a local field and should not be accessed as bean property.
-        boolean isSerializerArg = "write_buffer".equals(variableLiteral.getName()) || "checksum_raw_data".equals(variableLiteral.getName()) || "_value".equals(variableLiteral.getName()) || "element".equals(variableLiteral.getName()) || "size".equals(variableLiteral.getName());
-        boolean isTypeArg = "_type".equals(variableLiteral.getName());
-        if (!isSerializerArg && !isTypeArg && serialzerArguments != null) {
-            for (Argument serializerArgument : serialzerArguments) {
-                if (serializerArgument.getName().equals(variableLiteral.getName())) {
+    private String toCeilVariableExpression(Field field, VariableLiteral variableLiteral, List<Argument> parserArguments, List<Argument> serializerArguments, boolean serialize, boolean suppressPointerAccess, Tracer tracer) {
+        tracer = tracer.dive("ceil");
+        Term va = variableLiteral.getArgs().orElseThrow(() -> new RuntimeException("CEIL needs at least one arg"))
+            .stream().findFirst().orElseThrow(IllegalStateException::new);
+        // The Ceil function expects 64 bit floating point values.
+        TypeReference tr = new DefaultFloatTypeReference(SimpleTypeReference.SimpleBaseType.FLOAT, 64);
+        emitRequiredImport("math");
+        return tracer + "math.Ceil(" + toExpression(field, tr, va, parserArguments, serializerArguments, serialize, suppressPointerAccess) + ")";
+    }
+
+    private String toArraySizeInBytesVariableExpression(Field field, TypeReference typeReference, VariableLiteral variableLiteral, List<Argument> parserArguments, List<Argument> serializerArguments, boolean suppressPointerAccess, Tracer tracer) {
+        tracer = tracer.dive("array size in bytes");
+        VariableLiteral va = variableLiteral.getArgs()
+            .orElseThrow(() -> new RuntimeException("ARRAY_SIZE_IN_BYTES needs at least one arg"))
+            .stream().findFirst().orElseThrow(IllegalStateException::new)
+            .asLiteral()
+            .orElseThrow(() -> new RuntimeException("ARRAY_SIZE_IN_BYTES needs a literal"))
+            .asVariableLiteral()
+            .orElseThrow(() -> new RuntimeException("ARRAY_SIZE_IN_BYTES needs a variable literal"));
+        // "io" and "m" are always available in every parser.
+        boolean isSerializerArg = "readBuffer".equals(va.getName()) || "writeBuffer".equals(va.getName()) || "m".equals(va.getName()) || "element".equals(va.getName());
+        if (!isSerializerArg && serializerArguments != null) {
+            for (Argument serializerArgument : serializerArguments) {
+                if (serializerArgument.getName().equals(va.getName())) {
                     isSerializerArg = true;
                     break;
                 }
             }
         }
+        StringBuilder sb = new StringBuilder();
         if (isSerializerArg) {
-            tracer = tracer.dive("serializer arg");
-            return tracer + variableLiteral.getName() + variableLiteral.getChild().map(child -> "." + toVariableExpressionRest(field, resultType, child)).orElse("");
-        } else if (isTypeArg) {
-            tracer = tracer.dive("type arg");
-            String part = variableLiteral.getChild().map(VariableLiteral::getName).orElse("");
-            switch (part) {
-                case "name":
-                    return tracer + "\"" + field.getTypeName() + "\"";
-                case "length":
-                    return tracer + "\"" + ((SimpleTypeReference) field).getSizeInBits() + "\"";
-                case "encoding":
-                    String encoding = ((StringLiteral) field.getEncoding().orElse(new DefaultStringLiteral("UTF-8"))).getValue();
-                    return tracer + "\"" + encoding + "\"";
-                default:
-                    return tracer + "";
-            }
+            sb.append(va.getName()).append(va.getChild().map(child -> "." + toVariableExpression(field, typeReference, child, parserArguments, serializerArguments, true, suppressPointerAccess, true)).orElse(""));
         } else {
-            return tracer + toVariableExpressionRest(field, resultType, variableLiteral);
+            sb.append(toVariableExpression(field, typeReference, va, parserArguments, serializerArguments, true, suppressPointerAccess));
         }
+        return tracer + getCastExpressionForTypeReference(typeReference) + "(" + va.getName() + "ArraySizeInBytes(" + sb + "))";
     }
 
-    private String toGlobalFunctionCallSerializationExpression(Field field, TypeReference resultType, VariableLiteral variableLiteral, List<Argument> serialzerArguments, Tracer tracer) {
-        tracer = tracer.dive("GLOBAL_FUNCTION_CALL");
-        StringBuilder sb = new StringBuilder(variableLiteral.getName());
-        if (variableLiteral.getArgs().isPresent()) {
-            sb.append("(");
-            boolean firstArg = true;
-            for (Term arg : variableLiteral.getArgs().get()) {
-                if (!firstArg) {
-                    sb.append(", ");
-                }
-                sb.append(toSerializationExpression(field, ANY_TYPE_REFERENCE, arg, serialzerArguments));
-                firstArg = false;
-                /*if (arg instanceof VariableLiteral) {
-                    VariableLiteral va = (VariableLiteral) arg;
-                    boolean isSerializerArg = "readBuffer".equals(va.getName()) || "writeBuffer".equals(va.getName());
-                    boolean isTypeArg = "_type".equals(va.getName());
-                    if (!isSerializerArg && !isTypeArg && serialzerArguments != null) {
-                        for (Argument serializerArgument : serialzerArguments) {
-                            if (serializerArgument.getName().equals(va.getName())) {
-                                isSerializerArg = true;
-                                break;
-                            }
-                        }
-                    }
-                    if (isSerializerArg) {
-                        sb.append(va.getName()).append(va.getChild().map(child -> "." + toVariableExpressionRest(child)).orElse(""));
-                    } else if (isTypeArg) {
-                        String part = va.getChild().map(VariableLiteral::getName).orElse("");
-                        switch (part) {
-                            case "name":
-                                sb.append("\"").append(field.getTypeName()).append("\"");
-                                break;
-                            case "length":
-                                sb.append("\"").append(((SimpleTypeReference) field).getSizeInBits()).append("\"");
-                                break;
-                            case "encoding":
-                                String encoding = ((StringLiteral) field.getEncoding().orElse(new DefaultStringLiteral("UTF-8"))).getValue();
-                                sb.append("\"").append(encoding).append("\"");
-                                break;
-                        }
-                    } else {
-                        sb.append(toVariableSerializationExpression(field, va, serialzerArguments));
-                    }
-                } else if (arg instanceof StringLiteral) {
-                    sb.append(((StringLiteral) arg).getValue());
-                }*/
-            }
-            sb.append(")");
-        }
-        return tracer + sb.toString();
+    private String toCountVariableExpression(Field field, TypeReference typeReference, VariableLiteral variableLiteral, List<Argument> parserArguments, List<Argument> serializerArguments, boolean serialize, boolean suppressPointerAccess, Tracer tracer) {
+        tracer = tracer.dive("count");
+        VariableLiteral countLiteral = variableLiteral.getArgs()
+            .orElseThrow(() -> new RuntimeException("Count needs at least one arg"))
+            .get(0)
+            .asLiteral()
+            .orElseThrow(() -> new RuntimeException("Count needs a literal"))
+            .asVariableLiteral()
+            .orElseThrow(() -> new RuntimeException("Count needs a variable literal"));
+        return tracer + (typeReference instanceof SimpleTypeReference ? getCastExpressionForTypeReference(typeReference) : "") + "(len(" +
+            toVariableExpression(field, typeReference, countLiteral, parserArguments, serializerArguments, serialize, suppressPointerAccess) +
+            "))";
+    }
+
+    private String toStrLenVariableExpression(Field field, TypeReference typeReference, VariableLiteral variableLiteral, List<Argument> parserArguments, List<Argument> serializerArguments, boolean serialize, boolean suppressPointerAccess, Tracer tracer) {
+        tracer = tracer.dive("str-len");
+        VariableLiteral countLiteral = variableLiteral.getArgs()
+            .orElseThrow(() -> new RuntimeException("Str-len needs at least one arg"))
+            .get(0)
+            .asLiteral()
+            .orElseThrow(() -> new RuntimeException("Str-len needs a literal"))
+            .asVariableLiteral()
+            .orElseThrow(() -> new RuntimeException("Str-len needs a variable literal"));
+        return tracer + (typeReference instanceof SimpleTypeReference ? getCastExpressionForTypeReference(typeReference) : "") + "(len(" +
+            toVariableExpression(field, typeReference, countLiteral, parserArguments, serializerArguments, serialize, suppressPointerAccess) +
+            "))";
     }
 
-    private String toStaticCallSerializationExpression(Field field, TypeReference resultType, VariableLiteral variableLiteral, List<Argument> serialzerArguments, Tracer tracer) {
+    private String toStaticCallVariableExpression(Field field, TypeReference typeReference, VariableLiteral variableLiteral, List<Argument> parserArguments, List<Argument> serializerArguments, boolean serialize, boolean suppressPointerAccess, Tracer tracer) {
         tracer = tracer.dive("STATIC_CALL");
         StringBuilder sb = new StringBuilder();
         List<Term> arguments = variableLiteral.getArgs().orElseThrow(() -> new RuntimeException("A STATIC_CALL expression needs arguments"));
         if (arguments.size() < 1) {
             throw new RuntimeException("A STATIC_CALL expression expects at least one argument.");
         }
-        // TODO: make it as static import with a emitImport so if a static call is present a "utils" package must be present in the import
-        sb.append(packageName()).append(".utils.StaticHelper.");
         // Get the class and method name
-        String methodName = arguments.get(0).asLiteral()
+        String staticCall = arguments.get(0).asLiteral()
             .orElseThrow(() -> new RuntimeException("First argument should be a literal"))
             .asStringLiteral()
             .orElseThrow(() -> new RuntimeException("Expecting the first argument of a 'STATIC_CALL' to be a StringLiteral")).
             getValue();
-        //methodName = methodName.substring(1, methodName.length() - 1);
-        sb.append(methodName).append("(");
+        sb.append(camelCaseToSnakeCase(staticCall)).append("(");
         for (int i = 1; i < arguments.size(); i++) {
             Term arg = arguments.get(i);
             if (i > 1) {
                 sb.append(", ");
             }
-            sb.append(toSerializationExpression(field, ANY_TYPE_REFERENCE, arg, serialzerArguments));
-            /*if (arg instanceof VariableLiteral) {
+            if (arg instanceof UnaryTerm) {
+                arg = ((UnaryTerm) arg).getA();
+            }
+            if (arg instanceof VariableLiteral) {
+                tracer = tracer.dive("VariableLiteral nr." + i);
                 VariableLiteral va = (VariableLiteral) arg;
-                // "readBuffer" and "_value" are always available in every parser.
-                boolean isSerializerArg = "readBuffer".equals(va.getName()) || "writeBuffer".equals(va.getName()) || "_value".equals(va.getName()) || "element".equals(va.getName());
+                // "io" is the default name of the reader argument which is always available.
+                boolean isParserArg = "readBuffer".equals(va.getName()) || "writeBuffer".equals(va.getName()) || ((thisType instanceof DataIoTypeDefinition) && "_value".equals(va.getName()));
                 boolean isTypeArg = "_type".equals(va.getName());
-                if (!isSerializerArg && !isTypeArg && serialzerArguments != null) {
-                    for (Argument serializerArgument : serialzerArguments) {
-                        if (serializerArgument.getName().equals(va.getName())) {
-                            isSerializerArg = true;
+                if (!isParserArg && !isTypeArg && parserArguments != null) {
+                    for (Argument parserArgument : parserArguments) {
+                        if (parserArgument.getName().equals(va.getName())) {
+                            isParserArg = true;
                             break;
                         }
                     }
                 }
-                if (isSerializerArg) {
-                    sb.append(va.getName()).append(va.getChild().map(child -> "." + toVariableExpressionRest(child)).orElse(""));
-                } else if (isTypeArg) {
+                if (isParserArg) {
+                    tracer = tracer.dive("isParserArg");
+                    if (va.getName().equals("_value")) {
+                        tracer = tracer.dive("is _value");
+                        sb.append(va.getName().substring(1)).append(va.getChild().map(child -> "." + toVariableExpression(field, typeReference, child, parserArguments, serializerArguments, false, suppressPointerAccess, true)).orElse(""));
+                    } else {
+                        sb.append(va.getName()).append((va.getChild().isPresent()) ?
+                            ".get_" + camelCaseToSnakeCase(toVariableExpression(field, typeReference, va.getChild().orElseThrow(IllegalStateException::new), parserArguments, serializerArguments, false, suppressPointerAccess)) + "()" : "");
+                    }
+                }
+                // We have to manually evaluate the type information at code-generation time.
+                else if (isTypeArg) {
                     String part = va.getChild().map(VariableLiteral::getName).orElse("");
                     switch (part) {
                         case "name":
-                            sb.append("\"").append(field.getTypeName()).append("\"");
+//                                sb.append("\"").append(field.getTypeName()).append("\"");
                             break;
                         case "length":
-                            sb.append("\"").append(((SimpleTypeReference) field).getSizeInBits()).append("\"");
+                            sb.append("\"").append(((SimpleTypeReference) typeReference).getSizeInBits()).append("\"");
                             break;
                         case "encoding":
-                            String encoding = ((StringLiteral) field.getEncoding().orElse(new DefaultStringLiteral("UTF-8"))).getValue();
+                            final Term encodingTerm = field.getEncoding().orElse(new DefaultStringLiteral("UTF-8"));
+                            if (!(encodingTerm instanceof StringLiteral)) {
+                                throw new RuntimeException("Encoding must be a quoted string value");
+                            }
+                            String encoding = ((StringLiteral) encodingTerm).getValue();
                             sb.append("\"").append(encoding).append("\"");
                             break;
                     }
                 } else {
-                    sb.append(toVariableSerializationExpression(field, va, serialzerArguments));
+                    sb.append(toVariableExpression(field, typeReference, va, parserArguments, serializerArguments, serialize, suppressPointerAccess));
                 }
             } else if (arg instanceof StringLiteral) {
+                tracer = tracer.dive("StringLiteral");
                 sb.append(((StringLiteral) arg).getValue());
-            }*/
+            } else if (arg instanceof BooleanLiteral) {
+                tracer = tracer.dive("BooleanLiteral");
+                sb.append(((BooleanLiteral) arg).getValue());
+            } else if (arg instanceof NumericLiteral) {
+                tracer = tracer.dive("NumericLiteral");
+                sb.append(((NumericLiteral) arg).getNumber());
+            } else if (arg instanceof BinaryTerm) {
+                tracer = tracer.dive("BinaryTerm");
+                sb.append(toBinaryTermExpression(field, typeReference, (BinaryTerm) arg, parserArguments, serializerArguments, serialize, tracer));
+            } else {
+                throw new RuntimeException(arg.getClass().getName());
+            }
         }
         sb.append(")");
         return tracer + sb.toString();
     }
 
-    private String toVariableExpressionRest(Field field, TypeReference resultType, VariableLiteral variableLiteral) {
-        Tracer tracer = Tracer.start("variable expression rest");
-        // length is kind of a keyword in mspec, so we shouldn't be naming variables length. if we ask for the length of a object we can just return length().
-        // This way we can get the length of a string when serializing
-        String variableLiteralName = variableLiteral.getName();
-        if (variableLiteralName.equals("length")) {
-            tracer = tracer.dive("length");
-            return tracer + variableLiteralName + "()" + ((variableLiteral.getIndex().isPresent() ? ".get(" + variableLiteral.getIndex().orElseThrow() + ")" : "") +
-                variableLiteral.getChild().map(child -> "." + toVariableExpressionRest(field, resultType, child)).orElse(""));
+    private String toCastVariableExpression(Field field, TypeReference typeReference, VariableLiteral variableLiteral, List<Argument> parserArguments, List<Argument> serializerArguments, boolean serialize, boolean suppressPointerAccess, Tracer tracer) {
+        tracer = tracer.dive("CAST");
+        List<Term> arguments = variableLiteral.getArgs().orElseThrow(() -> new RuntimeException("A Cast expression needs arguments"));
+        if (arguments.size() != 2) {
+            throw new RuntimeException("A CAST expression expects exactly two arguments.");
+        }
+        VariableLiteral firstArgument = arguments.get(0).asLiteral()
+            .orElseThrow(() -> new RuntimeException("First argument should be a literal"))
+            .asVariableLiteral()
+            .orElseThrow(() -> new RuntimeException("First argument should be a Variable literal"));
+        StringLiteral typeLiteral = arguments.get(1).asLiteral()
+            .orElseThrow(() -> new RuntimeException("Second argument should be a String literal"))
+            .asStringLiteral()
+            .orElseThrow(() -> new RuntimeException("Second argument should be a String literal"));
+        final TypeDefinition typeDefinition = getTypeDefinitions().get(typeLiteral.getValue());
+        StringBuilder sb = new StringBuilder();
+        if (typeDefinition.isComplexTypeDefinition()) {
+            sb.append("Cast");
         }
-        return tracer + "self." + camelCaseToSnakeCase(variableLiteralName) + "()" + ((variableLiteral.getIndex().isPresent() ? ".get(" + variableLiteral.getIndex().orElseThrow() + ")" : "") +
-            variableLiteral.getChild().map(child -> "." + toVariableExpressionRest(field, resultType, child)).orElse(""));
+        sb.append(typeLiteral.getValue());
+        sb.append("(").append(toVariableExpression(field, typeReference, firstArgument, parserArguments, serializerArguments, serialize, suppressPointerAccess)).append(")");
+        return tracer + sb.toString() + variableLiteral.getChild().map(child -> "." + camelCaseToSnakeCase(toVariableExpression(field, typeReference, child, parserArguments, serializerArguments, false, suppressPointerAccess, true))).orElse("");
+    }
+
+    private String toOptionalVariableExpression(Field field, TypeReference typeReference, VariableLiteral variableLiteral, List<Argument> parserArguments, List<Argument> serializerArguments, boolean suppressPointerAccess, Tracer tracer) {
+        tracer = tracer.dive("optional fields");
+        return tracer + "(" + (suppressPointerAccess || (typeReference != null && typeReference.isComplexTypeReference()) ? "" : "*") + variableLiteral.getName() + ")" +
+            variableLiteral.getChild().map(child -> "." + camelCaseToSnakeCase(toVariableExpression(field, typeReference, child, parserArguments, serializerArguments, false, suppressPointerAccess, true))).orElse("");
+    }
+
+    private String toConstantVariableExpression(Field field, TypeReference typeReference, VariableLiteral variableLiteral, List<Argument> parserArguments, List<Argument> serializerArguments, boolean suppressPointerAccess, Tracer tracer) {
+        tracer = tracer.dive("enum constant");
+        VariableLiteral child = variableLiteral.getChild().orElseThrow(IllegalStateException::new);
+        return tracer + variableLiteral.getName() + "." + camelCaseToSnakeCase(child.getName()) + "()" +
+            child.getChild().map(childChild -> "." + toVariableExpression(field, typeReference, childChild, parserArguments, serializerArguments, false, suppressPointerAccess, true)).orElse("");
+    }
+
+    private String toEnumVariableExpression(Field field, TypeReference typeReference, VariableLiteral variableLiteral, List<Argument> parserArguments, List<Argument> serializerArguments, boolean suppressPointerAccess, Tracer tracer) {
+        tracer = tracer.dive("enum");
+        VariableLiteral child = variableLiteral.getChild().orElseThrow(() -> new RuntimeException("Enum should have a child"));
+        return tracer + variableLiteral.getName() + "_" + child.getName() +
+            child.getChild().map(childChild -> "." + toVariableExpression(field, typeReference, childChild, parserArguments, serializerArguments, false, suppressPointerAccess, true)).orElse("");
+    }
+
+    private String toLastItemVariableExpression(TypeReference typeReference, boolean serialize, Tracer tracer) {
+        tracer = tracer.dive("lastItem");
+        return tracer + "utils.GetLastItemFromContext(ctx)";
+    }
+
+    private String toLengthVariableExpression(Field field, VariableLiteral variableLiteral, boolean serialize, Tracer tracer) {
+        tracer = tracer.dive("length");
+        return tracer + (serialize ? ("len(self." + camelCaseToSnakeCase(variableLiteral.getName()) + ")") : ("(" + variableLiteral.getName() + ")"));
+    }
+
+    private String toValueVariableExpression(Field field, TypeReference typeReference, VariableLiteral variableLiteral, List<Argument> parserArguments, List<Argument> serializerArguments, boolean serialize, boolean suppressPointerAccess, Tracer tracer) {
+        final Tracer tracer2 = tracer.dive("_value");
+        return variableLiteral.getChild()
+            .map(child -> tracer2.dive("withChild") + "self." + toUppercaseVariableExpression(field, typeReference, child, parserArguments, serializerArguments, serialize, suppressPointerAccess, tracer2))
+            .orElse(tracer2 + "m");
+    }
+
+    private String toLengthInBitsVariableExpression(TypeReference typeReference, boolean serialize, Tracer tracer) {
+        tracer = tracer.dive("lengthInBits");
+        return tracer + (serialize ? getCastExpressionForTypeReference(typeReference) + "(self.get" : "get") + "length_in_bits" + (serialize ? "(ctx))" : "(ctx)");
+    }
+
+    private String toLengthInBytesVariableExpression(TypeReference typeReference, boolean serialize, Tracer tracer) {
+        tracer = tracer.dive("lengthInBytes");
+        return tracer + (serialize ? getCastExpressionForTypeReference(typeReference) + "(self.get" : "Get") + "length_in_bytes" + (serialize ? "(ctx))" : "(ctx)");
     }
 
     public String getSizeInBits(ComplexTypeDefinition complexTypeDefinition, List<Argument> parserArguments) {
@@ -1191,10 +1358,10 @@ public class PythonLanguageTemplateHelper extends BaseFreemarkerLanguageTemplate
                 final SimpleTypeReference type = (SimpleTypeReference) arrayField.getType();
                 switch (arrayField.getLoopType()) {
                     case COUNT:
-                        sb.append("(").append(toSerializationExpression(null, INT_TYPE_REFERENCE, arrayField.getLoopExpression(), parserArguments)).append(" * ").append(type.getSizeInBits()).append(") + ");
+                        sb.append("(").append(toTypedSerializationExpression(field, type, arrayField.getLoopExpression(), parserArguments)).append(" * ").append(type.getSizeInBits()).append(") + ");
                         break;
                     case LENGTH:
-                        sb.append("(").append(toSerializationExpression(null, INT_TYPE_REFERENCE, arrayField.getLoopExpression(), parserArguments)).append(" * 8) + ");
+                        sb.append("(").append(toTypedSerializationExpression(field, type, arrayField.getLoopExpression(), parserArguments)).append(" * 8) + ");
                         break;
                     case TERMINATED:
                         // No terminated.
@@ -1205,14 +1372,12 @@ public class PythonLanguageTemplateHelper extends BaseFreemarkerLanguageTemplate
                 final TypeReference type = typedField.getType();
                 if (field instanceof ManualField) {
                     ManualField manualField = (ManualField) field;
-                    sb.append("(").append(toSerializationExpression(null, INT_TYPE_REFERENCE, manualField.getLengthExpression(), parserArguments)).append(") + ");
+                    sb.append("(").append(toSerializationExpression(manualField, getIntTypeReference(), manualField.getLengthExpression(), parserArguments)).append(") + ");
                 } else if (type instanceof SimpleTypeReference) {
                     SimpleTypeReference simpleTypeReference = (SimpleTypeReference) type;
-                    if (simpleTypeReference instanceof VstringTypeReference) {
-                        sb.append(toSerializationExpression(null, INT_TYPE_REFERENCE, ((VstringTypeReference) simpleTypeReference).getLengthExpression(), parserArguments)).append(" + ");
-                    } else {
-                        sizeInBits += simpleTypeReference.getSizeInBits();
-                    }
+                    sizeInBits += simpleTypeReference.getSizeInBits();
+                } else {
+                    throw new IllegalStateException("No ComplexTypeReference supported");
                 }
             }
         }
@@ -1241,38 +1406,42 @@ public class PythonLanguageTemplateHelper extends BaseFreemarkerLanguageTemplate
         return valueString;
     }
 
-    public String getFieldOptions(TypedField field, List<Argument> parserArguments) {
-        StringBuilder sb = new StringBuilder();
-        final Optional<Term> encodingOptional = field.getEncoding();
-        if (encodingOptional.isPresent()) {
-            final String encoding = toParseExpression(field, field.getType(), encodingOptional.get(), parserArguments);
-            sb.append(", WithOption.WithEncoding(").append(encoding).append(")");
-        }
-        final Optional<Term> byteOrderOptional = field.getByteOrder();
-        if (byteOrderOptional.isPresent()) {
-            final String byteOrder = toParseExpression(field, field.getType(), byteOrderOptional.get(), parserArguments);
-            sb.append(", WithOption.WithByteOrder(").append(byteOrder).append(")");
+    public String escapeEnumValue(TypeReference typeReference, String valueString) {
+        // Currently the only case in which here complex type references are used are when referencing enum constants.
+        if (typeReference != null && typeReference.isNonSimpleTypeReference()) {
+            // C doesn't like NULL values for enums, so we have to return something else (we'll treat -1 as NULL)
+            if ("null".equals(valueString) || valueString == null) {
+                return "0";
+            }
+            if (valueString.contains(".")) {
+                String typeName = valueString.substring(0, valueString.indexOf('.'));
+                String constantName = valueString.substring(valueString.indexOf('.') + 1);
+                return typeName + "_" + constantName;
+            }
+            return valueString;
+        } else {
+            return escapeValue(typeReference, valueString);
         }
-        return sb.toString();
     }
 
-    public boolean isBigIntegerSource(Term term) {
-        boolean isBigInteger = term.asLiteral()
-            .flatMap(LiteralConversions::asVariableLiteral)
-            .flatMap(VariableLiteral::getChild)
-            .map(Term.class::cast)
-            .map(this::isBigIntegerSource)
-            .orElse(false);
-        return isBigInteger || term.asLiteral()
-            .flatMap(LiteralConversions::asVariableLiteral)
-            .map(VariableLiteral::getTypeReference)
-            .flatMap(TypeReferenceConversions::asIntegerTypeReference)
-            .map(integerTypeReference -> integerTypeReference.getSizeInBits() >= 64)
-            .orElse(false);
+    public Collection<EnumValue> getUniqueEnumValues(List<EnumValue> enumValues) {
+        Map<String, EnumValue> filteredEnumValues = new TreeMap<>();
+        for (EnumValue enumValue : enumValues) {
+            if (!filteredEnumValues.containsKey(enumValue.getValue())) {
+                filteredEnumValues.put(enumValue.getValue(), enumValue);
+            }
+        }
+        return filteredEnumValues.values();
     }
 
-    public boolean needsLongMarker(Optional<SimpleTypeReference> baseTypeReference) {
-        return baseTypeReference.isPresent() && baseTypeReference.get().isIntegerTypeReference() && baseTypeReference.get().asIntegerTypeReference().orElseThrow().getSizeInBits() >= 32;
+    public List<DiscriminatedComplexTypeDefinition> getUniqueSwitchCases(List<DiscriminatedComplexTypeDefinition> allSwitchCases) {
+        Map<String, DiscriminatedComplexTypeDefinition> switchCases = new LinkedHashMap<>();
+        for (DiscriminatedComplexTypeDefinition switchCase : allSwitchCases) {
+            if (!switchCases.containsKey(switchCase.getName())) {
+                switchCases.put(switchCase.getName(), switchCase);
+            }
+        }
+        return new ArrayList<>(switchCases.values());
     }
 
     public void emitRequiredImport(String requiredImport) {
@@ -1303,6 +1472,319 @@ public class PythonLanguageTemplateHelper extends BaseFreemarkerLanguageTemplate
         return requiredImportsForDataIo;
     }
 
+    public String getVariableName(Field field) {
+        if (!(field instanceof NamedField)) {
+            return "_";
+        }
+        NamedField namedField = (NamedField) field;
+
+        String name = null;
+        for (Field curField : ((ComplexTypeDefinition) thisType).getFields()) {
+            if (curField == field) {
+                name = namedField.getName();
+            } else if (name != null) {
+                if (curField instanceof ArrayField) {
+                    ArrayField arrayField = (ArrayField) curField;
+                    if (arrayField.getLoopExpression().contains(name)) {
+                        return name;
+                    }
+                } else if (curField instanceof ChecksumField) {
+                    ChecksumField checksumField = (ChecksumField) curField;
+                    if (checksumField.getChecksumExpression().contains(name)) {
+                        return name;
+                    }
+                } else if (curField instanceof ImplicitField) {
+                    ImplicitField implicitField = (ImplicitField) curField;
+                    if (implicitField.getSerializeExpression().contains(name)) {
+                        return name;
+                    }
+                } else if (curField instanceof ManualArrayField) {
+                    ManualArrayField manualArrayField = (ManualArrayField) curField;
+                    if (manualArrayField.getLengthExpression().contains(name)) {
+                        return name;
+                    }
+                    if (manualArrayField.getLoopExpression().contains(name)) {
+                        return name;
+                    }
+                    if (manualArrayField.getParseExpression().contains(name)) {
+                        return name;
+                    }
+                    if (manualArrayField.getSerializeExpression().contains(name)) {
+                        return name;
+                    }
+                } else if (curField instanceof ManualField) {
+                    ManualField manualField = (ManualField) curField;
+                    if (manualField.getLengthExpression().contains(name)) {
+                        return name;
+                    }
+                    if (manualField.getParseExpression().contains(name)) {
+                        return name;
+                    }
+                    if (manualField.getSerializeExpression().contains(name)) {
+                        return name;
+                    }
+                } else if (curField instanceof OptionalField) {
+                    OptionalField optionalField = (OptionalField) curField;
+                    if (optionalField.getConditionExpression().isPresent() && optionalField.getConditionExpression().orElseThrow(IllegalStateException::new).contains(name)) {
+                        return name;
+                    }
+                } else if (curField instanceof SwitchField) {
+                    SwitchField switchField = (SwitchField) curField;
+                    for (Term discriminatorExpression : switchField.getDiscriminatorExpressions()) {
+                        if (discriminatorExpression.contains(name)) {
+                            return name;
+                        }
+                    }
+                    for (DiscriminatedComplexTypeDefinition curCase : switchField.getCases()) {
+                        for (Argument parserArgument : curCase.getParserArguments().orElse(Collections.emptyList())) {
+                            if (parserArgument.getName().equals(name)) {
+                                return name;
+                            }
+                        }
+                    }
+                } else if (curField instanceof VirtualField) {
+                    VirtualField virtualField = (VirtualField) curField;
+                    if (virtualField.getValueExpression().contains(name)) {
+                        return name;
+                    }
+                }
+                List<Term> params = field.asTypedField()
+                    .map(typedField -> typedField.getType().asNonSimpleTypeReference()
+                        .map(NonSimpleTypeReference::getParams)
+                        .map(terms -> terms.orElse(Collections.emptyList()))
+                        .orElse(Collections.emptyList())
+                    )
+                    .orElse(Collections.emptyList());
+                for (Term param : params) {
+                    if (param.contains(name)) {
+                        return name;
+                    }
+                }
+            }
+        }
+
+        return "_";
+    }
+
+    public boolean needsVariable(Field field, String variableName, boolean serialization) {
+        if (!serialization) {
+            if (field instanceof ArrayField) {
+                ArrayField arrayField = (ArrayField) field;
+                if (arrayField.getLoopExpression().contains(variableName)) {
+                    return true;
+                }
+            }
+        }
+        if (field instanceof VirtualField) {
+            VirtualField virtualField = (VirtualField) field;
+            if (virtualField.getValueExpression().contains(variableName)) {
+                return true;
+            }
+        }
+        if (field instanceof PaddingField) {
+            PaddingField paddingField = (PaddingField) field;
+            if (paddingField.getPaddingCondition().contains(variableName)) {
+                return true;
+            }
+            if (paddingField.getPaddingValue().contains(variableName)) {
+                return true;
+            }
+        }
+        return field.asTypedField()
+            .map(typedField -> typedField.getType().asNonSimpleTypeReference()
+                .map(nonSimpleTypeReference -> nonSimpleTypeReference.getParams()
+                    .map(params -> params.stream()
+                        .anyMatch(param -> param.contains(variableName))
+                    )
+                    .orElse(false)
+                )
+                .orElse(false)
+            )
+            .orElse(false);
+    }
+
+    /**
+     * Right now only the ARRAY_SIZE_IN_BYTES requires helpers to be generated.
+     * Also right now only the Modbus protocol requires this and here the referenced
+     * properties are all also members of the current complex type,
+     * so we'll simplify things here for now.
+     *
+     * @param functionName name of the
+     * @return something
+     */
+    public Map<String, String> requiresHelperFunctions(String functionName) {
+        Map<String, String> result = new HashMap<>();
+        boolean usesFunction = false;
+        // As the ARRAY_SIZE_IN_BYTES only applies to ArrayFields, search for these
+        for (Field curField : ((ComplexTypeDefinition) thisType).getFields()) {
+            if (curField instanceof ArrayField) {
+                ArrayField arrayField = (ArrayField) curField;
+                if (arrayField.getLoopExpression().contains(functionName)) {
+                    usesFunction = true;
+                }
+                result.put(arrayField.getName(), getLanguageTypeNameForField(arrayField));
+            } else if (curField instanceof ImplicitField) {
+                ImplicitField implicitField = (ImplicitField) curField;
+                if (implicitField.getSerializeExpression().contains(functionName)) {
+                    usesFunction = true;
+                }
+            }
+        }
+        if (!usesFunction) {
+            return Collections.emptyMap();
+        }
+        return result;
+    }
+
+    public boolean requiresCurPos() {
+        if (thisType instanceof ComplexTypeDefinition) {
+            ComplexTypeDefinition complexTypeDefinition = (ComplexTypeDefinition) this.thisType;
+            for (Field curField : complexTypeDefinition.getFields()) {
+                if (requiresVariable(curField, "curPos")) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    public boolean requiresStartPos() {
+        if (thisType instanceof ComplexTypeDefinition) {
+            ComplexTypeDefinition complexTypeDefinition = (ComplexTypeDefinition) this.thisType;
+            for (Field curField : complexTypeDefinition.getFields()) {
+                if (requiresVariable(curField, "startPos")) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    public boolean requiresVariable(Field curField, String variable) {
+        if (curField.isArrayField()) {
+            ArrayField arrayField = (ArrayField) curField;
+            if (arrayField.getLoopExpression().contains(variable)) {
+                return true;
+            }
+        } else if (curField.isOptionalField()) {
+            OptionalField optionalField = (OptionalField) curField;
+            if (optionalField.getConditionExpression().isPresent() && optionalField.getConditionExpression().orElseThrow(IllegalStateException::new).contains(variable)) {
+                return true;
+            }
+        }
+        return curField.asTypedField()
+            .map(typedField -> typedField.getType().asNonSimpleTypeReference()
+                .map(nonSimpleTypeReference -> nonSimpleTypeReference.getParams()
+                    .map(params -> params.stream()
+                        .anyMatch(param -> param.contains(variable))
+                    )
+                    .orElse(false)
+                )
+                .orElse(false)
+            )
+            .orElse(false);
+    }
+
+    public Term findTerm(Term baseTerm, String name) {
+        if (baseTerm instanceof VariableLiteral) {
+            VariableLiteral variableLiteral = (VariableLiteral) baseTerm;
+            if (variableLiteral.getName().equals(name)) {
+                return variableLiteral;
+            }
+            if (variableLiteral.getChild().isPresent()) {
+                Term found = findTerm(variableLiteral.getChild().get(), name);
+                if (found != null) {
+                    return found;
+                }
+            }
+            for (Term arg : variableLiteral.getArgs().orElse(Collections.emptyList())) {
+                Term found = findTerm(arg, name);
+                if (found != null) {
+                    return found;
+                }
+            }
+        } else if (baseTerm instanceof UnaryTerm) {
+            UnaryTerm unaryTerm = (UnaryTerm) baseTerm;
+            return findTerm(unaryTerm.getA(), name);
+        } else if (baseTerm instanceof BinaryTerm) {
+            BinaryTerm binaryTerm = (BinaryTerm) baseTerm;
+            Term found = findTerm(binaryTerm.getA(), name);
+            if (found != null) {
+                return found;
+            }
+            found = findTerm(binaryTerm.getB(), name);
+            return found;
+        } else if (baseTerm instanceof TernaryTerm) {
+            TernaryTerm ternaryTerm = (TernaryTerm) baseTerm;
+            Term found = findTerm(ternaryTerm.getA(), name);
+            if (found != null) {
+                return found;
+            }
+            found = findTerm(ternaryTerm.getB(), name);
+            if (found != null) {
+                return found;
+            }
+            found = findTerm(ternaryTerm.getC(), name);
+            return found;
+        }
+        return null;
+    }
+
+    public String getEnumExpression(String expression) {
+        String enumName = expression.substring(0, expression.indexOf('.'));
+        String enumConstant = expression.substring(expression.indexOf('.') + 1);
+        return enumName + "_" + enumConstant;
+    }
+
+    public boolean needsReferenceForParserArgument(String propertyName, TypeReference argumentType) {
+        return argumentType.asComplexTypeReference()
+            .map(complexTypeReference -> {
+                // Check if this is a local field.
+                // FIXME: shouldn't this look onto the argumentType? this is nowhere used...
+                return thisType.asComplexTypeDefinition()
+                    .map(
+                        complexTypeDefinition -> complexTypeDefinition.getPropertyFieldByName(propertyName)
+                            .map(TypedField.class::cast)
+                            .map(TypedField::getType)
+                            .filter(NonSimpleTypeReference.class::isInstance)
+                            .map(NonSimpleTypeReference.class::cast)
+                            .map(NonSimpleTypeReference::getTypeDefinition)
+                            .map(typeDefinition -> !(typeDefinition instanceof EnumTypeDefinition))
+                            .orElse(false)
+                    )
+                    .orElse(false);
+            })
+            .orElse(false);
+    }
+
+    public String capitalize(String str) {
+        Tracer dummyTracer = Tracer.start("");
+        String extractedTrace = dummyTracer.extractTraces(str);
+        String cleanedString = dummyTracer.removeTraces(str);
+        return extractedTrace + StringUtils.capitalize(cleanedString);
+    }
+
+    public String getEndiannessOptions(boolean read, boolean separatorPrefix) {
+        return getEndiannessOptions(read, separatorPrefix, Collections.emptyList());
+    }
+
+    public String getEndiannessOptions(boolean read, boolean separatorPrefix, List<Argument> parserArguments) {
+        Optional<Term> byteOrder = thisType.getAttribute("byteOrder");
+        if (byteOrder.isPresent()) {
+            emitRequiredImport("encoding/binary");
+            if(read) {
+                return (separatorPrefix ? ", " : "") + "utils.WithByteOrderForReadBufferByteBased(" +
+                    toParseExpression(null, new DefaultByteOrderTypeReference(), byteOrder.orElseThrow(), parserArguments) +
+                    ")";
+            } else {
+                return (separatorPrefix ? ", " : "") + "utils.WithByteOrderForByteBasedBuffer(" +
+                    toSerializationExpression(null, new DefaultByteOrderTypeReference(), byteOrder.orElseThrow(), parserArguments) +
+                    ")";
+            }
+        }
+        return "";
+    }
+
     /**
      * Converts a camel-case string to snake-case.
      *
@@ -1337,4 +1819,4 @@ public class PythonLanguageTemplateHelper extends BaseFreemarkerLanguageTemplate
         return snakeCase.toString();
     }
 
-}
+}
\ No newline at end of file
diff --git a/code-generation/language-python/src/main/resources/templates/python/complex-type-template.python.ftlh b/code-generation/language-python/src/main/resources/templates/python/complex-type-template.python.ftlh
index 77e4617393..e6e2584b03 100644
--- a/code-generation/language-python/src/main/resources/templates/python/complex-type-template.python.ftlh
+++ b/code-generation/language-python/src/main/resources/templates/python/complex-type-template.python.ftlh
@@ -64,6 +64,7 @@ ${import}
 <#if type.parserArguments.isPresent()><#assign parserArguments=type.allParserArguments.orElseThrow()></#if>
 
 <@emitImport import="from plc4py.api.messages.PlcMessage import PlcMessage" />
+<@emitImport import="from plc4py.spi.generation.WriteBuffer import WriteBuffer" />
 @dataclass
 class ${type.name}<#if type.isDiscriminatedParentTypeDefinition()></#if>(<#if type.isDiscriminatedParentTypeDefinition()>ABC, <@emitImport import="from abc import ABC" /></#if>PlcMessage<#if type.parentType.isPresent()>,${type.parentType.orElseThrow().name}<@emitImport import="from plc4py.protocols.${protocolName}.${outputFlavor?replace('-', '')}.${type.parentType.orElseThrow().name} import ${type.parentType.orElseThrow().name}" /></#if>):
     <#if parserArguments?has_content>
@@ -198,17 +199,16 @@ class ${type.name}<#if type.isDiscriminatedParentTypeDefinition()></#if>(<#if ty
     <#if type.isDiscriminatedParentTypeDefinition()>
     <@emitImport import="from abc import abstractmethod" />
     @abstractmethod
-    def serialize_${helper.camelCaseToSnakeCase(type.name)}Child(write_buffer: WriteBuffer) -> None:
+    def serialize_${helper.camelCaseToSnakeCase(type.name)}_child(write_buffer: WriteBuffer) -> None:
         pass
 
     </#if>
     def serialize(self, write_buffer: WriteBuffer):
 </#if>
-        position_aware: PositionAware = write_buffer
         <#if helper.hasFieldOfType("unknown")>
         raise SerializationException("Unknown field not serializable")
         <#else>
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("${type.name}")
             <#assign reservedFieldIndex=0>
             <#list type.fields as field>
@@ -220,11 +220,11 @@ class ${type.name}<#if type.isDiscriminatedParentTypeDefinition()></#if>(<#if ty
 
         # Array Field (${arrayField.name})
                         <#if arrayField.type.elementTypeReference.isByteBased()>
-        write_byte_array_field("${namedField.name}", self.${helper.camelCaseToSnakeCase(namedField.name)}, writeByteArray(write_buffer, 8))
+        write_buffer.write_byte_array(self.${helper.camelCaseToSnakeCase(namedField.name)}, 8, logical_name="${namedField.name}")
                         <#elseif arrayField.type.elementTypeReference.isSimpleTypeReference()>
-        write_simple_type_array_field("${namedField.name}", self.${helper.camelCaseToSnakeCase(namedField.name)}, ${helper.getDataWriterCall(arrayField.type.elementTypeReference, namedField.name)})
+        write_buffer.write_simple_array(self.${helper.camelCaseToSnakeCase(namedField.name)}, ${helper.getDataWriterCall(arrayField.type.elementTypeReference, namedField.name)}, logical_name="${namedField.name}")
                         <#else>
-        write_complex_type_array_field("${namedField.name}", self.${helper.camelCaseToSnakeCase(namedField.name)}, write_buffer)
+        write_buffer.write_complex_array(self.${helper.camelCaseToSnakeCase(namedField.name)}, logical_name="${namedField.name}")
                         </#if>
                         <#break>
                     <#case "checksum">
@@ -233,7 +233,7 @@ class ${type.name}<#if type.isDiscriminatedParentTypeDefinition()></#if>(<#if ty
                         <#assign namedField = field.asNamedField().orElseThrow()>
 
         # Checksum Field (checksum) (Calculated)
-        write_checksum_field("${namedField.name}", ${helper.getLanguageTypeNameForField(field)}(${helper.toParseExpression(checksumField, checksumField.type, checksumField.checksumExpression, parserArguments)}), ${helper.getDataWriterCall(typedField.type, namedField.name)})
+        write_buffer.${helper.getDataWriterCall(typedField.type, namedField.name)}(${helper.getLanguageTypeNameForField(field)}(${helper.toParseExpression(checksumField, checksumField.type, checksumField.checksumExpression, parserArguments)}), logical_name="${namedField.name}")
                         <#break>
                     <#case "const">
                         <#assign constField = field.asConstField().orElseThrow()>
@@ -241,7 +241,7 @@ class ${type.name}<#if type.isDiscriminatedParentTypeDefinition()></#if>(<#if ty
                         <#assign namedField = field.asNamedField().orElseThrow()>
 
         # Const Field (${constField.name})
-        <#if typedField.type.isEnumTypeReference()>write_const_field("${constField.name}", self.${helper.camelCaseToSnakeCase(namedField.name)}.value, ${helper.getDataWriterCall(helper.getEnumBaseTypeReference(typedField.type), namedField.name)})<#else>write_const_field("${constField.name}", self.${helper.camelCaseToSnakeCase(namedField.name)}, ${helper.getDataWriterCall(typedField.type, namedField.name)})</#if>
+        <#if typedField.type.isEnumTypeReference()>write_buffer.${helper.getDataWriterCall(helper.getEnumBaseTypeReference(typedField.type), namedField.name)}(self.${helper.camelCaseToSnakeCase(namedField.name)}.value, logical_name="${constField.name}")<#else>write_buffer.${helper.getDataWriterCall(typedField.type, namedField.name)}(self.${helper.camelCaseToSnakeCase(namedField.name)}.value, logical_name="${constField.name}")</#if>
                         <#break>
                     <#case "discriminator">
                         <#assign discriminatorField = field.asDiscriminatorField().orElseThrow()>
@@ -250,9 +250,9 @@ class ${type.name}<#if type.isDiscriminatedParentTypeDefinition()></#if>(<#if ty
 
         # Discriminator Field (${discriminatorField.name}) (Used as input to a switch field)
                         <#if typedField.type.isEnumTypeReference()>
-        write_discriminator_enum_field("${namedField.name}", "${helper.getLanguageTypeNameForField(field)}", self.${helper.camelCaseToSnakeCase(discriminatorField.name)}(), ${helper.getEnumDataWriterCall(typedField.type, namedField.name, "value")})
+        write_buffer.${helper.getEnumDataWriterCall(typedField.type, namedField.name, "value")}(self.${helper.camelCaseToSnakeCase(discriminatorField.name)}(), logical_name="${namedField.name}")
                         <#else>
-        write_discriminator_field("${namedField.name}", self.${helper.camelCaseToSnakeCase(discriminatorField.name)}(), ${helper.getDataWriterCall(typedField.type, namedField.name)})
+        write_buffer.${helper.getDataWriterCall(typedField.type, namedField.name)}(self.${helper.camelCaseToSnakeCase(discriminatorField.name)}(), logical_name="${namedField.name}")
                         </#if>
                         <#break>
                     <#case "enum">
@@ -261,7 +261,7 @@ class ${type.name}<#if type.isDiscriminatedParentTypeDefinition()></#if>(<#if ty
                         <#assign namedField = field.asNamedField().orElseThrow()>
 
         # Enum field (${namedField.name})
-        write_enum_field("${namedField.name}", "${helper.getLanguageTypeNameForField(field)}", self.${helper.camelCaseToSnakeCase(namedField.name)}, ${helper.getEnumDataWriterCall(typedField.type, namedField.name, enumField.fieldName)})
+        write_buffer.${helper.getEnumDataWriterCall(typedField.type, namedField.name, enumField.fieldName)}(self.${helper.camelCaseToSnakeCase(namedField.name)}, logical_name="${namedField.name}")
                         <#break>
                     <#case "implicit">
                         <#assign implicitField = field.asImplicitField().orElseThrow()>
@@ -270,8 +270,8 @@ class ${type.name}<#if type.isDiscriminatedParentTypeDefinition()></#if>(<#if ty
 
         # Implicit Field (${helper.camelCaseToSnakeCase(implicitField.name)}) (Used for parsing, but its value is not stored as it's implicitly given by the objects content)
                         <#-- Implicit field values might be used in expressions, in order to avoid problems, we generate a temporary variable with the given name. -->
-        ${helper.camelCaseToSnakeCase(implicitField.name)}: ${helper.getLanguageTypeNameForField(field)} = ${helper.getLanguageTypeNameForField(field)}((${helper.toSerializationExpression(implicitField, implicitField.type, implicitField.serializeExpression, parserArguments)}))
-        write_implicit_field("${namedField.name}", ${helper.camelCaseToSnakeCase(implicitField.name)}, ${helper.getDataWriterCall(typedField.type, namedField.name)})
+        ${helper.camelCaseToSnakeCase(implicitField.name)}: ${helper.getLanguageTypeNameForField(field)} = (${helper.toSerializationExpression(implicitField, implicitField.type, implicitField.serializeExpression, parserArguments)})
+        write_buffer.${helper.getDataWriterCall(typedField.type, namedField.name)}(${helper.camelCaseToSnakeCase(implicitField.name)}, logical_name="${namedField.name}")
                         <#break>
                     <#case "manualArray">
                         <#assign manualArrayField = field.asManualArrayField().orElseThrow()>
@@ -279,7 +279,7 @@ class ${type.name}<#if type.isDiscriminatedParentTypeDefinition()></#if>(<#if ty
                         <#assign namedField = field.asNamedField().orElseThrow()>
 
         # Manual Array Field (${manualArrayField.name})
-        write_manual_array_field("${namedField.name}", self.${helper.camelCaseToSnakeCase(namedField.name)}, (${helper.getLanguageTypeNameForTypeReference(manualArrayField.type.elementTypeReference)} _value) -> ${helper.toParseExpression(manualArrayField, manualArrayField.type.elementTypeReference, manualArrayField.serializeExpression, parserArguments)}, write_buffer)
+        write_buffer.${helper.getDataWriterCall(typedField.type, namedField.name)}((${helper.getLanguageTypeNameForTypeReference(manualArrayField.type.elementTypeReference)} _value) -> ${helper.toParseExpression(manualArrayField, manualArrayField.type.elementTypeReference, manualArrayField.serializeExpression, parserArguments)}, logical_name="${namedField.name}")
                         <#break>
                     <#case "manual">
                         <#assign manualField = field.asManualField().orElseThrow()>
@@ -287,7 +287,7 @@ class ${type.name}<#if type.isDiscriminatedParentTypeDefinition()></#if>(<#if ty
                         <#assign namedField = field.asNamedField().orElseThrow()>
 
         # Manual Field (${manualField.name})
-        write_manual_field("${namedField.name}", lambda : ${helper.toParseExpression(manualField, manualField.type, manualField.serializeExpression, parserArguments)}, write_buffer)
+        write_buffer.${helper.getDataWriterCall(typedField.type, namedField.name)}(lambda : ${helper.toParseExpression(manualField, manualField.type, manualField.serializeExpression, parserArguments)}, logical_name="${namedField.name}")
                         <#break>
                     <#case "optional">
                         <#assign optionalField = field.asOptionalField().orElseThrow()>
@@ -296,11 +296,11 @@ class ${type.name}<#if type.isDiscriminatedParentTypeDefinition()></#if>(<#if ty
 
         # Optional Field (${optionalField.name}) (Can be skipped, if the value is null)
                         <#if optionalField.type.isEnumTypeReference()>
-        write_optional_enum_field("${optionalField.name}", "${helper.getLanguageTypeNameForField(field)}", self.${helper.camelCaseToSnakeCase(optionalField.name)}, ${helper.getEnumDataWriterCall(optionalField.type, optionalField.name, "value")}<#if optionalField.conditionExpression.present>, ${helper.toSerializationExpression(optionalField, helper.boolTypeReference, optionalField.conditionExpression.get(), parserArguments)}</#if>)
+        write_buffer.${helper.getEnumDataWriterCall(optionalField.type, optionalField.name, "value")}(self.${helper.camelCaseToSnakeCase(optionalField.name)}, logical_name="${optionalField.name}", condition=${helper.toSerializationExpression(optionalField, helper.boolTypeReference, optionalField.conditionExpression.get(), parserArguments)})
                         <#elseif optionalField.type.isDataIoTypeReference()>
-        write_optional_field("${optionalField.name}", self.${helper.camelCaseToSnakeCase(optionalField.name)}, DataWriterDataIoDefault(write_buffer, (wb, val) -> ${optionalField.type.asComplexTypeReference().orElseThrow().name}.staticSerialize(wb, val<#if optionalField.type.asComplexTypeReference().orElseThrow().params?has_content>, <#list optionalField.type.asComplexTypeReference().orElseThrow().params.orElseThrow() as param>${helper.toParseExpression(optionalField, helper.anyTypeRefere [...]
+        write_buffer.${helper.getDataWriterCall(typedField.type, optionalField.name)}(self.${helper.camelCaseToSnakeCase(optionalField.name)}, logical_name="${optionalField.name}", condition=${helper.toSerializationExpression(optionalField, helper.boolTypeReference, optionalField.conditionExpression.get(), parserArguments)}, <#list optionalField.type.asComplexTypeReference().orElseThrow().params.orElseThrow() as param>${helper.toParseExpression(optionalField, helper.anyTypeReference, par [...]
                         <#else>
-        write_optional_field("${optionalField.name}", self.${helper.camelCaseToSnakeCase(optionalField.name)}, ${helper.getDataWriterCall(typedField.type, optionalField.name)}<#if optionalField.conditionExpression.present>, ${helper.toSerializationExpression(optionalField, helper.boolTypeReference, optionalField.conditionExpression.get(), parserArguments)}</#if>)
+        write_buffer.${helper.getDataWriterCall(typedField.type, optionalField.name)}(self.${helper.camelCaseToSnakeCase(optionalField.name)}, logical_name="${optionalField.name}"<#if optionalField.conditionExpression.present>, condition=${helper.toSerializationExpression(optionalField, helper.boolTypeReference, optionalField.conditionExpression.get(), parserArguments)}}</#if>)
                         </#if>
                         <#break>
                     <#case "padding">
@@ -308,14 +308,14 @@ class ${type.name}<#if type.isDiscriminatedParentTypeDefinition()></#if>(<#if ty
                         <#assign typedField = field.asTypedField().orElseThrow()>
 
         # Padding Field (padding)
-        write_padding_field("padding", int(${helper.toParseExpression(paddingField, helper.intTypeReference, paddingField.paddingCondition, parserArguments)}), ${helper.getLanguageTypeNameForField(field)}(${helper.toSerializationExpression(paddingField, paddingField.type, paddingField.paddingValue, parserArguments)}, ${helper.getDataWriterCall(typedField.type, "padding")})
+        write_buffer.${helper.getDataWriterCall(typedField.type, "padding")}(int(${helper.toParseExpression(paddingField, helper.intTypeReference, paddingField.paddingCondition, parserArguments)}), logical_name="padding")
                         <#break>
                     <#case "reserved">
                         <#assign reservedField = field.asReservedField().orElseThrow()>
                         <#assign typedField = field.asTypedField().orElseThrow()>
 
         # Reserved Field (reserved)
-        write_reserved_field("reserved", self.reserved_field_${reservedFieldIndex}!=null?self.reserved_field_${reservedFieldIndex}: ${helper.getReservedValue(reservedField)}, ${helper.getDataWriterCall(typedField.type, "reserved")})<#assign reservedFieldIndex=reservedFieldIndex+1>
+        write_buffer.${helper.getDataWriterCall(typedField.type, "reserved")}(self.reserved_field_${reservedFieldIndex}!=None?self.reserved_field_${reservedFieldIndex}: ${helper.getReservedValue(reservedField)}, logical_name="reserved")<#assign reservedFieldIndex=reservedFieldIndex+1>
                         <#break>
                     <#case "simple">
                         <#assign simpleField = field.asSimpleField().orElseThrow()>
@@ -324,11 +324,11 @@ class ${type.name}<#if type.isDiscriminatedParentTypeDefinition()></#if>(<#if ty
 
         # Simple Field (${namedField.name})
                         <#if typedField.type.isEnumTypeReference()>
-        write_simple_enum_field("${simpleField.name}", "${helper.getLanguageTypeNameForField(field)}", self.${helper.camelCaseToSnakeCase(simpleField.name)}, ${helper.getEnumDataWriterCall(simpleField.type, simpleField.name, "value")})
+        write_buffer.${helper.getEnumDataWriterCall(simpleField.type, simpleField.name, "value")}(self.${helper.camelCaseToSnakeCase(simpleField.name)}, logical_name="${simpleField.name}")
                         <#elseif simpleField.type.isDataIoTypeReference()>
-        write_simple_field("${simpleField.name}", self.${helper.camelCaseToSnakeCase(simpleField.name)}, DataWriterDataIoDefault(write_buffer, (wb, val) -> ${simpleField.type.asComplexTypeReference().orElseThrow().name}.staticSerialize(wb, val<#if simpleField.type.asComplexTypeReference().orElseThrow().params?has_content>, <#list simpleField.type.asComplexTypeReference().orElseThrow().params.orElseThrow() as param>${helper.toParseExpression(simpleField, helper.anyTypeReference, param, pa [...]
+        write_buffer.${helper.getEnumDataWriterCall(simpleField.type, simpleField.name, "value")}(DataWriterDataIoDefault(write_buffer, (wb, val) -> ${simpleField.type.asComplexTypeReference().orElseThrow().name}.staticSerialize(wb, val<#if simpleField.type.asComplexTypeReference().orElseThrow().params?has_content>, <#list simpleField.type.asComplexTypeReference().orElseThrow().params.orElseThrow() as param>${helper.toParseExpression(simpleField, helper.anyTypeReference, param, parserArg [...]
                         <#else>
-        write_simple_field("${simpleField.name}", self.${helper.camelCaseToSnakeCase(simpleField.name)}, ${helper.getDataWriterCall(typedField.type, simpleField.name)}${helper.getFieldOptions(typedField, parserArguments)})</#if>
+        write_buffer.${helper.getDataWriterCall(typedField.type, simpleField.name)}(self.${helper.camelCaseToSnakeCase(simpleField.name)}, logical_name="${simpleField.name}")</#if>
                         <#break>
                     <#case "switch">
                         <#assign switchField = field.asSwitchField().orElseThrow()>
@@ -343,7 +343,6 @@ class ${type.name}<#if type.isDiscriminatedParentTypeDefinition()></#if>(<#if ty
 
         # Virtual field (doesn't actually serialize anything, just makes the value available)
         ${namedField.name}: ${helper.getLanguageTypeNameForField(field)}  = self.${helper.camelCaseToSnakeCase(namedField.name)}()
-        write_buffer.write_virtual("${namedField.name}", self.${helper.camelCaseToSnakeCase(namedField.name)})
                         <#break>
                 </#switch>
             </#list>
@@ -535,7 +534,6 @@ class ${type.name}<#if type.isDiscriminatedParentTypeDefinition()></#if>(<#if ty
 <#-- The parse and serialize methods here are just proxies for forwardning the requests to static counterparts -->
     <#if !type.isDiscriminatedChildTypeDefinition()>
     def static_parse(read_buffer: ReadBuffer , args):
-        position_aware: PositionAware = read_buffer
         <#if parserArguments?has_content>
         if (args is None) or (args.length is not ${parserArguments?size}):
             raise PlcRuntimeException("Wrong number of arguments, expected ${parserArguments?size}, but got " + args.length)
@@ -564,8 +562,7 @@ class ${type.name}<#if type.isDiscriminatedParentTypeDefinition()></#if>(<#if ty
     @staticmethod
     def <#if type.isDiscriminatedChildTypeDefinition()>static_parse_builder<#else>static_parse_context</#if>(read_buffer: ReadBuffer<#if hasParserArguments>, ${parserArgumentList}</#if>):
         read_buffer.pull_context("${type.name}")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
     <#assign reservedFieldIndex=0>
     <#list type.fields as field>
diff --git a/code-generation/language-python/src/main/resources/templates/python/enum-template.python.ftlh b/code-generation/language-python/src/main/resources/templates/python/enum-template.python.ftlh
index 5b882ce5c9..e14eb49d4a 100644
--- a/code-generation/language-python/src/main/resources/templates/python/enum-template.python.ftlh
+++ b/code-generation/language-python/src/main/resources/templates/python/enum-template.python.ftlh
@@ -58,9 +58,9 @@ ${import}
 </#macro>
 <#macro emitImport import>${helper.emitRequiredImport(import)}</#macro>
 <@importSectionWithContentBelow>
-<@emitImport import="from enum import Enum" />
+<@emitImport import="from enum import IntEnum" />
 
-class ${type.name}(Enum):
+class ${type.name}(IntEnum):
     <#list type.enumValues as enumValue>
     ${enumValue.name}: <@compress single_line=true>
             <#if type.type.isPresent()>
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/DataItem.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/DataItem.py
index a0397bf828..ddbc20e5c2 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/DataItem.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/DataItem.py
@@ -40,9 +40,9 @@ class DataItem:
         read_buffer: ReadBuffer, data_type: ModbusDataType, number_of_values: c_uint16
     ):
         if EvaluationHelper.equals(
-            data_type, ModbusDataType.BOOL
+            data_type, ModbusDataType.get_bool()
         ) and EvaluationHelper.equals(
-            number_of_values, 1
+            number_of_values, c_uint16(1)
         ):  # BOOL
             # Reserved Field (Compartmentalized so the "reserved" variable can't leak)
             reserved: c_uint16 = read_buffer.readUnsignedInt("", 15)
@@ -59,7 +59,7 @@ class DataItem:
             value: c_bool = read_buffer.readBit("")
 
             return PlcBOOL(value)
-        if EvaluationHelper.equals(data_type, ModbusDataType.BOOL):  # List
+        if EvaluationHelper.equals(data_type, ModbusDataType.get_bool()):  # List
             # Array field (value)
             # Count array
             if numberOfValues > Integer.MAX_VALUE:
@@ -77,9 +77,9 @@ class DataItem:
 
             return PlcList(value)
         if EvaluationHelper.equals(
-            data_type, ModbusDataType.BYTE
+            data_type, ModbusDataType.get_byte()
         ) and EvaluationHelper.equals(
-            number_of_values, 1
+            number_of_values, c_uint16(1)
         ):  # BYTE
             # Reserved Field (Compartmentalized so the "reserved" variable can't leak)
             reserved: c_uint8 = read_buffer.readUnsignedShort("", 8)
@@ -96,42 +96,42 @@ class DataItem:
             value: c_uint8 = read_buffer.readUnsignedShort("", 8)
 
             return PlcBYTE(value)
-        if EvaluationHelper.equals(data_type, ModbusDataType.BYTE):  # List
+        if EvaluationHelper.equals(data_type, ModbusDataType.get_byte()):  # List
             # Array field (value)
             # Count array
-            if (numberOfValues) * (8) > Integer.MAX_VALUE:
+            if c_int32(numberOfValues) * c_int32(c_int32(8)) > Integer.MAX_VALUE:
                 raise ParseException(
                     "Array count of "
-                    + ((numberOfValues) * (8))
+                    + (c_int32(numberOfValues) * c_int32(c_int32(8)))
                     + " exceeds the maximum allowed count of "
                     + Integer.MAX_VALUE
                 )
 
-            item_count: int = int((numberOfValues) * (8))
+            item_count: int = int(c_int32(numberOfValues) * c_int32(c_int32(8)))
             value: List[PlcValue] = []
             for cur_item in range(item_count):
                 value.append(PlcBOOL(c_bool(read_buffer.readBit(""))))
 
             return PlcList(value)
-        if EvaluationHelper.equals(data_type, ModbusDataType.WORD):  # WORD
+        if EvaluationHelper.equals(data_type, ModbusDataType.get_word()):  # WORD
             # Simple Field (value)
             value: c_uint16 = read_buffer.readUnsignedInt("", 16)
 
             return PlcWORD(value)
-        if EvaluationHelper.equals(data_type, ModbusDataType.DWORD):  # DWORD
+        if EvaluationHelper.equals(data_type, ModbusDataType.get_dword()):  # DWORD
             # Simple Field (value)
             value: c_uint32 = read_buffer.readUnsignedLong("", 32)
 
             return PlcDWORD(value)
-        if EvaluationHelper.equals(data_type, ModbusDataType.LWORD):  # LWORD
+        if EvaluationHelper.equals(data_type, ModbusDataType.get_lword()):  # LWORD
             # Simple Field (value)
             value: c_uint64 = read_buffer.readUnsignedBigInteger("", 64)
 
             return PlcLWORD(value)
         if EvaluationHelper.equals(
-            data_type, ModbusDataType.SINT
+            data_type, ModbusDataType.get_sint()
         ) and EvaluationHelper.equals(
-            number_of_values, 1
+            number_of_values, c_uint16(1)
         ):  # SINT
             # Reserved Field (Compartmentalized so the "reserved" variable can't leak)
             reserved: c_uint8 = read_buffer.readUnsignedShort("", 8)
@@ -148,7 +148,7 @@ class DataItem:
             value: c_int8 = read_buffer.readSignedByte("", 8)
 
             return PlcSINT(value)
-        if EvaluationHelper.equals(data_type, ModbusDataType.SINT):  # List
+        if EvaluationHelper.equals(data_type, ModbusDataType.get_sint()):  # List
             # Array field (value)
             # Count array
             if numberOfValues > Integer.MAX_VALUE:
@@ -166,15 +166,15 @@ class DataItem:
 
             return PlcList(value)
         if EvaluationHelper.equals(
-            data_type, ModbusDataType.INT
+            data_type, ModbusDataType.get_int()
         ) and EvaluationHelper.equals(
-            number_of_values, 1
+            number_of_values, c_uint16(1)
         ):  # INT
             # Simple Field (value)
             value: c_int16 = read_buffer.readShort("", 16)
 
             return PlcINT(value)
-        if EvaluationHelper.equals(data_type, ModbusDataType.INT):  # List
+        if EvaluationHelper.equals(data_type, ModbusDataType.get_int()):  # List
             # Array field (value)
             # Count array
             if numberOfValues > Integer.MAX_VALUE:
@@ -192,15 +192,15 @@ class DataItem:
 
             return PlcList(value)
         if EvaluationHelper.equals(
-            data_type, ModbusDataType.DINT
+            data_type, ModbusDataType.get_dint()
         ) and EvaluationHelper.equals(
-            number_of_values, 1
+            number_of_values, c_uint16(1)
         ):  # DINT
             # Simple Field (value)
             value: c_int32 = read_buffer.readInt("", 32)
 
             return PlcDINT(value)
-        if EvaluationHelper.equals(data_type, ModbusDataType.DINT):  # List
+        if EvaluationHelper.equals(data_type, ModbusDataType.get_dint()):  # List
             # Array field (value)
             # Count array
             if numberOfValues > Integer.MAX_VALUE:
@@ -218,15 +218,15 @@ class DataItem:
 
             return PlcList(value)
         if EvaluationHelper.equals(
-            data_type, ModbusDataType.LINT
+            data_type, ModbusDataType.get_lint()
         ) and EvaluationHelper.equals(
-            number_of_values, 1
+            number_of_values, c_uint16(1)
         ):  # LINT
             # Simple Field (value)
             value: c_int64 = read_buffer.readLong("", 64)
 
             return PlcLINT(value)
-        if EvaluationHelper.equals(data_type, ModbusDataType.LINT):  # List
+        if EvaluationHelper.equals(data_type, ModbusDataType.get_lint()):  # List
             # Array field (value)
             # Count array
             if numberOfValues > Integer.MAX_VALUE:
@@ -244,9 +244,9 @@ class DataItem:
 
             return PlcList(value)
         if EvaluationHelper.equals(
-            data_type, ModbusDataType.USINT
+            data_type, ModbusDataType.get_usint()
         ) and EvaluationHelper.equals(
-            number_of_values, 1
+            number_of_values, c_uint16(1)
         ):  # USINT
             # Reserved Field (Compartmentalized so the "reserved" variable can't leak)
             reserved: c_uint8 = read_buffer.readUnsignedShort("", 8)
@@ -263,7 +263,7 @@ class DataItem:
             value: c_uint8 = read_buffer.readUnsignedShort("", 8)
 
             return PlcUSINT(value)
-        if EvaluationHelper.equals(data_type, ModbusDataType.USINT):  # List
+        if EvaluationHelper.equals(data_type, ModbusDataType.get_usint()):  # List
             # Array field (value)
             # Count array
             if numberOfValues > Integer.MAX_VALUE:
@@ -281,15 +281,15 @@ class DataItem:
 
             return PlcList(value)
         if EvaluationHelper.equals(
-            data_type, ModbusDataType.UINT
+            data_type, ModbusDataType.get_uint()
         ) and EvaluationHelper.equals(
-            number_of_values, 1
+            number_of_values, c_uint16(1)
         ):  # UINT
             # Simple Field (value)
             value: c_uint16 = read_buffer.readUnsignedInt("", 16)
 
             return PlcUINT(value)
-        if EvaluationHelper.equals(data_type, ModbusDataType.UINT):  # List
+        if EvaluationHelper.equals(data_type, ModbusDataType.get_uint()):  # List
             # Array field (value)
             # Count array
             if numberOfValues > Integer.MAX_VALUE:
@@ -307,15 +307,15 @@ class DataItem:
 
             return PlcList(value)
         if EvaluationHelper.equals(
-            data_type, ModbusDataType.UDINT
+            data_type, ModbusDataType.get_udint()
         ) and EvaluationHelper.equals(
-            number_of_values, 1
+            number_of_values, c_uint16(1)
         ):  # UDINT
             # Simple Field (value)
             value: c_uint32 = read_buffer.readUnsignedLong("", 32)
 
             return PlcUDINT(value)
-        if EvaluationHelper.equals(data_type, ModbusDataType.UDINT):  # List
+        if EvaluationHelper.equals(data_type, ModbusDataType.get_udint()):  # List
             # Array field (value)
             # Count array
             if numberOfValues > Integer.MAX_VALUE:
@@ -333,15 +333,15 @@ class DataItem:
 
             return PlcList(value)
         if EvaluationHelper.equals(
-            data_type, ModbusDataType.ULINT
+            data_type, ModbusDataType.get_ulint()
         ) and EvaluationHelper.equals(
-            number_of_values, 1
+            number_of_values, c_uint16(1)
         ):  # ULINT
             # Simple Field (value)
             value: c_uint64 = read_buffer.readUnsignedBigInteger("", 64)
 
             return PlcULINT(value)
-        if EvaluationHelper.equals(data_type, ModbusDataType.ULINT):  # List
+        if EvaluationHelper.equals(data_type, ModbusDataType.get_ulint()):  # List
             # Array field (value)
             # Count array
             if numberOfValues > Integer.MAX_VALUE:
@@ -361,15 +361,15 @@ class DataItem:
 
             return PlcList(value)
         if EvaluationHelper.equals(
-            data_type, ModbusDataType.REAL
+            data_type, ModbusDataType.get_real()
         ) and EvaluationHelper.equals(
-            number_of_values, 1
+            number_of_values, c_uint16(1)
         ):  # REAL
             # Simple Field (value)
             value: c_float = read_buffer.readFloat("", 32)
 
             return PlcREAL(value)
-        if EvaluationHelper.equals(data_type, ModbusDataType.REAL):  # List
+        if EvaluationHelper.equals(data_type, ModbusDataType.get_real()):  # List
             # Array field (value)
             # Count array
             if numberOfValues > Integer.MAX_VALUE:
@@ -387,15 +387,15 @@ class DataItem:
 
             return PlcList(value)
         if EvaluationHelper.equals(
-            data_type, ModbusDataType.LREAL
+            data_type, ModbusDataType.get_lreal()
         ) and EvaluationHelper.equals(
-            number_of_values, 1
+            number_of_values, c_uint16(1)
         ):  # LREAL
             # Simple Field (value)
             value: c_double = read_buffer.readDouble("", 64)
 
             return PlcLREAL(value)
-        if EvaluationHelper.equals(data_type, ModbusDataType.LREAL):  # List
+        if EvaluationHelper.equals(data_type, ModbusDataType.get_lreal()):  # List
             # Array field (value)
             # Count array
             if numberOfValues > Integer.MAX_VALUE:
@@ -413,15 +413,15 @@ class DataItem:
 
             return PlcList(value)
         if EvaluationHelper.equals(
-            data_type, ModbusDataType.CHAR
+            data_type, ModbusDataType.get_char()
         ) and EvaluationHelper.equals(
-            number_of_values, 1
+            number_of_values, c_uint16(1)
         ):  # CHAR
             # Simple Field (value)
             value: str = read_buffer.readString("", 8, "UTF-8")
 
             return PlcCHAR(value)
-        if EvaluationHelper.equals(data_type, ModbusDataType.CHAR):  # List
+        if EvaluationHelper.equals(data_type, ModbusDataType.get_char()):  # List
             # Array field (value)
             # Count array
             if numberOfValues > Integer.MAX_VALUE:
@@ -439,15 +439,15 @@ class DataItem:
 
             return PlcList(value)
         if EvaluationHelper.equals(
-            data_type, ModbusDataType.WCHAR
+            data_type, ModbusDataType.get_wchar()
         ) and EvaluationHelper.equals(
-            number_of_values, 1
+            number_of_values, c_uint16(1)
         ):  # WCHAR
             # Simple Field (value)
             value: str = read_buffer.readString("", 16, "UTF-16")
 
             return PlcWCHAR(value)
-        if EvaluationHelper.equals(data_type, ModbusDataType.WCHAR):  # List
+        if EvaluationHelper.equals(data_type, ModbusDataType.get_wchar()):  # List
             # Array field (value)
             # Count array
             if numberOfValues > Integer.MAX_VALUE:
@@ -486,234 +486,234 @@ class DataItem:
         byteOrder: ByteOrder,
     ) -> None:
         if EvaluationHelper.equals(
-            dataType, ModbusDataType.BOOL
+            dataType, ModbusDataType.get_bool()
         ) and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # BOOL
             # Reserved Field
-            writeBuffer.writeUnsignedInt("", 15, c_uint16(0x0000).intValue())
+            writeBuffer.WriteUint16("cuint160x0000", 15, c_uint16(0x0000))
             # Simple Field (value)
             value: c_bool = _value.getC_bool()
-            writeBuffer.writeBit("", bool((value)))
-        if EvaluationHelper.equals(dataType, ModbusDataType.BOOL):  # List
+            writeBuffer.WriteBit("value", (value))
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_bool()):  # List
             values: PlcList = _value
 
             for val in values.getList():
                 value: c_bool = val.getC_bool()
-                writeBuffer.writeBit("", bool((value)))
+                writeBuffer.WriteBit("value", (value))
 
         if EvaluationHelper.equals(
-            dataType, ModbusDataType.BYTE
+            dataType, ModbusDataType.get_byte()
         ) and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # BYTE
             # Reserved Field
-            writeBuffer.writeUnsignedShort("", 8, c_uint8(0x00).shortValue())
+            writeBuffer.WriteUint8("cuint80x00", 8, c_uint8(0x00))
             # Simple Field (value)
             value: c_uint8 = _value.getC_uint8()
-            writeBuffer.writeUnsignedShort("", 8, (value).shortValue())
-        if EvaluationHelper.equals(dataType, ModbusDataType.BYTE):  # List
+            writeBuffer.WriteUint8("value", 8, (value))
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_byte()):  # List
             values: PlcList = _value
 
             for val in values.getList():
                 value: c_bool = val.getC_bool()
-                writeBuffer.writeBit("", bool((value)))
+                writeBuffer.WriteBit("value", (value))
 
-        if EvaluationHelper.equals(dataType, ModbusDataType.WORD):  # WORD
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_word()):  # WORD
             # Simple Field (value)
             value: c_uint16 = _value.getC_uint16()
-            writeBuffer.writeUnsignedInt("", 16, (value).intValue())
-        if EvaluationHelper.equals(dataType, ModbusDataType.DWORD):  # DWORD
+            writeBuffer.WriteUint16("value", 16, (value))
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_dword()):  # DWORD
             # Simple Field (value)
             value: c_uint32 = _value.getC_uint32()
-            writeBuffer.writeUnsignedLong("", 32, (value).longValue())
-        if EvaluationHelper.equals(dataType, ModbusDataType.LWORD):  # LWORD
+            writeBuffer.WriteUint32("value", 32, (value))
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_lword()):  # LWORD
             # Simple Field (value)
             value: c_uint64 = _value.getC_uint64()
-            writeBuffer.writeUnsignedBigInteger("", 64, (value))
+            writeBuffer.WriteUint64("value", 64, (value))
         if EvaluationHelper.equals(
-            dataType, ModbusDataType.SINT
+            dataType, ModbusDataType.get_sint()
         ) and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # SINT
             # Reserved Field
-            writeBuffer.writeUnsignedShort("", 8, c_uint8(0x00).shortValue())
+            writeBuffer.WriteUint8("cuint80x00", 8, c_uint8(0x00))
             # Simple Field (value)
             value: c_int8 = _value.getC_int8()
-            writeBuffer.writeSignedByte("", 8, (value).byteValue())
-        if EvaluationHelper.equals(dataType, ModbusDataType.SINT):  # List
+            writeBuffer.WriteInt8("value", 8, (value))
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_sint()):  # List
             values: PlcList = _value
 
             for val in values.getList():
                 value: c_int8 = val.getC_int8()
-                writeBuffer.writeSignedByte("", 8, (value).byteValue())
+                writeBuffer.WriteInt8("value", 8, (value))
 
         if EvaluationHelper.equals(
-            dataType, ModbusDataType.INT
+            dataType, ModbusDataType.get_int()
         ) and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # INT
             # Simple Field (value)
             value: c_int16 = _value.getC_int16()
-            writeBuffer.writeShort("", 16, (value).shortValue())
-        if EvaluationHelper.equals(dataType, ModbusDataType.INT):  # List
+            writeBuffer.WriteInt16("value", 16, (value))
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_int()):  # List
             values: PlcList = _value
 
             for val in values.getList():
                 value: c_int16 = val.getC_int16()
-                writeBuffer.writeShort("", 16, (value).shortValue())
+                writeBuffer.WriteInt16("value", 16, (value))
 
         if EvaluationHelper.equals(
-            dataType, ModbusDataType.DINT
+            dataType, ModbusDataType.get_dint()
         ) and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # DINT
             # Simple Field (value)
             value: c_int32 = _value.getC_int32()
-            writeBuffer.writeInt("", 32, (value).intValue())
-        if EvaluationHelper.equals(dataType, ModbusDataType.DINT):  # List
+            writeBuffer.WriteInt32("value", 32, (value))
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_dint()):  # List
             values: PlcList = _value
 
             for val in values.getList():
                 value: c_int32 = val.getC_int32()
-                writeBuffer.writeInt("", 32, (value).intValue())
+                writeBuffer.WriteInt32("value", 32, (value))
 
         if EvaluationHelper.equals(
-            dataType, ModbusDataType.LINT
+            dataType, ModbusDataType.get_lint()
         ) and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # LINT
             # Simple Field (value)
             value: c_int64 = _value.getC_int64()
-            writeBuffer.writeLong("", 64, (value).longValue())
-        if EvaluationHelper.equals(dataType, ModbusDataType.LINT):  # List
+            writeBuffer.WriteInt64("value", 64, (value))
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_lint()):  # List
             values: PlcList = _value
 
             for val in values.getList():
                 value: c_int64 = val.getC_int64()
-                writeBuffer.writeLong("", 64, (value).longValue())
+                writeBuffer.WriteInt64("value", 64, (value))
 
         if EvaluationHelper.equals(
-            dataType, ModbusDataType.USINT
+            dataType, ModbusDataType.get_usint()
         ) and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # USINT
             # Reserved Field
-            writeBuffer.writeUnsignedShort("", 8, c_uint8(0x00).shortValue())
+            writeBuffer.WriteUint8("cuint80x00", 8, c_uint8(0x00))
             # Simple Field (value)
             value: c_uint8 = _value.getC_uint8()
-            writeBuffer.writeUnsignedShort("", 8, (value).shortValue())
-        if EvaluationHelper.equals(dataType, ModbusDataType.USINT):  # List
+            writeBuffer.WriteUint8("value", 8, (value))
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_usint()):  # List
             values: PlcList = _value
 
             for val in values.getList():
                 value: c_uint8 = val.getC_uint8()
-                writeBuffer.writeUnsignedShort("", 8, (value).shortValue())
+                writeBuffer.WriteUint8("value", 8, (value))
 
         if EvaluationHelper.equals(
-            dataType, ModbusDataType.UINT
+            dataType, ModbusDataType.get_uint()
         ) and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # UINT
             # Simple Field (value)
             value: c_uint16 = _value.getC_uint16()
-            writeBuffer.writeUnsignedInt("", 16, (value).intValue())
-        if EvaluationHelper.equals(dataType, ModbusDataType.UINT):  # List
+            writeBuffer.WriteUint16("value", 16, (value))
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_uint()):  # List
             values: PlcList = _value
 
             for val in values.getList():
                 value: c_uint16 = val.getC_uint16()
-                writeBuffer.writeUnsignedInt("", 16, (value).intValue())
+                writeBuffer.WriteUint16("value", 16, (value))
 
         if EvaluationHelper.equals(
-            dataType, ModbusDataType.UDINT
+            dataType, ModbusDataType.get_udint()
         ) and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # UDINT
             # Simple Field (value)
             value: c_uint32 = _value.getC_uint32()
-            writeBuffer.writeUnsignedLong("", 32, (value).longValue())
-        if EvaluationHelper.equals(dataType, ModbusDataType.UDINT):  # List
+            writeBuffer.WriteUint32("value", 32, (value))
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_udint()):  # List
             values: PlcList = _value
 
             for val in values.getList():
                 value: c_uint32 = val.getC_uint32()
-                writeBuffer.writeUnsignedLong("", 32, (value).longValue())
+                writeBuffer.WriteUint32("value", 32, (value))
 
         if EvaluationHelper.equals(
-            dataType, ModbusDataType.ULINT
+            dataType, ModbusDataType.get_ulint()
         ) and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # ULINT
             # Simple Field (value)
             value: c_uint64 = _value.getC_uint64()
-            writeBuffer.writeUnsignedBigInteger("", 64, (value))
-        if EvaluationHelper.equals(dataType, ModbusDataType.ULINT):  # List
+            writeBuffer.WriteUint64("value", 64, (value))
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_ulint()):  # List
             values: PlcList = _value
 
             for val in values.getList():
                 value: c_uint64 = val.getC_uint64()
-                writeBuffer.writeUnsignedBigInteger("", 64, (value))
+                writeBuffer.WriteUint64("value", 64, (value))
 
         if EvaluationHelper.equals(
-            dataType, ModbusDataType.REAL
+            dataType, ModbusDataType.get_real()
         ) and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # REAL
             # Simple Field (value)
             value: c_float = _value.getC_float()
-            writeBuffer.writeFloat("", 32, (value))
-        if EvaluationHelper.equals(dataType, ModbusDataType.REAL):  # List
+            writeBuffer.WriteFloat32("value", 32, (value))
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_real()):  # List
             values: PlcList = _value
 
             for val in values.getList():
                 value: c_float = val.getC_float()
-                writeBuffer.writeFloat("", 32, (value))
+                writeBuffer.WriteFloat32("value", 32, (value))
 
         if EvaluationHelper.equals(
-            dataType, ModbusDataType.LREAL
+            dataType, ModbusDataType.get_lreal()
         ) and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # LREAL
             # Simple Field (value)
             value: c_double = _value.getC_double()
-            writeBuffer.writeDouble("", 64, (value))
-        if EvaluationHelper.equals(dataType, ModbusDataType.LREAL):  # List
+            writeBuffer.WriteFloat64("value", 64, (value))
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_lreal()):  # List
             values: PlcList = _value
 
             for val in values.getList():
                 value: c_double = val.getC_double()
-                writeBuffer.writeDouble("", 64, (value))
+                writeBuffer.WriteFloat64("value", 64, (value))
 
         if EvaluationHelper.equals(
-            dataType, ModbusDataType.CHAR
+            dataType, ModbusDataType.get_char()
         ) and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # CHAR
             # Simple Field (value)
             value: str = _value.getStr()
-            writeBuffer.writeString("", 8, "UTF-8", (String)(value))
-        if EvaluationHelper.equals(dataType, ModbusDataType.CHAR):  # List
+            writeBuffer.WriteString("value", uint32(8), "UTF-8", (value))
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_char()):  # List
             values: PlcList = _value
 
             for val in values.getList():
                 value: str = val.getStr()
-                writeBuffer.writeString("", 8, "UTF-8", (String)(value))
+                writeBuffer.WriteString("value", uint32(8), "UTF-8", (value))
 
         if EvaluationHelper.equals(
-            dataType, ModbusDataType.WCHAR
+            dataType, ModbusDataType.get_wchar()
         ) and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # WCHAR
             # Simple Field (value)
             value: str = _value.getStr()
-            writeBuffer.writeString("", 16, "UTF-16", (String)(value))
-        if EvaluationHelper.equals(dataType, ModbusDataType.WCHAR):  # List
+            writeBuffer.WriteString("value", uint32(16), "UTF-16", (value))
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_wchar()):  # List
             values: PlcList = _value
 
             for val in values.getList():
                 value: str = val.getStr()
-                writeBuffer.writeString("", 16, "UTF-16", (String)(value))
+                writeBuffer.WriteString("value", uint32(16), "UTF-16", (value))
 
     @staticmethod
     def get_length_in_bytes(
@@ -729,160 +729,160 @@ class DataItem:
     ) -> int:
         sizeInBits: int = 0
         if EvaluationHelper.equals(
-            dataType, ModbusDataType.BOOL
+            dataType, ModbusDataType.get_bool()
         ) and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # BOOL
             # Reserved Field
             sizeInBits += 15
             # Simple Field (value)
             sizeInBits += 1
-        if EvaluationHelper.equals(dataType, ModbusDataType.BOOL):  # List
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_bool()):  # List
             values: PlcList = _value
             sizeInBits += values.getList().size() * 1
         if EvaluationHelper.equals(
-            dataType, ModbusDataType.BYTE
+            dataType, ModbusDataType.get_byte()
         ) and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # BYTE
             # Reserved Field
             sizeInBits += 8
             # Simple Field (value)
             sizeInBits += 8
-        if EvaluationHelper.equals(dataType, ModbusDataType.BYTE):  # List
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_byte()):  # List
             values: PlcList = _value
             sizeInBits += values.getList().size() * 1
-        if EvaluationHelper.equals(dataType, ModbusDataType.WORD):  # WORD
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_word()):  # WORD
             # Simple Field (value)
             sizeInBits += 16
-        if EvaluationHelper.equals(dataType, ModbusDataType.DWORD):  # DWORD
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_dword()):  # DWORD
             # Simple Field (value)
             sizeInBits += 32
-        if EvaluationHelper.equals(dataType, ModbusDataType.LWORD):  # LWORD
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_lword()):  # LWORD
             # Simple Field (value)
             sizeInBits += 64
         if EvaluationHelper.equals(
-            dataType, ModbusDataType.SINT
+            dataType, ModbusDataType.get_sint()
         ) and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # SINT
             # Reserved Field
             sizeInBits += 8
             # Simple Field (value)
             sizeInBits += 8
-        if EvaluationHelper.equals(dataType, ModbusDataType.SINT):  # List
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_sint()):  # List
             values: PlcList = _value
             sizeInBits += values.getList().size() * 8
         if EvaluationHelper.equals(
-            dataType, ModbusDataType.INT
+            dataType, ModbusDataType.get_int()
         ) and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # INT
             # Simple Field (value)
             sizeInBits += 16
-        if EvaluationHelper.equals(dataType, ModbusDataType.INT):  # List
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_int()):  # List
             values: PlcList = _value
             sizeInBits += values.getList().size() * 16
         if EvaluationHelper.equals(
-            dataType, ModbusDataType.DINT
+            dataType, ModbusDataType.get_dint()
         ) and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # DINT
             # Simple Field (value)
             sizeInBits += 32
-        if EvaluationHelper.equals(dataType, ModbusDataType.DINT):  # List
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_dint()):  # List
             values: PlcList = _value
             sizeInBits += values.getList().size() * 32
         if EvaluationHelper.equals(
-            dataType, ModbusDataType.LINT
+            dataType, ModbusDataType.get_lint()
         ) and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # LINT
             # Simple Field (value)
             sizeInBits += 64
-        if EvaluationHelper.equals(dataType, ModbusDataType.LINT):  # List
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_lint()):  # List
             values: PlcList = _value
             sizeInBits += values.getList().size() * 64
         if EvaluationHelper.equals(
-            dataType, ModbusDataType.USINT
+            dataType, ModbusDataType.get_usint()
         ) and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # USINT
             # Reserved Field
             sizeInBits += 8
             # Simple Field (value)
             sizeInBits += 8
-        if EvaluationHelper.equals(dataType, ModbusDataType.USINT):  # List
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_usint()):  # List
             values: PlcList = _value
             sizeInBits += values.getList().size() * 8
         if EvaluationHelper.equals(
-            dataType, ModbusDataType.UINT
+            dataType, ModbusDataType.get_uint()
         ) and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # UINT
             # Simple Field (value)
             sizeInBits += 16
-        if EvaluationHelper.equals(dataType, ModbusDataType.UINT):  # List
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_uint()):  # List
             values: PlcList = _value
             sizeInBits += values.getList().size() * 16
         if EvaluationHelper.equals(
-            dataType, ModbusDataType.UDINT
+            dataType, ModbusDataType.get_udint()
         ) and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # UDINT
             # Simple Field (value)
             sizeInBits += 32
-        if EvaluationHelper.equals(dataType, ModbusDataType.UDINT):  # List
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_udint()):  # List
             values: PlcList = _value
             sizeInBits += values.getList().size() * 32
         if EvaluationHelper.equals(
-            dataType, ModbusDataType.ULINT
+            dataType, ModbusDataType.get_ulint()
         ) and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # ULINT
             # Simple Field (value)
             sizeInBits += 64
-        if EvaluationHelper.equals(dataType, ModbusDataType.ULINT):  # List
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_ulint()):  # List
             values: PlcList = _value
             sizeInBits += values.getList().size() * 64
         if EvaluationHelper.equals(
-            dataType, ModbusDataType.REAL
+            dataType, ModbusDataType.get_real()
         ) and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # REAL
             # Simple Field (value)
             sizeInBits += 32
-        if EvaluationHelper.equals(dataType, ModbusDataType.REAL):  # List
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_real()):  # List
             values: PlcList = _value
             sizeInBits += values.getList().size() * 32
         if EvaluationHelper.equals(
-            dataType, ModbusDataType.LREAL
+            dataType, ModbusDataType.get_lreal()
         ) and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # LREAL
             # Simple Field (value)
             sizeInBits += 64
-        if EvaluationHelper.equals(dataType, ModbusDataType.LREAL):  # List
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_lreal()):  # List
             values: PlcList = _value
             sizeInBits += values.getList().size() * 64
         if EvaluationHelper.equals(
-            dataType, ModbusDataType.CHAR
+            dataType, ModbusDataType.get_char()
         ) and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # CHAR
             # Simple Field (value)
             sizeInBits += 8
-        if EvaluationHelper.equals(dataType, ModbusDataType.CHAR):  # List
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_char()):  # List
             values: PlcList = _value
             sizeInBits += values.getList().size() * 8
         if EvaluationHelper.equals(
-            dataType, ModbusDataType.WCHAR
+            dataType, ModbusDataType.get_wchar()
         ) and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # WCHAR
             # Simple Field (value)
             sizeInBits += 16
-        if EvaluationHelper.equals(dataType, ModbusDataType.WCHAR):  # List
+        if EvaluationHelper.equals(dataType, ModbusDataType.get_wchar()):  # List
             values: PlcList = _value
             sizeInBits += values.getList().size() * 16
         return sizeInBits
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/DriverType.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/DriverType.py
index 821d24cd90..60dd42ebb6 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/DriverType.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/DriverType.py
@@ -19,10 +19,10 @@
 
 # Code generated by code-generation. DO NOT EDIT.
 from ctypes import c_uint32
-from enum import Enum
+from enum import IntEnum
 
 
-class DriverType(Enum):
+class DriverType(IntEnum):
     MODBUS_TCP: c_uint32 = 0x01
     MODBUS_RTU: c_uint32 = 0x02
     MODBUS_ASCII: c_uint32 = 0x03
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusADU.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusADU.py
index 13cbf20db8..b8afde3aef 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusADU.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusADU.py
@@ -24,6 +24,7 @@ from abc import abstractmethod
 from ctypes import c_bool
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.DriverType import DriverType
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 import math
 
 
@@ -42,12 +43,11 @@ class ModbusADU(ABC, PlcMessage):
         pass
 
     @abstractmethod
-    def serialize_modbus_aduChild(write_buffer: WriteBuffer) -> None:
+    def serialize_modbus_adu_child(write_buffer: WriteBuffer) -> None:
         pass
 
     def serialize(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusADU")
 
         # Switch field (Serialize the sub-type)
@@ -67,7 +67,6 @@ class ModbusADU(ABC, PlcMessage):
         return length_in_bits
 
     def static_parse(read_buffer: ReadBuffer, args):
-        position_aware: PositionAware = read_buffer
         if (args is None) or (args.length is not 2):
             raise PlcRuntimeException(
                 "Wrong number of arguments, expected 2, but got " + args.length
@@ -102,17 +101,16 @@ class ModbusADU(ABC, PlcMessage):
         read_buffer: ReadBuffer, driver_type: DriverType, response: c_bool
     ):
         read_buffer.pull_context("ModbusADU")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         # Switch Field (Depending on the discriminator values, passes the instantiation to a sub-type)
         builder: ModbusADUBuilder = None
-        if EvaluationHelper.equals(driverType, DriverType.MODBUS_TCP):
+        if EvaluationHelper.equals(driverType, DriverType.get_modbu_s__tcp()):
             builder = ModbusTcpADU.staticParseBuilder(read_buffer, driverType, response)
-        if EvaluationHelper.equals(driverType, DriverType.MODBUS_RTU):
+        if EvaluationHelper.equals(driverType, DriverType.get_modbu_s__rtu()):
             builder = ModbusRtuADU.staticParseBuilder(read_buffer, driverType, response)
-        if EvaluationHelper.equals(driverType, DriverType.MODBUS_ASCII):
+        if EvaluationHelper.equals(driverType, DriverType.get_modbu_s__ascii()):
             builder = ModbusAsciiADU.staticParseBuilder(
                 read_buffer, driverType, response
             )
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusAsciiADU.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusAsciiADU.py
index 46c828dd89..8a06bc3a2d 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusAsciiADU.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusAsciiADU.py
@@ -26,6 +26,7 @@ from plc4py.protocols.modbus.readwrite.DriverType import DriverType
 from plc4py.protocols.modbus.readwrite.ModbusADU import ModbusADU
 from plc4py.protocols.modbus.readwrite.ModbusADU import ModbusADUBuilder
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 import math
 
 
@@ -36,37 +37,26 @@ class ModbusAsciiADU(PlcMessage, ModbusADU):
     # Arguments.
     response: c_bool
     # Accessors for discriminator values.
-    driver_type: DriverType = DriverType.MODBUS_ASCII
+    driver_type: DriverType = DriverType.get_modbu_s__ascii()
 
     def __post_init__(self):
         super().__init__(self.response)
 
     def serialize_modbus_adu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusAsciiADU")
 
         # Simple Field (address)
-        write_simple_field(
-            "address",
-            self.address,
-            write_unsigned_short(write_buffer, 8),
-            WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN),
-        )
+        write_buffer.write_unsigned_byte(self.address, logical_name="address")
 
         # Simple Field (pdu)
-        write_simple_field(
-            "pdu",
-            self.pdu,
-            DataWriterComplexDefault(write_buffer),
-            WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN),
+        write_buffer.DataWriterComplexDefault(write_buffer)(
+            self.pdu, logical_name="pdu"
         )
 
         # Checksum Field (checksum) (Calculated)
-        write_checksum_field(
-            "crc",
-            c_uint8(modbus.readwrite.utils.StaticHelper.asciiLrcCheck(address, pdu)),
-            write_unsigned_short(write_buffer, 8),
+        write_buffer.write_unsigned_byte(
+            c_uint8(ascii_lrc_check(address, pdu)), logical_name="crc"
         )
 
         write_buffer.pop_context("ModbusAsciiADU")
@@ -94,14 +84,13 @@ class ModbusAsciiADU(PlcMessage, ModbusADU):
         read_buffer: ReadBuffer, driver_type: DriverType, response: c_bool
     ):
         read_buffer.pull_context("ModbusAsciiADU")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         address: c_uint8 = read_simple_field(
             "address",
             read_unsigned_short(read_buffer, 8),
-            WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN),
+            WithOption.WithByteOrder(get_bi_g__endian()),
         )
 
         pdu: ModbusPDU = read_simple_field(
@@ -109,14 +98,14 @@ class ModbusAsciiADU(PlcMessage, ModbusADU):
             DataReaderComplexDefault(
                 ModbusPDU.static_parse(read_buffer, c_bool(response)), read_buffer
             ),
-            WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN),
+            WithOption.WithByteOrder(get_bi_g__endian()),
         )
 
         crc: c_uint8 = read_checksum_field(
             "crc",
             read_unsigned_short(read_buffer, 8),
-            (c_uint8)(modbus.readwrite.utils.StaticHelper.asciiLrcCheck(address, pdu)),
-            WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN),
+            (c_uint8)(ascii_lrc_check(address, pdu)),
+            WithOption.WithByteOrder(get_bi_g__endian()),
         )
 
         read_buffer.close_context("ModbusAsciiADU")
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusConstants.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusConstants.py
index 5b1dffdedb..5d35fc9fa9 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusConstants.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusConstants.py
@@ -21,26 +21,24 @@ from dataclasses import dataclass
 
 from ctypes import c_uint16
 from plc4py.api.messages.PlcMessage import PlcMessage
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 import math
 
 
 @dataclass
 class ModbusConstants(PlcMessage):
-    MODBUSTCPDEFAULTPORT: c_uint16 = 502
+    MODBUSTCPDEFAULTPORT: c_uint16 = c_uint16(502)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusConstants")
 
         # Const Field (modbusTcpDefaultPort)
-        write_const_field(
-            "modbusTcpDefaultPort",
-            self.modbus_tcp_default_port,
-            write_unsigned_int(write_buffer, 16),
+        write_buffer.write_unsigned_short(
+            self.modbus_tcp_default_port.value, logical_name="modbusTcpDefaultPort"
         )
 
         write_buffer.pop_context("ModbusConstants")
@@ -58,14 +56,12 @@ class ModbusConstants(PlcMessage):
         return length_in_bits
 
     def static_parse(read_buffer: ReadBuffer, args):
-        position_aware: PositionAware = read_buffer
         return staticParse(read_buffer)
 
     @staticmethod
     def static_parse_context(read_buffer: ReadBuffer):
         read_buffer.pull_context("ModbusConstants")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         modbus_tcp_default_port: c_uint16 = read_const_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusDataType.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusDataType.py
index a0bb9a839e..f3faf92283 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusDataType.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusDataType.py
@@ -19,10 +19,10 @@
 
 # Code generated by code-generation. DO NOT EDIT.
 from ctypes import c_uint8
-from enum import Enum
+from enum import IntEnum
 
 
-class ModbusDataType(Enum):
+class ModbusDataType(IntEnum):
     BOOL: c_uint8 = (1, c_uint8(2))
     BYTE: c_uint8 = (2, c_uint8(2))
     WORD: c_uint8 = (3, c_uint8(2))
@@ -51,7 +51,7 @@ class ModbusDataType(Enum):
     STRING: c_uint8 = (26, c_uint8(1))
     WSTRING: c_uint8 = (27, c_uint8(2))
 
-    def __new__(cls, value, dataTypeSize):
+    def __new__(cls, value, data_type_size):
         obj = object.__new__(cls)
         obj._value_ = value
         obj.dataTypeSize = dataTypeSize
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusDeviceInformationConformityLevel.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusDeviceInformationConformityLevel.py
index 714b8f4c1a..35f8cf4800 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusDeviceInformationConformityLevel.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusDeviceInformationConformityLevel.py
@@ -19,10 +19,10 @@
 
 # Code generated by code-generation. DO NOT EDIT.
 from ctypes import c_uint8
-from enum import Enum
+from enum import IntEnum
 
 
-class ModbusDeviceInformationConformityLevel(Enum):
+class ModbusDeviceInformationConformityLevel(IntEnum):
     BASIC_STREAM_ONLY: c_uint8 = 0x01
     REGULAR_STREAM_ONLY: c_uint8 = 0x02
     EXTENDED_STREAM_ONLY: c_uint8 = 0x03
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusDeviceInformationLevel.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusDeviceInformationLevel.py
index 524da5a86d..3e689b521e 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusDeviceInformationLevel.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusDeviceInformationLevel.py
@@ -19,10 +19,10 @@
 
 # Code generated by code-generation. DO NOT EDIT.
 from ctypes import c_uint8
-from enum import Enum
+from enum import IntEnum
 
 
-class ModbusDeviceInformationLevel(Enum):
+class ModbusDeviceInformationLevel(IntEnum):
     BASIC: c_uint8 = 0x01
     REGULAR: c_uint8 = 0x02
     EXTENDED: c_uint8 = 0x03
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusDeviceInformationMoreFollows.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusDeviceInformationMoreFollows.py
index 9144a09fcf..fafecd5f54 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusDeviceInformationMoreFollows.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusDeviceInformationMoreFollows.py
@@ -19,9 +19,9 @@
 
 # Code generated by code-generation. DO NOT EDIT.
 from ctypes import c_uint8
-from enum import Enum
+from enum import IntEnum
 
 
-class ModbusDeviceInformationMoreFollows(Enum):
+class ModbusDeviceInformationMoreFollows(IntEnum):
     NO_MORE_OBJECTS_AVAILABLE: c_uint8 = 0x00
     MORE_OBJECTS_AVAILABLE: c_uint8 = 0xFF
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusDeviceInformationObject.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusDeviceInformationObject.py
index 6d919290c2..259271e9c5 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusDeviceInformationObject.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusDeviceInformationObject.py
@@ -22,6 +22,7 @@ from dataclasses import dataclass
 from ctypes import c_byte
 from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 from typing import List
 import math
 
@@ -35,23 +36,18 @@ class ModbusDeviceInformationObject(PlcMessage):
         super().__init__()
 
     def serialize(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusDeviceInformationObject")
 
         # Simple Field (objectId)
-        write_simple_field(
-            "objectId", self.object_id, write_unsigned_short(write_buffer, 8)
-        )
+        write_buffer.write_unsigned_byte(self.object_id, logical_name="objectId")
 
         # Implicit Field (object_length) (Used for parsing, but its value is not stored as it's implicitly given by the objects content)
-        object_length: c_uint8 = c_uint8((COUNT(self.data())))
-        write_implicit_field(
-            "objectLength", object_length, write_unsigned_short(write_buffer, 8)
-        )
+        object_length: c_uint8 = c_uint8(len(self.data))
+        write_buffer.write_unsigned_byte(object_length, logical_name="objectLength")
 
         # Array Field (data)
-        write_byte_array_field("data", self.data, writeByteArray(write_buffer, 8))
+        write_buffer.write_byte_array(self.data, 8, logical_name="data")
 
         write_buffer.pop_context("ModbusDeviceInformationObject")
 
@@ -75,14 +71,12 @@ class ModbusDeviceInformationObject(PlcMessage):
         return length_in_bits
 
     def static_parse(read_buffer: ReadBuffer, args):
-        position_aware: PositionAware = read_buffer
         return staticParse(read_buffer)
 
     @staticmethod
     def static_parse_context(read_buffer: ReadBuffer):
         read_buffer.pull_context("ModbusDeviceInformationObject")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         object_id: c_uint8 = read_simple_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusErrorCode.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusErrorCode.py
index 7d14fdc976..572896afe1 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusErrorCode.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusErrorCode.py
@@ -19,10 +19,10 @@
 
 # Code generated by code-generation. DO NOT EDIT.
 from ctypes import c_uint8
-from enum import Enum
+from enum import IntEnum
 
 
-class ModbusErrorCode(Enum):
+class ModbusErrorCode(IntEnum):
     ILLEGAL_FUNCTION: c_uint8 = 1
     ILLEGAL_DATA_ADDRESS: c_uint8 = 2
     ILLEGAL_DATA_VALUE: c_uint8 = 3
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDU.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDU.py
index df8afc62c1..3f4e929ee4 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDU.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDU.py
@@ -24,6 +24,7 @@ from abc import abstractmethod
 from ctypes import c_bool
 from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 import math
 
 
@@ -49,22 +50,19 @@ class ModbusPDU(ABC, PlcMessage):
         pass
 
     @abstractmethod
-    def serialize_modbus_pduChild(write_buffer: WriteBuffer) -> None:
+    def serialize_modbus_pdu_child(write_buffer: WriteBuffer) -> None:
         pass
 
     def serialize(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDU")
 
         # Discriminator Field (errorFlag) (Used as input to a switch field)
-        write_discriminator_field(
-            "errorFlag", self.error_flag(), write_boolean(write_buffer)
-        )
+        write_buffer.write_boolean(self.error_flag(), logical_name="errorFlag")
 
         # Discriminator Field (functionFlag) (Used as input to a switch field)
-        write_discriminator_field(
-            "functionFlag", self.function_flag(), write_unsigned_short(write_buffer, 7)
+        write_buffer.write_unsigned_byte(
+            self.function_flag(), logical_name="functionFlag"
         )
 
         # Switch field (Serialize the sub-type)
@@ -90,7 +88,6 @@ class ModbusPDU(ABC, PlcMessage):
         return length_in_bits
 
     def static_parse(read_buffer: ReadBuffer, args):
-        position_aware: PositionAware = read_buffer
         if (args is None) or (args.length is not 1):
             raise PlcRuntimeException(
                 "Wrong number of arguments, expected 1, but got " + args.length
@@ -112,8 +109,7 @@ class ModbusPDU(ABC, PlcMessage):
     @staticmethod
     def static_parse_context(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDU")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         error_flag: c_bool = read_discriminator_field(
@@ -126,140 +122,140 @@ class ModbusPDU(ABC, PlcMessage):
 
         # Switch Field (Depending on the discriminator values, passes the instantiation to a sub-type)
         builder: ModbusPDUBuilder = None
-        if EvaluationHelper.equals(errorFlag, c_bool(True)):
+        if EvaluationHelper.equals(errorFlag, c_bool(c_bool(true))):
             builder = ModbusPDUError.staticParseBuilder(read_buffer, response)
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x02))
-            and EvaluationHelper.equals(response, c_bool(False))
+            and EvaluationHelper.equals(response, c_bool(c_bool(false)))
         ):
             builder = ModbusPDUReadDiscreteInputsRequest.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x02))
-            and EvaluationHelper.equals(response, c_bool(True))
+            and EvaluationHelper.equals(response, c_bool(c_bool(true)))
         ):
             builder = ModbusPDUReadDiscreteInputsResponse.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x01))
-            and EvaluationHelper.equals(response, c_bool(False))
+            and EvaluationHelper.equals(response, c_bool(c_bool(false)))
         ):
             builder = ModbusPDUReadCoilsRequest.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x01))
-            and EvaluationHelper.equals(response, c_bool(True))
+            and EvaluationHelper.equals(response, c_bool(c_bool(true)))
         ):
             builder = ModbusPDUReadCoilsResponse.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x05))
-            and EvaluationHelper.equals(response, c_bool(False))
+            and EvaluationHelper.equals(response, c_bool(c_bool(false)))
         ):
             builder = ModbusPDUWriteSingleCoilRequest.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x05))
-            and EvaluationHelper.equals(response, c_bool(True))
+            and EvaluationHelper.equals(response, c_bool(c_bool(true)))
         ):
             builder = ModbusPDUWriteSingleCoilResponse.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x0F))
-            and EvaluationHelper.equals(response, c_bool(False))
+            and EvaluationHelper.equals(response, c_bool(c_bool(false)))
         ):
             builder = ModbusPDUWriteMultipleCoilsRequest.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x0F))
-            and EvaluationHelper.equals(response, c_bool(True))
+            and EvaluationHelper.equals(response, c_bool(c_bool(true)))
         ):
             builder = ModbusPDUWriteMultipleCoilsResponse.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x04))
-            and EvaluationHelper.equals(response, c_bool(False))
+            and EvaluationHelper.equals(response, c_bool(c_bool(false)))
         ):
             builder = ModbusPDUReadInputRegistersRequest.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x04))
-            and EvaluationHelper.equals(response, c_bool(True))
+            and EvaluationHelper.equals(response, c_bool(c_bool(true)))
         ):
             builder = ModbusPDUReadInputRegistersResponse.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x03))
-            and EvaluationHelper.equals(response, c_bool(False))
+            and EvaluationHelper.equals(response, c_bool(c_bool(false)))
         ):
             builder = ModbusPDUReadHoldingRegistersRequest.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x03))
-            and EvaluationHelper.equals(response, c_bool(True))
+            and EvaluationHelper.equals(response, c_bool(c_bool(true)))
         ):
             builder = ModbusPDUReadHoldingRegistersResponse.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x06))
-            and EvaluationHelper.equals(response, c_bool(False))
+            and EvaluationHelper.equals(response, c_bool(c_bool(false)))
         ):
             builder = ModbusPDUWriteSingleRegisterRequest.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x06))
-            and EvaluationHelper.equals(response, c_bool(True))
+            and EvaluationHelper.equals(response, c_bool(c_bool(true)))
         ):
             builder = ModbusPDUWriteSingleRegisterResponse.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x10))
-            and EvaluationHelper.equals(response, c_bool(False))
+            and EvaluationHelper.equals(response, c_bool(c_bool(false)))
         ):
             builder = ModbusPDUWriteMultipleHoldingRegistersRequest.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x10))
-            and EvaluationHelper.equals(response, c_bool(True))
+            and EvaluationHelper.equals(response, c_bool(c_bool(true)))
         ):
             builder = ModbusPDUWriteMultipleHoldingRegistersResponse.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x17))
-            and EvaluationHelper.equals(response, c_bool(False))
+            and EvaluationHelper.equals(response, c_bool(c_bool(false)))
         ):
             builder = (
                 ModbusPDUReadWriteMultipleHoldingRegistersRequest.staticParseBuilder(
@@ -267,9 +263,9 @@ class ModbusPDU(ABC, PlcMessage):
                 )
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x17))
-            and EvaluationHelper.equals(response, c_bool(True))
+            and EvaluationHelper.equals(response, c_bool(c_bool(true)))
         ):
             builder = (
                 ModbusPDUReadWriteMultipleHoldingRegistersResponse.staticParseBuilder(
@@ -277,161 +273,161 @@ class ModbusPDU(ABC, PlcMessage):
                 )
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x16))
-            and EvaluationHelper.equals(response, c_bool(False))
+            and EvaluationHelper.equals(response, c_bool(c_bool(false)))
         ):
             builder = ModbusPDUMaskWriteHoldingRegisterRequest.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x16))
-            and EvaluationHelper.equals(response, c_bool(True))
+            and EvaluationHelper.equals(response, c_bool(c_bool(true)))
         ):
             builder = ModbusPDUMaskWriteHoldingRegisterResponse.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x18))
-            and EvaluationHelper.equals(response, c_bool(False))
+            and EvaluationHelper.equals(response, c_bool(c_bool(false)))
         ):
             builder = ModbusPDUReadFifoQueueRequest.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x18))
-            and EvaluationHelper.equals(response, c_bool(True))
+            and EvaluationHelper.equals(response, c_bool(c_bool(true)))
         ):
             builder = ModbusPDUReadFifoQueueResponse.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x14))
-            and EvaluationHelper.equals(response, c_bool(False))
+            and EvaluationHelper.equals(response, c_bool(c_bool(false)))
         ):
             builder = ModbusPDUReadFileRecordRequest.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x14))
-            and EvaluationHelper.equals(response, c_bool(True))
+            and EvaluationHelper.equals(response, c_bool(c_bool(true)))
         ):
             builder = ModbusPDUReadFileRecordResponse.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x15))
-            and EvaluationHelper.equals(response, c_bool(False))
+            and EvaluationHelper.equals(response, c_bool(c_bool(false)))
         ):
             builder = ModbusPDUWriteFileRecordRequest.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x15))
-            and EvaluationHelper.equals(response, c_bool(True))
+            and EvaluationHelper.equals(response, c_bool(c_bool(true)))
         ):
             builder = ModbusPDUWriteFileRecordResponse.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x07))
-            and EvaluationHelper.equals(response, c_bool(False))
+            and EvaluationHelper.equals(response, c_bool(c_bool(false)))
         ):
             builder = ModbusPDUReadExceptionStatusRequest.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x07))
-            and EvaluationHelper.equals(response, c_bool(True))
+            and EvaluationHelper.equals(response, c_bool(c_bool(true)))
         ):
             builder = ModbusPDUReadExceptionStatusResponse.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x08))
-            and EvaluationHelper.equals(response, c_bool(False))
+            and EvaluationHelper.equals(response, c_bool(c_bool(false)))
         ):
             builder = ModbusPDUDiagnosticRequest.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x08))
-            and EvaluationHelper.equals(response, c_bool(True))
+            and EvaluationHelper.equals(response, c_bool(c_bool(true)))
         ):
             builder = ModbusPDUDiagnosticResponse.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x0B))
-            and EvaluationHelper.equals(response, c_bool(False))
+            and EvaluationHelper.equals(response, c_bool(c_bool(false)))
         ):
             builder = ModbusPDUGetComEventCounterRequest.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x0B))
-            and EvaluationHelper.equals(response, c_bool(True))
+            and EvaluationHelper.equals(response, c_bool(c_bool(true)))
         ):
             builder = ModbusPDUGetComEventCounterResponse.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x0C))
-            and EvaluationHelper.equals(response, c_bool(False))
+            and EvaluationHelper.equals(response, c_bool(c_bool(false)))
         ):
             builder = ModbusPDUGetComEventLogRequest.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x0C))
-            and EvaluationHelper.equals(response, c_bool(True))
+            and EvaluationHelper.equals(response, c_bool(c_bool(true)))
         ):
             builder = ModbusPDUGetComEventLogResponse.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x11))
-            and EvaluationHelper.equals(response, c_bool(False))
+            and EvaluationHelper.equals(response, c_bool(c_bool(false)))
         ):
             builder = ModbusPDUReportServerIdRequest.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x11))
-            and EvaluationHelper.equals(response, c_bool(True))
+            and EvaluationHelper.equals(response, c_bool(c_bool(true)))
         ):
             builder = ModbusPDUReportServerIdResponse.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x2B))
-            and EvaluationHelper.equals(response, c_bool(False))
+            and EvaluationHelper.equals(response, c_bool(c_bool(false)))
         ):
             builder = ModbusPDUReadDeviceIdentificationRequest.staticParseBuilder(
                 read_buffer, response
             )
         if (
-            EvaluationHelper.equals(errorFlag, c_bool(False))
+            EvaluationHelper.equals(errorFlag, c_bool(c_bool(false)))
             and EvaluationHelper.equals(functionFlag, c_uint8(0x2B))
-            and EvaluationHelper.equals(response, c_bool(True))
+            and EvaluationHelper.equals(response, c_bool(c_bool(true)))
         ):
             builder = ModbusPDUReadDeviceIdentificationResponse.staticParseBuilder(
                 read_buffer, response
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUDiagnosticRequest.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUDiagnosticRequest.py
index 6780d3938d..c64daebf0b 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUDiagnosticRequest.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUDiagnosticRequest.py
@@ -25,6 +25,7 @@ from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 import math
 
 
@@ -33,25 +34,22 @@ class ModbusPDUDiagnosticRequest(PlcMessage, ModbusPDU):
     sub_function: c_uint16
     data: c_uint16
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x08
-    response: c_bool = False
+    response: c_bool = c_bool(false)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUDiagnosticRequest")
 
         # Simple Field (subFunction)
-        write_simple_field(
-            "subFunction", self.sub_function, write_unsigned_int(write_buffer, 16)
-        )
+        write_buffer.write_unsigned_short(self.sub_function, logical_name="subFunction")
 
         # Simple Field (data)
-        write_simple_field("data", self.data, write_unsigned_int(write_buffer, 16))
+        write_buffer.write_unsigned_short(self.data, logical_name="data")
 
         write_buffer.pop_context("ModbusPDUDiagnosticRequest")
 
@@ -73,8 +71,7 @@ class ModbusPDUDiagnosticRequest(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUDiagnosticRequest")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         sub_function: c_uint16 = read_simple_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUDiagnosticResponse.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUDiagnosticResponse.py
index 5fbd869b97..ae00e09287 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUDiagnosticResponse.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUDiagnosticResponse.py
@@ -25,6 +25,7 @@ from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 import math
 
 
@@ -33,25 +34,22 @@ class ModbusPDUDiagnosticResponse(PlcMessage, ModbusPDU):
     sub_function: c_uint16
     data: c_uint16
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x08
-    response: c_bool = True
+    response: c_bool = c_bool(true)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUDiagnosticResponse")
 
         # Simple Field (subFunction)
-        write_simple_field(
-            "subFunction", self.sub_function, write_unsigned_int(write_buffer, 16)
-        )
+        write_buffer.write_unsigned_short(self.sub_function, logical_name="subFunction")
 
         # Simple Field (data)
-        write_simple_field("data", self.data, write_unsigned_int(write_buffer, 16))
+        write_buffer.write_unsigned_short(self.data, logical_name="data")
 
         write_buffer.pop_context("ModbusPDUDiagnosticResponse")
 
@@ -73,8 +71,7 @@ class ModbusPDUDiagnosticResponse(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUDiagnosticResponse")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         sub_function: c_uint16 = read_simple_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUError.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUError.py
index cd156df49d..0bc22be06f 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUError.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUError.py
@@ -25,6 +25,7 @@ from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusErrorCode import ModbusErrorCode
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 import math
 
 
@@ -32,7 +33,7 @@ import math
 class ModbusPDUError(PlcMessage, ModbusPDU):
     exception_code: ModbusErrorCode
     # Accessors for discriminator values.
-    error_flag: c_bool = True
+    error_flag: c_bool = c_bool(true)
     function_flag: c_uint8 = 0
     response: c_bool = False
 
@@ -40,21 +41,13 @@ class ModbusPDUError(PlcMessage, ModbusPDU):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUError")
 
         # Simple Field (exceptionCode)
-        write_simple_enum_field(
-            "exceptionCode",
-            "ModbusErrorCode",
-            self.exception_code,
-            DataWriterEnumDefault(
-                ModbusErrorCode.value,
-                ModbusErrorCode.name,
-                write_unsigned_short(write_buffer, 8),
-            ),
-        )
+        write_buffer.DataWriterEnumDefault(
+            ModbusErrorCode.value, ModbusErrorCode.name, write_unsigned_byte
+        )(self.exception_code, logical_name="exceptionCode")
 
         write_buffer.pop_context("ModbusPDUError")
 
@@ -73,8 +66,7 @@ class ModbusPDUError(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUError")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         exception_code: ModbusErrorCode = read_enum_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUGetComEventCounterRequest.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUGetComEventCounterRequest.py
index fec6e32e88..ebd135c89c 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUGetComEventCounterRequest.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUGetComEventCounterRequest.py
@@ -24,22 +24,22 @@ from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 import math
 
 
 @dataclass
 class ModbusPDUGetComEventCounterRequest(PlcMessage, ModbusPDU):
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x0B
-    response: c_bool = False
+    response: c_bool = c_bool(false)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUGetComEventCounterRequest")
 
         write_buffer.pop_context("ModbusPDUGetComEventCounterRequest")
@@ -56,8 +56,7 @@ class ModbusPDUGetComEventCounterRequest(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUGetComEventCounterRequest")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         read_buffer.close_context("ModbusPDUGetComEventCounterRequest")
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUGetComEventCounterResponse.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUGetComEventCounterResponse.py
index 9bc8ed844f..c9bb72146c 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUGetComEventCounterResponse.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUGetComEventCounterResponse.py
@@ -25,6 +25,7 @@ from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 import math
 
 
@@ -33,25 +34,22 @@ class ModbusPDUGetComEventCounterResponse(PlcMessage, ModbusPDU):
     status: c_uint16
     event_count: c_uint16
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x0B
-    response: c_bool = True
+    response: c_bool = c_bool(true)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUGetComEventCounterResponse")
 
         # Simple Field (status)
-        write_simple_field("status", self.status, write_unsigned_int(write_buffer, 16))
+        write_buffer.write_unsigned_short(self.status, logical_name="status")
 
         # Simple Field (eventCount)
-        write_simple_field(
-            "eventCount", self.event_count, write_unsigned_int(write_buffer, 16)
-        )
+        write_buffer.write_unsigned_short(self.event_count, logical_name="eventCount")
 
         write_buffer.pop_context("ModbusPDUGetComEventCounterResponse")
 
@@ -73,8 +71,7 @@ class ModbusPDUGetComEventCounterResponse(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUGetComEventCounterResponse")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         status: c_uint16 = read_simple_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUGetComEventLogRequest.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUGetComEventLogRequest.py
index a0f7534979..6d641496d2 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUGetComEventLogRequest.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUGetComEventLogRequest.py
@@ -24,22 +24,22 @@ from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 import math
 
 
 @dataclass
 class ModbusPDUGetComEventLogRequest(PlcMessage, ModbusPDU):
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x0C
-    response: c_bool = False
+    response: c_bool = c_bool(false)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUGetComEventLogRequest")
 
         write_buffer.pop_context("ModbusPDUGetComEventLogRequest")
@@ -56,8 +56,7 @@ class ModbusPDUGetComEventLogRequest(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUGetComEventLogRequest")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         read_buffer.close_context("ModbusPDUGetComEventLogRequest")
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUGetComEventLogResponse.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUGetComEventLogResponse.py
index 11f94ac204..cd8d6286c5 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUGetComEventLogResponse.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUGetComEventLogResponse.py
@@ -21,11 +21,13 @@ from dataclasses import dataclass
 
 from ctypes import c_bool
 from ctypes import c_byte
+from ctypes import c_int32
 from ctypes import c_uint16
 from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 from typing import List
 import math
 
@@ -37,39 +39,34 @@ class ModbusPDUGetComEventLogResponse(PlcMessage, ModbusPDU):
     message_count: c_uint16
     events: List[c_byte]
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x0C
-    response: c_bool = True
+    response: c_bool = c_bool(true)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUGetComEventLogResponse")
 
         # Implicit Field (byte_count) (Used for parsing, but its value is not stored as it's implicitly given by the objects content)
-        byte_count: c_uint8 = c_uint8(((COUNT(self.events())) + (6)))
-        write_implicit_field(
-            "byteCount", byte_count, write_unsigned_short(write_buffer, 8)
-        )
+        byte_count: c_uint8 = c_uint8(c_uint8(len(self.events))) + c_uint8(c_uint8(6))
+        write_buffer.write_unsigned_byte(byte_count, logical_name="byteCount")
 
         # Simple Field (status)
-        write_simple_field("status", self.status, write_unsigned_int(write_buffer, 16))
+        write_buffer.write_unsigned_short(self.status, logical_name="status")
 
         # Simple Field (eventCount)
-        write_simple_field(
-            "eventCount", self.event_count, write_unsigned_int(write_buffer, 16)
-        )
+        write_buffer.write_unsigned_short(self.event_count, logical_name="eventCount")
 
         # Simple Field (messageCount)
-        write_simple_field(
-            "messageCount", self.message_count, write_unsigned_int(write_buffer, 16)
+        write_buffer.write_unsigned_short(
+            self.message_count, logical_name="messageCount"
         )
 
         # Array Field (events)
-        write_byte_array_field("events", self.events, writeByteArray(write_buffer, 8))
+        write_buffer.write_byte_array(self.events, 8, logical_name="events")
 
         write_buffer.pop_context("ModbusPDUGetComEventLogResponse")
 
@@ -101,8 +98,7 @@ class ModbusPDUGetComEventLogResponse(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUGetComEventLogResponse")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         byte_count: c_uint8 = read_implicit_field(
@@ -122,7 +118,7 @@ class ModbusPDUGetComEventLogResponse(PlcMessage, ModbusPDU):
         )
 
         events: List[c_byte] = read_buffer.read_byte_array(
-            "events", int((byteCount) - (6))
+            "events", int(c_int32(byteCount) - c_int32(c_int32(6)))
         )
 
         read_buffer.close_context("ModbusPDUGetComEventLogResponse")
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUMaskWriteHoldingRegisterRequest.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUMaskWriteHoldingRegisterRequest.py
index 385a468145..51137cb412 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUMaskWriteHoldingRegisterRequest.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUMaskWriteHoldingRegisterRequest.py
@@ -25,6 +25,7 @@ from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 import math
 
 
@@ -34,32 +35,27 @@ class ModbusPDUMaskWriteHoldingRegisterRequest(PlcMessage, ModbusPDU):
     and_mask: c_uint16
     or_mask: c_uint16
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x16
-    response: c_bool = False
+    response: c_bool = c_bool(false)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUMaskWriteHoldingRegisterRequest")
 
         # Simple Field (referenceAddress)
-        write_simple_field(
-            "referenceAddress",
-            self.reference_address,
-            write_unsigned_int(write_buffer, 16),
+        write_buffer.write_unsigned_short(
+            self.reference_address, logical_name="referenceAddress"
         )
 
         # Simple Field (andMask)
-        write_simple_field(
-            "andMask", self.and_mask, write_unsigned_int(write_buffer, 16)
-        )
+        write_buffer.write_unsigned_short(self.and_mask, logical_name="andMask")
 
         # Simple Field (orMask)
-        write_simple_field("orMask", self.or_mask, write_unsigned_int(write_buffer, 16))
+        write_buffer.write_unsigned_short(self.or_mask, logical_name="orMask")
 
         write_buffer.pop_context("ModbusPDUMaskWriteHoldingRegisterRequest")
 
@@ -84,8 +80,7 @@ class ModbusPDUMaskWriteHoldingRegisterRequest(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUMaskWriteHoldingRegisterRequest")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         reference_address: c_uint16 = read_simple_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUMaskWriteHoldingRegisterResponse.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUMaskWriteHoldingRegisterResponse.py
index 0a800bb7a9..b67c7e9946 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUMaskWriteHoldingRegisterResponse.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUMaskWriteHoldingRegisterResponse.py
@@ -25,6 +25,7 @@ from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 import math
 
 
@@ -34,32 +35,27 @@ class ModbusPDUMaskWriteHoldingRegisterResponse(PlcMessage, ModbusPDU):
     and_mask: c_uint16
     or_mask: c_uint16
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x16
-    response: c_bool = True
+    response: c_bool = c_bool(true)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUMaskWriteHoldingRegisterResponse")
 
         # Simple Field (referenceAddress)
-        write_simple_field(
-            "referenceAddress",
-            self.reference_address,
-            write_unsigned_int(write_buffer, 16),
+        write_buffer.write_unsigned_short(
+            self.reference_address, logical_name="referenceAddress"
         )
 
         # Simple Field (andMask)
-        write_simple_field(
-            "andMask", self.and_mask, write_unsigned_int(write_buffer, 16)
-        )
+        write_buffer.write_unsigned_short(self.and_mask, logical_name="andMask")
 
         # Simple Field (orMask)
-        write_simple_field("orMask", self.or_mask, write_unsigned_int(write_buffer, 16))
+        write_buffer.write_unsigned_short(self.or_mask, logical_name="orMask")
 
         write_buffer.pop_context("ModbusPDUMaskWriteHoldingRegisterResponse")
 
@@ -84,8 +80,7 @@ class ModbusPDUMaskWriteHoldingRegisterResponse(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUMaskWriteHoldingRegisterResponse")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         reference_address: c_uint16 = read_simple_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadCoilsRequest.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadCoilsRequest.py
index 3b554f41cb..444b90bedc 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadCoilsRequest.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadCoilsRequest.py
@@ -25,6 +25,7 @@ from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 import math
 
 
@@ -33,29 +34,24 @@ class ModbusPDUReadCoilsRequest(PlcMessage, ModbusPDU):
     starting_address: c_uint16
     quantity: c_uint16
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x01
-    response: c_bool = False
+    response: c_bool = c_bool(false)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUReadCoilsRequest")
 
         # Simple Field (startingAddress)
-        write_simple_field(
-            "startingAddress",
-            self.starting_address,
-            write_unsigned_int(write_buffer, 16),
+        write_buffer.write_unsigned_short(
+            self.starting_address, logical_name="startingAddress"
         )
 
         # Simple Field (quantity)
-        write_simple_field(
-            "quantity", self.quantity, write_unsigned_int(write_buffer, 16)
-        )
+        write_buffer.write_unsigned_short(self.quantity, logical_name="quantity")
 
         write_buffer.pop_context("ModbusPDUReadCoilsRequest")
 
@@ -77,8 +73,7 @@ class ModbusPDUReadCoilsRequest(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUReadCoilsRequest")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         starting_address: c_uint16 = read_simple_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadCoilsResponse.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadCoilsResponse.py
index 923d3055a2..0ccdd3a6f0 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadCoilsResponse.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadCoilsResponse.py
@@ -25,6 +25,7 @@ from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 from typing import List
 import math
 
@@ -33,26 +34,23 @@ import math
 class ModbusPDUReadCoilsResponse(PlcMessage, ModbusPDU):
     value: List[c_byte]
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x01
-    response: c_bool = True
+    response: c_bool = c_bool(true)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUReadCoilsResponse")
 
         # Implicit Field (byte_count) (Used for parsing, but its value is not stored as it's implicitly given by the objects content)
-        byte_count: c_uint8 = c_uint8((COUNT(self.value())))
-        write_implicit_field(
-            "byteCount", byte_count, write_unsigned_short(write_buffer, 8)
-        )
+        byte_count: c_uint8 = c_uint8(len(self.value))
+        write_buffer.write_unsigned_byte(byte_count, logical_name="byteCount")
 
         # Array Field (value)
-        write_byte_array_field("value", self.value, writeByteArray(write_buffer, 8))
+        write_buffer.write_byte_array(self.value, 8, logical_name="value")
 
         write_buffer.pop_context("ModbusPDUReadCoilsResponse")
 
@@ -75,8 +73,7 @@ class ModbusPDUReadCoilsResponse(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUReadCoilsResponse")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         byte_count: c_uint8 = read_implicit_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadDeviceIdentificationRequest.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadDeviceIdentificationRequest.py
index 759a360cd8..7f2be71e4b 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadDeviceIdentificationRequest.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadDeviceIdentificationRequest.py
@@ -27,6 +27,7 @@ from plc4py.protocols.modbus.readwrite.ModbusDeviceInformationLevel import (
 )
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 import math
 
 
@@ -36,39 +37,29 @@ class ModbusPDUReadDeviceIdentificationRequest(PlcMessage, ModbusPDU):
     object_id: c_uint8
     MEITYPE: c_uint8 = 0x0E
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x2B
-    response: c_bool = False
+    response: c_bool = c_bool(false)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUReadDeviceIdentificationRequest")
 
         # Const Field (meiType)
-        write_const_field(
-            "meiType", self.mei_type, write_unsigned_short(write_buffer, 8)
-        )
+        write_buffer.write_unsigned_byte(self.mei_type.value, logical_name="meiType")
 
         # Simple Field (level)
-        write_simple_enum_field(
-            "level",
-            "ModbusDeviceInformationLevel",
-            self.level,
-            DataWriterEnumDefault(
-                ModbusDeviceInformationLevel.value,
-                ModbusDeviceInformationLevel.name,
-                write_unsigned_short(write_buffer, 8),
-            ),
-        )
+        write_buffer.DataWriterEnumDefault(
+            ModbusDeviceInformationLevel.value,
+            ModbusDeviceInformationLevel.name,
+            write_unsigned_byte,
+        )(self.level, logical_name="level")
 
         # Simple Field (objectId)
-        write_simple_field(
-            "objectId", self.object_id, write_unsigned_short(write_buffer, 8)
-        )
+        write_buffer.write_unsigned_byte(self.object_id, logical_name="objectId")
 
         write_buffer.pop_context("ModbusPDUReadDeviceIdentificationRequest")
 
@@ -93,8 +84,7 @@ class ModbusPDUReadDeviceIdentificationRequest(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUReadDeviceIdentificationRequest")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         mei_type: c_uint8 = read_const_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadDeviceIdentificationResponse.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadDeviceIdentificationResponse.py
index 312c83f35b..4a35f54d77 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadDeviceIdentificationResponse.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadDeviceIdentificationResponse.py
@@ -36,6 +36,7 @@ from plc4py.protocols.modbus.readwrite.ModbusDeviceInformationObject import (
 )
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 from typing import List
 import math
 
@@ -50,77 +51,59 @@ class ModbusPDUReadDeviceIdentificationResponse(PlcMessage, ModbusPDU):
     objects: List[ModbusDeviceInformationObject]
     MEITYPE: c_uint8 = 0x0E
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x2B
-    response: c_bool = True
+    response: c_bool = c_bool(true)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUReadDeviceIdentificationResponse")
 
         # Const Field (meiType)
-        write_const_field(
-            "meiType", self.mei_type, write_unsigned_short(write_buffer, 8)
-        )
+        write_buffer.write_unsigned_byte(self.mei_type.value, logical_name="meiType")
 
         # Simple Field (level)
-        write_simple_enum_field(
-            "level",
-            "ModbusDeviceInformationLevel",
-            self.level,
-            DataWriterEnumDefault(
-                ModbusDeviceInformationLevel.value,
-                ModbusDeviceInformationLevel.name,
-                write_unsigned_short(write_buffer, 8),
-            ),
-        )
+        write_buffer.DataWriterEnumDefault(
+            ModbusDeviceInformationLevel.value,
+            ModbusDeviceInformationLevel.name,
+            write_unsigned_byte,
+        )(self.level, logical_name="level")
 
         # Simple Field (individualAccess)
-        write_simple_field(
-            "individualAccess", self.individual_access, write_boolean(write_buffer)
+        write_buffer.write_boolean(
+            self.individual_access, logical_name="individualAccess"
         )
 
         # Simple Field (conformityLevel)
-        write_simple_enum_field(
-            "conformityLevel",
-            "ModbusDeviceInformationConformityLevel",
-            self.conformity_level,
-            DataWriterEnumDefault(
-                ModbusDeviceInformationConformityLevel.value,
-                ModbusDeviceInformationConformityLevel.name,
-                write_unsigned_short(write_buffer, 7),
-            ),
-        )
+        write_buffer.DataWriterEnumDefault(
+            ModbusDeviceInformationConformityLevel.value,
+            ModbusDeviceInformationConformityLevel.name,
+            write_unsigned_byte,
+        )(self.conformity_level, logical_name="conformityLevel")
 
         # Simple Field (moreFollows)
-        write_simple_enum_field(
-            "moreFollows",
-            "ModbusDeviceInformationMoreFollows",
-            self.more_follows,
-            DataWriterEnumDefault(
-                ModbusDeviceInformationMoreFollows.value,
-                ModbusDeviceInformationMoreFollows.name,
-                write_unsigned_short(write_buffer, 8),
-            ),
-        )
+        write_buffer.DataWriterEnumDefault(
+            ModbusDeviceInformationMoreFollows.value,
+            ModbusDeviceInformationMoreFollows.name,
+            write_unsigned_byte,
+        )(self.more_follows, logical_name="moreFollows")
 
         # Simple Field (nextObjectId)
-        write_simple_field(
-            "nextObjectId", self.next_object_id, write_unsigned_short(write_buffer, 8)
+        write_buffer.write_unsigned_byte(
+            self.next_object_id, logical_name="nextObjectId"
         )
 
         # Implicit Field (number_of_objects) (Used for parsing, but its value is not stored as it's implicitly given by the objects content)
-        number_of_objects: c_uint8 = c_uint8((COUNT(self.objects())))
-        write_implicit_field(
-            "numberOfObjects", number_of_objects, write_unsigned_short(write_buffer, 8)
+        number_of_objects: c_uint8 = c_uint8(len(self.objects))
+        write_buffer.write_unsigned_byte(
+            number_of_objects, logical_name="numberOfObjects"
         )
 
         # Array Field (objects)
-        write_complex_type_array_field("objects", self.objects, write_buffer)
+        write_buffer.write_complex_array(self.objects, logical_name="objects")
 
         write_buffer.pop_context("ModbusPDUReadDeviceIdentificationResponse")
 
@@ -164,8 +147,7 @@ class ModbusPDUReadDeviceIdentificationResponse(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUReadDeviceIdentificationResponse")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         mei_type: c_uint8 = read_const_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadDiscreteInputsRequest.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadDiscreteInputsRequest.py
index c2fba3ef26..97b20800b8 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadDiscreteInputsRequest.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadDiscreteInputsRequest.py
@@ -25,6 +25,7 @@ from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 import math
 
 
@@ -33,29 +34,24 @@ class ModbusPDUReadDiscreteInputsRequest(PlcMessage, ModbusPDU):
     starting_address: c_uint16
     quantity: c_uint16
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x02
-    response: c_bool = False
+    response: c_bool = c_bool(false)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUReadDiscreteInputsRequest")
 
         # Simple Field (startingAddress)
-        write_simple_field(
-            "startingAddress",
-            self.starting_address,
-            write_unsigned_int(write_buffer, 16),
+        write_buffer.write_unsigned_short(
+            self.starting_address, logical_name="startingAddress"
         )
 
         # Simple Field (quantity)
-        write_simple_field(
-            "quantity", self.quantity, write_unsigned_int(write_buffer, 16)
-        )
+        write_buffer.write_unsigned_short(self.quantity, logical_name="quantity")
 
         write_buffer.pop_context("ModbusPDUReadDiscreteInputsRequest")
 
@@ -77,8 +73,7 @@ class ModbusPDUReadDiscreteInputsRequest(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUReadDiscreteInputsRequest")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         starting_address: c_uint16 = read_simple_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadDiscreteInputsResponse.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadDiscreteInputsResponse.py
index 0bafeb94f4..afa39fcc4e 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadDiscreteInputsResponse.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadDiscreteInputsResponse.py
@@ -25,6 +25,7 @@ from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 from typing import List
 import math
 
@@ -33,26 +34,23 @@ import math
 class ModbusPDUReadDiscreteInputsResponse(PlcMessage, ModbusPDU):
     value: List[c_byte]
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x02
-    response: c_bool = True
+    response: c_bool = c_bool(true)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUReadDiscreteInputsResponse")
 
         # Implicit Field (byte_count) (Used for parsing, but its value is not stored as it's implicitly given by the objects content)
-        byte_count: c_uint8 = c_uint8((COUNT(self.value())))
-        write_implicit_field(
-            "byteCount", byte_count, write_unsigned_short(write_buffer, 8)
-        )
+        byte_count: c_uint8 = c_uint8(len(self.value))
+        write_buffer.write_unsigned_byte(byte_count, logical_name="byteCount")
 
         # Array Field (value)
-        write_byte_array_field("value", self.value, writeByteArray(write_buffer, 8))
+        write_buffer.write_byte_array(self.value, 8, logical_name="value")
 
         write_buffer.pop_context("ModbusPDUReadDiscreteInputsResponse")
 
@@ -75,8 +73,7 @@ class ModbusPDUReadDiscreteInputsResponse(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUReadDiscreteInputsResponse")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         byte_count: c_uint8 = read_implicit_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadExceptionStatusRequest.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadExceptionStatusRequest.py
index 8b69cb93ac..be5fd8d8d2 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadExceptionStatusRequest.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadExceptionStatusRequest.py
@@ -24,22 +24,22 @@ from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 import math
 
 
 @dataclass
 class ModbusPDUReadExceptionStatusRequest(PlcMessage, ModbusPDU):
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x07
-    response: c_bool = False
+    response: c_bool = c_bool(false)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUReadExceptionStatusRequest")
 
         write_buffer.pop_context("ModbusPDUReadExceptionStatusRequest")
@@ -56,8 +56,7 @@ class ModbusPDUReadExceptionStatusRequest(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUReadExceptionStatusRequest")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         read_buffer.close_context("ModbusPDUReadExceptionStatusRequest")
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadExceptionStatusResponse.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadExceptionStatusResponse.py
index afb01ded60..7e66a893f9 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadExceptionStatusResponse.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadExceptionStatusResponse.py
@@ -24,6 +24,7 @@ from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 import math
 
 
@@ -31,20 +32,19 @@ import math
 class ModbusPDUReadExceptionStatusResponse(PlcMessage, ModbusPDU):
     value: c_uint8
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x07
-    response: c_bool = True
+    response: c_bool = c_bool(true)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUReadExceptionStatusResponse")
 
         # Simple Field (value)
-        write_simple_field("value", self.value, write_unsigned_short(write_buffer, 8))
+        write_buffer.write_unsigned_byte(self.value, logical_name="value")
 
         write_buffer.pop_context("ModbusPDUReadExceptionStatusResponse")
 
@@ -63,8 +63,7 @@ class ModbusPDUReadExceptionStatusResponse(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUReadExceptionStatusResponse")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         value: c_uint8 = read_simple_field("value", read_unsigned_short(read_buffer, 8))
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFifoQueueRequest.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFifoQueueRequest.py
index 0afea69b9d..1a5dd76b9d 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFifoQueueRequest.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFifoQueueRequest.py
@@ -25,6 +25,7 @@ from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 import math
 
 
@@ -32,23 +33,20 @@ import math
 class ModbusPDUReadFifoQueueRequest(PlcMessage, ModbusPDU):
     fifo_pointer_address: c_uint16
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x18
-    response: c_bool = False
+    response: c_bool = c_bool(false)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUReadFifoQueueRequest")
 
         # Simple Field (fifoPointerAddress)
-        write_simple_field(
-            "fifoPointerAddress",
-            self.fifo_pointer_address,
-            write_unsigned_int(write_buffer, 16),
+        write_buffer.write_unsigned_short(
+            self.fifo_pointer_address, logical_name="fifoPointerAddress"
         )
 
         write_buffer.pop_context("ModbusPDUReadFifoQueueRequest")
@@ -68,8 +66,7 @@ class ModbusPDUReadFifoQueueRequest(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUReadFifoQueueRequest")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         fifo_pointer_address: c_uint16 = read_simple_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFifoQueueResponse.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFifoQueueResponse.py
index 7cc80730fa..cfa769833e 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFifoQueueResponse.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFifoQueueResponse.py
@@ -25,6 +25,7 @@ from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 from typing import List
 import math
 
@@ -33,33 +34,32 @@ import math
 class ModbusPDUReadFifoQueueResponse(PlcMessage, ModbusPDU):
     fifo_value: List[c_uint16]
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x18
-    response: c_bool = True
+    response: c_bool = c_bool(true)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUReadFifoQueueResponse")
 
         # Implicit Field (byte_count) (Used for parsing, but its value is not stored as it's implicitly given by the objects content)
-        byte_count: c_uint16 = c_uint16(((((COUNT(self.fifo_value())) * (2))) + (2)))
-        write_implicit_field(
-            "byteCount", byte_count, write_unsigned_int(write_buffer, 16)
-        )
+        byte_count: c_uint16 = c_uint16(
+            (c_uint16(c_uint16(len(self.fifo_value))) * c_uint16(c_uint16(2)))
+        ) + c_uint16(c_uint16(2))
+        write_buffer.write_unsigned_short(byte_count, logical_name="byteCount")
 
         # Implicit Field (fifo_count) (Used for parsing, but its value is not stored as it's implicitly given by the objects content)
-        fifo_count: c_uint16 = c_uint16(((((COUNT(self.fifo_value())) * (2))) / (2)))
-        write_implicit_field(
-            "fifoCount", fifo_count, write_unsigned_int(write_buffer, 16)
-        )
+        fifo_count: c_uint16 = c_uint16(
+            (c_uint16(c_uint16(len(self.fifo_value))) * c_uint16(c_uint16(2)))
+        ) / c_uint16(c_uint16(2))
+        write_buffer.write_unsigned_short(fifo_count, logical_name="fifoCount")
 
         # Array Field (fifoValue)
-        write_simple_type_array_field(
-            "fifoValue", self.fifo_value, write_unsigned_int(write_buffer, 16)
+        write_buffer.write_simple_array(
+            self.fifo_value, write_unsigned_short, logical_name="fifoValue"
         )
 
         write_buffer.pop_context("ModbusPDUReadFifoQueueResponse")
@@ -86,8 +86,7 @@ class ModbusPDUReadFifoQueueResponse(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUReadFifoQueueResponse")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         byte_count: c_uint16 = read_implicit_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFileRecordRequest.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFileRecordRequest.py
index 932031abad..99850b8f93 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFileRecordRequest.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFileRecordRequest.py
@@ -27,6 +27,7 @@ from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
 from plc4py.protocols.modbus.readwrite.ModbusPDUReadFileRecordRequestItem import (
     ModbusPDUReadFileRecordRequestItem,
 )
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 from typing import List
 import math
 
@@ -35,26 +36,23 @@ import math
 class ModbusPDUReadFileRecordRequest(PlcMessage, ModbusPDU):
     items: List[ModbusPDUReadFileRecordRequestItem]
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x14
-    response: c_bool = False
+    response: c_bool = c_bool(false)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUReadFileRecordRequest")
 
         # Implicit Field (byte_count) (Used for parsing, but its value is not stored as it's implicitly given by the objects content)
-        byte_count: c_uint8 = c_uint8((ARRAY_SIZE_IN_BYTES(self.items())))
-        write_implicit_field(
-            "byteCount", byte_count, write_unsigned_short(write_buffer, 8)
-        )
+        byte_count: c_uint8 = c_uint8(itemsArraySizeInBytes(self.items))
+        write_buffer.write_unsigned_byte(byte_count, logical_name="byteCount")
 
         # Array Field (items)
-        write_complex_type_array_field("items", self.items, write_buffer)
+        write_buffer.write_complex_array(self.items, logical_name="items")
 
         write_buffer.pop_context("ModbusPDUReadFileRecordRequest")
 
@@ -78,8 +76,7 @@ class ModbusPDUReadFileRecordRequest(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUReadFileRecordRequest")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         byte_count: c_uint8 = read_implicit_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFileRecordRequestItem.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFileRecordRequestItem.py
index 61475ad25f..d7b322ba45 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFileRecordRequestItem.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFileRecordRequestItem.py
@@ -22,6 +22,7 @@ from dataclasses import dataclass
 from ctypes import c_uint16
 from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 import math
 
 
@@ -36,28 +37,25 @@ class ModbusPDUReadFileRecordRequestItem(PlcMessage):
         super().__init__()
 
     def serialize(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUReadFileRecordRequestItem")
 
         # Simple Field (referenceType)
-        write_simple_field(
-            "referenceType", self.reference_type, write_unsigned_short(write_buffer, 8)
+        write_buffer.write_unsigned_byte(
+            self.reference_type, logical_name="referenceType"
         )
 
         # Simple Field (fileNumber)
-        write_simple_field(
-            "fileNumber", self.file_number, write_unsigned_int(write_buffer, 16)
-        )
+        write_buffer.write_unsigned_short(self.file_number, logical_name="fileNumber")
 
         # Simple Field (recordNumber)
-        write_simple_field(
-            "recordNumber", self.record_number, write_unsigned_int(write_buffer, 16)
+        write_buffer.write_unsigned_short(
+            self.record_number, logical_name="recordNumber"
         )
 
         # Simple Field (recordLength)
-        write_simple_field(
-            "recordLength", self.record_length, write_unsigned_int(write_buffer, 16)
+        write_buffer.write_unsigned_short(
+            self.record_length, logical_name="recordLength"
         )
 
         write_buffer.pop_context("ModbusPDUReadFileRecordRequestItem")
@@ -84,14 +82,12 @@ class ModbusPDUReadFileRecordRequestItem(PlcMessage):
         return length_in_bits
 
     def static_parse(read_buffer: ReadBuffer, args):
-        position_aware: PositionAware = read_buffer
         return staticParse(read_buffer)
 
     @staticmethod
     def static_parse_context(read_buffer: ReadBuffer):
         read_buffer.pull_context("ModbusPDUReadFileRecordRequestItem")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         reference_type: c_uint8 = read_simple_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFileRecordResponse.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFileRecordResponse.py
index ea7489803a..d00ce01c9c 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFileRecordResponse.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFileRecordResponse.py
@@ -27,6 +27,7 @@ from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
 from plc4py.protocols.modbus.readwrite.ModbusPDUReadFileRecordResponseItem import (
     ModbusPDUReadFileRecordResponseItem,
 )
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 from typing import List
 import math
 
@@ -35,26 +36,23 @@ import math
 class ModbusPDUReadFileRecordResponse(PlcMessage, ModbusPDU):
     items: List[ModbusPDUReadFileRecordResponseItem]
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x14
-    response: c_bool = True
+    response: c_bool = c_bool(true)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUReadFileRecordResponse")
 
         # Implicit Field (byte_count) (Used for parsing, but its value is not stored as it's implicitly given by the objects content)
-        byte_count: c_uint8 = c_uint8((ARRAY_SIZE_IN_BYTES(self.items())))
-        write_implicit_field(
-            "byteCount", byte_count, write_unsigned_short(write_buffer, 8)
-        )
+        byte_count: c_uint8 = c_uint8(itemsArraySizeInBytes(self.items))
+        write_buffer.write_unsigned_byte(byte_count, logical_name="byteCount")
 
         # Array Field (items)
-        write_complex_type_array_field("items", self.items, write_buffer)
+        write_buffer.write_complex_array(self.items, logical_name="items")
 
         write_buffer.pop_context("ModbusPDUReadFileRecordResponse")
 
@@ -78,8 +76,7 @@ class ModbusPDUReadFileRecordResponse(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUReadFileRecordResponse")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         byte_count: c_uint8 = read_implicit_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFileRecordResponseItem.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFileRecordResponseItem.py
index 2bd4936c80..63dc78d3d0 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFileRecordResponseItem.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadFileRecordResponseItem.py
@@ -20,8 +20,10 @@
 from dataclasses import dataclass
 
 from ctypes import c_byte
+from ctypes import c_int32
 from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 from typing import List
 import math
 
@@ -35,23 +37,20 @@ class ModbusPDUReadFileRecordResponseItem(PlcMessage):
         super().__init__()
 
     def serialize(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUReadFileRecordResponseItem")
 
         # Implicit Field (data_length) (Used for parsing, but its value is not stored as it's implicitly given by the objects content)
-        data_length: c_uint8 = c_uint8(((COUNT(self.data())) + (1)))
-        write_implicit_field(
-            "dataLength", data_length, write_unsigned_short(write_buffer, 8)
-        )
+        data_length: c_uint8 = c_uint8(c_uint8(len(self.data))) + c_uint8(c_uint8(1))
+        write_buffer.write_unsigned_byte(data_length, logical_name="dataLength")
 
         # Simple Field (referenceType)
-        write_simple_field(
-            "referenceType", self.reference_type, write_unsigned_short(write_buffer, 8)
+        write_buffer.write_unsigned_byte(
+            self.reference_type, logical_name="referenceType"
         )
 
         # Array Field (data)
-        write_byte_array_field("data", self.data, writeByteArray(write_buffer, 8))
+        write_buffer.write_byte_array(self.data, 8, logical_name="data")
 
         write_buffer.pop_context("ModbusPDUReadFileRecordResponseItem")
 
@@ -75,14 +74,12 @@ class ModbusPDUReadFileRecordResponseItem(PlcMessage):
         return length_in_bits
 
     def static_parse(read_buffer: ReadBuffer, args):
-        position_aware: PositionAware = read_buffer
         return staticParse(read_buffer)
 
     @staticmethod
     def static_parse_context(read_buffer: ReadBuffer):
         read_buffer.pull_context("ModbusPDUReadFileRecordResponseItem")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         data_length: c_uint8 = read_implicit_field(
@@ -94,7 +91,7 @@ class ModbusPDUReadFileRecordResponseItem(PlcMessage):
         )
 
         data: List[c_byte] = read_buffer.read_byte_array(
-            "data", int((dataLength) - (1))
+            "data", int(c_int32(dataLength) - c_int32(c_int32(1)))
         )
 
         read_buffer.close_context("ModbusPDUReadFileRecordResponseItem")
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadHoldingRegistersRequest.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadHoldingRegistersRequest.py
index 31034ea6bd..d647466eb1 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadHoldingRegistersRequest.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadHoldingRegistersRequest.py
@@ -25,6 +25,7 @@ from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 import math
 
 
@@ -33,29 +34,24 @@ class ModbusPDUReadHoldingRegistersRequest(PlcMessage, ModbusPDU):
     starting_address: c_uint16
     quantity: c_uint16
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x03
-    response: c_bool = False
+    response: c_bool = c_bool(false)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUReadHoldingRegistersRequest")
 
         # Simple Field (startingAddress)
-        write_simple_field(
-            "startingAddress",
-            self.starting_address,
-            write_unsigned_int(write_buffer, 16),
+        write_buffer.write_unsigned_short(
+            self.starting_address, logical_name="startingAddress"
         )
 
         # Simple Field (quantity)
-        write_simple_field(
-            "quantity", self.quantity, write_unsigned_int(write_buffer, 16)
-        )
+        write_buffer.write_unsigned_short(self.quantity, logical_name="quantity")
 
         write_buffer.pop_context("ModbusPDUReadHoldingRegistersRequest")
 
@@ -77,8 +73,7 @@ class ModbusPDUReadHoldingRegistersRequest(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUReadHoldingRegistersRequest")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         starting_address: c_uint16 = read_simple_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadHoldingRegistersResponse.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadHoldingRegistersResponse.py
index a7f2104f90..2f34aa9447 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadHoldingRegistersResponse.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadHoldingRegistersResponse.py
@@ -25,6 +25,7 @@ from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 from typing import List
 import math
 
@@ -33,26 +34,23 @@ import math
 class ModbusPDUReadHoldingRegistersResponse(PlcMessage, ModbusPDU):
     value: List[c_byte]
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x03
-    response: c_bool = True
+    response: c_bool = c_bool(true)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUReadHoldingRegistersResponse")
 
         # Implicit Field (byte_count) (Used for parsing, but its value is not stored as it's implicitly given by the objects content)
-        byte_count: c_uint8 = c_uint8((COUNT(self.value())))
-        write_implicit_field(
-            "byteCount", byte_count, write_unsigned_short(write_buffer, 8)
-        )
+        byte_count: c_uint8 = c_uint8(len(self.value))
+        write_buffer.write_unsigned_byte(byte_count, logical_name="byteCount")
 
         # Array Field (value)
-        write_byte_array_field("value", self.value, writeByteArray(write_buffer, 8))
+        write_buffer.write_byte_array(self.value, 8, logical_name="value")
 
         write_buffer.pop_context("ModbusPDUReadHoldingRegistersResponse")
 
@@ -75,8 +73,7 @@ class ModbusPDUReadHoldingRegistersResponse(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUReadHoldingRegistersResponse")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         byte_count: c_uint8 = read_implicit_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadInputRegistersRequest.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadInputRegistersRequest.py
index 094b818271..f417da4e02 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadInputRegistersRequest.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadInputRegistersRequest.py
@@ -25,6 +25,7 @@ from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 import math
 
 
@@ -33,29 +34,24 @@ class ModbusPDUReadInputRegistersRequest(PlcMessage, ModbusPDU):
     starting_address: c_uint16
     quantity: c_uint16
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x04
-    response: c_bool = False
+    response: c_bool = c_bool(false)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUReadInputRegistersRequest")
 
         # Simple Field (startingAddress)
-        write_simple_field(
-            "startingAddress",
-            self.starting_address,
-            write_unsigned_int(write_buffer, 16),
+        write_buffer.write_unsigned_short(
+            self.starting_address, logical_name="startingAddress"
         )
 
         # Simple Field (quantity)
-        write_simple_field(
-            "quantity", self.quantity, write_unsigned_int(write_buffer, 16)
-        )
+        write_buffer.write_unsigned_short(self.quantity, logical_name="quantity")
 
         write_buffer.pop_context("ModbusPDUReadInputRegistersRequest")
 
@@ -77,8 +73,7 @@ class ModbusPDUReadInputRegistersRequest(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUReadInputRegistersRequest")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         starting_address: c_uint16 = read_simple_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadInputRegistersResponse.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadInputRegistersResponse.py
index f075d15ffd..b540e08136 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadInputRegistersResponse.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadInputRegistersResponse.py
@@ -25,6 +25,7 @@ from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 from typing import List
 import math
 
@@ -33,26 +34,23 @@ import math
 class ModbusPDUReadInputRegistersResponse(PlcMessage, ModbusPDU):
     value: List[c_byte]
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x04
-    response: c_bool = True
+    response: c_bool = c_bool(true)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUReadInputRegistersResponse")
 
         # Implicit Field (byte_count) (Used for parsing, but its value is not stored as it's implicitly given by the objects content)
-        byte_count: c_uint8 = c_uint8((COUNT(self.value())))
-        write_implicit_field(
-            "byteCount", byte_count, write_unsigned_short(write_buffer, 8)
-        )
+        byte_count: c_uint8 = c_uint8(len(self.value))
+        write_buffer.write_unsigned_byte(byte_count, logical_name="byteCount")
 
         # Array Field (value)
-        write_byte_array_field("value", self.value, writeByteArray(write_buffer, 8))
+        write_buffer.write_byte_array(self.value, 8, logical_name="value")
 
         write_buffer.pop_context("ModbusPDUReadInputRegistersResponse")
 
@@ -75,8 +73,7 @@ class ModbusPDUReadInputRegistersResponse(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUReadInputRegistersResponse")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         byte_count: c_uint8 = read_implicit_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadWriteMultipleHoldingRegistersRequest.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadWriteMultipleHoldingRegistersRequest.py
index 8f9663b0fb..ba29db1fd0 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadWriteMultipleHoldingRegistersRequest.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadWriteMultipleHoldingRegistersRequest.py
@@ -26,6 +26,7 @@ from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 from typing import List
 import math
 
@@ -38,50 +39,43 @@ class ModbusPDUReadWriteMultipleHoldingRegistersRequest(PlcMessage, ModbusPDU):
     write_quantity: c_uint16
     value: List[c_byte]
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x17
-    response: c_bool = False
+    response: c_bool = c_bool(false)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUReadWriteMultipleHoldingRegistersRequest")
 
         # Simple Field (readStartingAddress)
-        write_simple_field(
-            "readStartingAddress",
-            self.read_starting_address,
-            write_unsigned_int(write_buffer, 16),
+        write_buffer.write_unsigned_short(
+            self.read_starting_address, logical_name="readStartingAddress"
         )
 
         # Simple Field (readQuantity)
-        write_simple_field(
-            "readQuantity", self.read_quantity, write_unsigned_int(write_buffer, 16)
+        write_buffer.write_unsigned_short(
+            self.read_quantity, logical_name="readQuantity"
         )
 
         # Simple Field (writeStartingAddress)
-        write_simple_field(
-            "writeStartingAddress",
-            self.write_starting_address,
-            write_unsigned_int(write_buffer, 16),
+        write_buffer.write_unsigned_short(
+            self.write_starting_address, logical_name="writeStartingAddress"
         )
 
         # Simple Field (writeQuantity)
-        write_simple_field(
-            "writeQuantity", self.write_quantity, write_unsigned_int(write_buffer, 16)
+        write_buffer.write_unsigned_short(
+            self.write_quantity, logical_name="writeQuantity"
         )
 
         # Implicit Field (byte_count) (Used for parsing, but its value is not stored as it's implicitly given by the objects content)
-        byte_count: c_uint8 = c_uint8((COUNT(self.value())))
-        write_implicit_field(
-            "byteCount", byte_count, write_unsigned_short(write_buffer, 8)
-        )
+        byte_count: c_uint8 = c_uint8(len(self.value))
+        write_buffer.write_unsigned_byte(byte_count, logical_name="byteCount")
 
         # Array Field (value)
-        write_byte_array_field("value", self.value, writeByteArray(write_buffer, 8))
+        write_buffer.write_byte_array(self.value, 8, logical_name="value")
 
         write_buffer.pop_context("ModbusPDUReadWriteMultipleHoldingRegistersRequest")
 
@@ -116,8 +110,7 @@ class ModbusPDUReadWriteMultipleHoldingRegistersRequest(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUReadWriteMultipleHoldingRegistersRequest")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         read_starting_address: c_uint16 = read_simple_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadWriteMultipleHoldingRegistersResponse.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadWriteMultipleHoldingRegistersResponse.py
index 9a204a0f3c..249c0da70b 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadWriteMultipleHoldingRegistersResponse.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReadWriteMultipleHoldingRegistersResponse.py
@@ -25,6 +25,7 @@ from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 from typing import List
 import math
 
@@ -33,26 +34,23 @@ import math
 class ModbusPDUReadWriteMultipleHoldingRegistersResponse(PlcMessage, ModbusPDU):
     value: List[c_byte]
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x17
-    response: c_bool = True
+    response: c_bool = c_bool(true)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUReadWriteMultipleHoldingRegistersResponse")
 
         # Implicit Field (byte_count) (Used for parsing, but its value is not stored as it's implicitly given by the objects content)
-        byte_count: c_uint8 = c_uint8((COUNT(self.value())))
-        write_implicit_field(
-            "byteCount", byte_count, write_unsigned_short(write_buffer, 8)
-        )
+        byte_count: c_uint8 = c_uint8(len(self.value))
+        write_buffer.write_unsigned_byte(byte_count, logical_name="byteCount")
 
         # Array Field (value)
-        write_byte_array_field("value", self.value, writeByteArray(write_buffer, 8))
+        write_buffer.write_byte_array(self.value, 8, logical_name="value")
 
         write_buffer.pop_context("ModbusPDUReadWriteMultipleHoldingRegistersResponse")
 
@@ -75,8 +73,7 @@ class ModbusPDUReadWriteMultipleHoldingRegistersResponse(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUReadWriteMultipleHoldingRegistersResponse")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         byte_count: c_uint8 = read_implicit_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReportServerIdRequest.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReportServerIdRequest.py
index b1d7ae4ed6..fd8e32be31 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReportServerIdRequest.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReportServerIdRequest.py
@@ -24,22 +24,22 @@ from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 import math
 
 
 @dataclass
 class ModbusPDUReportServerIdRequest(PlcMessage, ModbusPDU):
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x11
-    response: c_bool = False
+    response: c_bool = c_bool(false)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUReportServerIdRequest")
 
         write_buffer.pop_context("ModbusPDUReportServerIdRequest")
@@ -56,8 +56,7 @@ class ModbusPDUReportServerIdRequest(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUReportServerIdRequest")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         read_buffer.close_context("ModbusPDUReportServerIdRequest")
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReportServerIdResponse.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReportServerIdResponse.py
index 6ecc408459..a2087de9a9 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReportServerIdResponse.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUReportServerIdResponse.py
@@ -25,6 +25,7 @@ from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 from typing import List
 import math
 
@@ -33,26 +34,23 @@ import math
 class ModbusPDUReportServerIdResponse(PlcMessage, ModbusPDU):
     value: List[c_byte]
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x11
-    response: c_bool = True
+    response: c_bool = c_bool(true)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUReportServerIdResponse")
 
         # Implicit Field (byte_count) (Used for parsing, but its value is not stored as it's implicitly given by the objects content)
-        byte_count: c_uint8 = c_uint8((COUNT(self.value())))
-        write_implicit_field(
-            "byteCount", byte_count, write_unsigned_short(write_buffer, 8)
-        )
+        byte_count: c_uint8 = c_uint8(len(self.value))
+        write_buffer.write_unsigned_byte(byte_count, logical_name="byteCount")
 
         # Array Field (value)
-        write_byte_array_field("value", self.value, writeByteArray(write_buffer, 8))
+        write_buffer.write_byte_array(self.value, 8, logical_name="value")
 
         write_buffer.pop_context("ModbusPDUReportServerIdResponse")
 
@@ -75,8 +73,7 @@ class ModbusPDUReportServerIdResponse(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUReportServerIdResponse")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         byte_count: c_uint8 = read_implicit_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteFileRecordRequest.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteFileRecordRequest.py
index 8057d11edd..5b97b0ea39 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteFileRecordRequest.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteFileRecordRequest.py
@@ -27,6 +27,7 @@ from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
 from plc4py.protocols.modbus.readwrite.ModbusPDUWriteFileRecordRequestItem import (
     ModbusPDUWriteFileRecordRequestItem,
 )
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 from typing import List
 import math
 
@@ -35,26 +36,23 @@ import math
 class ModbusPDUWriteFileRecordRequest(PlcMessage, ModbusPDU):
     items: List[ModbusPDUWriteFileRecordRequestItem]
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x15
-    response: c_bool = False
+    response: c_bool = c_bool(false)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUWriteFileRecordRequest")
 
         # Implicit Field (byte_count) (Used for parsing, but its value is not stored as it's implicitly given by the objects content)
-        byte_count: c_uint8 = c_uint8((ARRAY_SIZE_IN_BYTES(self.items())))
-        write_implicit_field(
-            "byteCount", byte_count, write_unsigned_short(write_buffer, 8)
-        )
+        byte_count: c_uint8 = c_uint8(itemsArraySizeInBytes(self.items))
+        write_buffer.write_unsigned_byte(byte_count, logical_name="byteCount")
 
         # Array Field (items)
-        write_complex_type_array_field("items", self.items, write_buffer)
+        write_buffer.write_complex_array(self.items, logical_name="items")
 
         write_buffer.pop_context("ModbusPDUWriteFileRecordRequest")
 
@@ -78,8 +76,7 @@ class ModbusPDUWriteFileRecordRequest(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUWriteFileRecordRequest")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         byte_count: c_uint8 = read_implicit_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteFileRecordRequestItem.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteFileRecordRequestItem.py
index 71c86d9545..9f900ad63d 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteFileRecordRequestItem.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteFileRecordRequestItem.py
@@ -20,9 +20,11 @@
 from dataclasses import dataclass
 
 from ctypes import c_byte
+from ctypes import c_int32
 from ctypes import c_uint16
 from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 from typing import List
 import math
 
@@ -38,35 +40,30 @@ class ModbusPDUWriteFileRecordRequestItem(PlcMessage):
         super().__init__()
 
     def serialize(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUWriteFileRecordRequestItem")
 
         # Simple Field (referenceType)
-        write_simple_field(
-            "referenceType", self.reference_type, write_unsigned_short(write_buffer, 8)
+        write_buffer.write_unsigned_byte(
+            self.reference_type, logical_name="referenceType"
         )
 
         # Simple Field (fileNumber)
-        write_simple_field(
-            "fileNumber", self.file_number, write_unsigned_int(write_buffer, 16)
-        )
+        write_buffer.write_unsigned_short(self.file_number, logical_name="fileNumber")
 
         # Simple Field (recordNumber)
-        write_simple_field(
-            "recordNumber", self.record_number, write_unsigned_int(write_buffer, 16)
+        write_buffer.write_unsigned_short(
+            self.record_number, logical_name="recordNumber"
         )
 
         # Implicit Field (record_length) (Used for parsing, but its value is not stored as it's implicitly given by the objects content)
-        record_length: c_uint16 = c_uint16(((COUNT(self.record_data())) / (2)))
-        write_implicit_field(
-            "recordLength", record_length, write_unsigned_int(write_buffer, 16)
+        record_length: c_uint16 = c_uint16(c_uint16(len(self.record_data))) / c_uint16(
+            c_uint16(2)
         )
+        write_buffer.write_unsigned_short(record_length, logical_name="recordLength")
 
         # Array Field (recordData)
-        write_byte_array_field(
-            "recordData", self.record_data, writeByteArray(write_buffer, 8)
-        )
+        write_buffer.write_byte_array(self.record_data, 8, logical_name="recordData")
 
         write_buffer.pop_context("ModbusPDUWriteFileRecordRequestItem")
 
@@ -96,14 +93,12 @@ class ModbusPDUWriteFileRecordRequestItem(PlcMessage):
         return length_in_bits
 
     def static_parse(read_buffer: ReadBuffer, args):
-        position_aware: PositionAware = read_buffer
         return staticParse(read_buffer)
 
     @staticmethod
     def static_parse_context(read_buffer: ReadBuffer):
         read_buffer.pull_context("ModbusPDUWriteFileRecordRequestItem")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         reference_type: c_uint8 = read_simple_field(
@@ -123,7 +118,7 @@ class ModbusPDUWriteFileRecordRequestItem(PlcMessage):
         )
 
         record_data: List[c_byte] = read_buffer.read_byte_array(
-            "recordData", int((recordLength) * (2))
+            "recordData", int(c_int32(recordLength) * c_int32(c_int32(2)))
         )
 
         read_buffer.close_context("ModbusPDUWriteFileRecordRequestItem")
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteFileRecordResponse.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteFileRecordResponse.py
index 5cea4aa7cf..0b6c5b10fd 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteFileRecordResponse.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteFileRecordResponse.py
@@ -27,6 +27,7 @@ from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
 from plc4py.protocols.modbus.readwrite.ModbusPDUWriteFileRecordResponseItem import (
     ModbusPDUWriteFileRecordResponseItem,
 )
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 from typing import List
 import math
 
@@ -35,26 +36,23 @@ import math
 class ModbusPDUWriteFileRecordResponse(PlcMessage, ModbusPDU):
     items: List[ModbusPDUWriteFileRecordResponseItem]
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x15
-    response: c_bool = True
+    response: c_bool = c_bool(true)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUWriteFileRecordResponse")
 
         # Implicit Field (byte_count) (Used for parsing, but its value is not stored as it's implicitly given by the objects content)
-        byte_count: c_uint8 = c_uint8((ARRAY_SIZE_IN_BYTES(self.items())))
-        write_implicit_field(
-            "byteCount", byte_count, write_unsigned_short(write_buffer, 8)
-        )
+        byte_count: c_uint8 = c_uint8(itemsArraySizeInBytes(self.items))
+        write_buffer.write_unsigned_byte(byte_count, logical_name="byteCount")
 
         # Array Field (items)
-        write_complex_type_array_field("items", self.items, write_buffer)
+        write_buffer.write_complex_array(self.items, logical_name="items")
 
         write_buffer.pop_context("ModbusPDUWriteFileRecordResponse")
 
@@ -78,8 +76,7 @@ class ModbusPDUWriteFileRecordResponse(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUWriteFileRecordResponse")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         byte_count: c_uint8 = read_implicit_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteFileRecordResponseItem.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteFileRecordResponseItem.py
index 89bfafa373..c4f92aefb7 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteFileRecordResponseItem.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteFileRecordResponseItem.py
@@ -23,6 +23,7 @@ from ctypes import c_byte
 from ctypes import c_uint16
 from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 from typing import List
 import math
 
@@ -38,35 +39,30 @@ class ModbusPDUWriteFileRecordResponseItem(PlcMessage):
         super().__init__()
 
     def serialize(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUWriteFileRecordResponseItem")
 
         # Simple Field (referenceType)
-        write_simple_field(
-            "referenceType", self.reference_type, write_unsigned_short(write_buffer, 8)
+        write_buffer.write_unsigned_byte(
+            self.reference_type, logical_name="referenceType"
         )
 
         # Simple Field (fileNumber)
-        write_simple_field(
-            "fileNumber", self.file_number, write_unsigned_int(write_buffer, 16)
-        )
+        write_buffer.write_unsigned_short(self.file_number, logical_name="fileNumber")
 
         # Simple Field (recordNumber)
-        write_simple_field(
-            "recordNumber", self.record_number, write_unsigned_int(write_buffer, 16)
+        write_buffer.write_unsigned_short(
+            self.record_number, logical_name="recordNumber"
         )
 
         # Implicit Field (record_length) (Used for parsing, but its value is not stored as it's implicitly given by the objects content)
-        record_length: c_uint16 = c_uint16(((COUNT(self.record_data())) / (2)))
-        write_implicit_field(
-            "recordLength", record_length, write_unsigned_int(write_buffer, 16)
+        record_length: c_uint16 = c_uint16(c_uint16(len(self.record_data))) / c_uint16(
+            c_uint16(2)
         )
+        write_buffer.write_unsigned_short(record_length, logical_name="recordLength")
 
         # Array Field (recordData)
-        write_byte_array_field(
-            "recordData", self.record_data, writeByteArray(write_buffer, 8)
-        )
+        write_buffer.write_byte_array(self.record_data, 8, logical_name="recordData")
 
         write_buffer.pop_context("ModbusPDUWriteFileRecordResponseItem")
 
@@ -96,14 +92,12 @@ class ModbusPDUWriteFileRecordResponseItem(PlcMessage):
         return length_in_bits
 
     def static_parse(read_buffer: ReadBuffer, args):
-        position_aware: PositionAware = read_buffer
         return staticParse(read_buffer)
 
     @staticmethod
     def static_parse_context(read_buffer: ReadBuffer):
         read_buffer.pull_context("ModbusPDUWriteFileRecordResponseItem")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         reference_type: c_uint8 = read_simple_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteMultipleCoilsRequest.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteMultipleCoilsRequest.py
index e66aa21caa..a57653364b 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteMultipleCoilsRequest.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteMultipleCoilsRequest.py
@@ -26,6 +26,7 @@ from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 from typing import List
 import math
 
@@ -36,38 +37,31 @@ class ModbusPDUWriteMultipleCoilsRequest(PlcMessage, ModbusPDU):
     quantity: c_uint16
     value: List[c_byte]
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x0F
-    response: c_bool = False
+    response: c_bool = c_bool(false)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUWriteMultipleCoilsRequest")
 
         # Simple Field (startingAddress)
-        write_simple_field(
-            "startingAddress",
-            self.starting_address,
-            write_unsigned_int(write_buffer, 16),
+        write_buffer.write_unsigned_short(
+            self.starting_address, logical_name="startingAddress"
         )
 
         # Simple Field (quantity)
-        write_simple_field(
-            "quantity", self.quantity, write_unsigned_int(write_buffer, 16)
-        )
+        write_buffer.write_unsigned_short(self.quantity, logical_name="quantity")
 
         # Implicit Field (byte_count) (Used for parsing, but its value is not stored as it's implicitly given by the objects content)
-        byte_count: c_uint8 = c_uint8((COUNT(self.value())))
-        write_implicit_field(
-            "byteCount", byte_count, write_unsigned_short(write_buffer, 8)
-        )
+        byte_count: c_uint8 = c_uint8(len(self.value))
+        write_buffer.write_unsigned_byte(byte_count, logical_name="byteCount")
 
         # Array Field (value)
-        write_byte_array_field("value", self.value, writeByteArray(write_buffer, 8))
+        write_buffer.write_byte_array(self.value, 8, logical_name="value")
 
         write_buffer.pop_context("ModbusPDUWriteMultipleCoilsRequest")
 
@@ -96,8 +90,7 @@ class ModbusPDUWriteMultipleCoilsRequest(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUWriteMultipleCoilsRequest")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         starting_address: c_uint16 = read_simple_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteMultipleCoilsResponse.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteMultipleCoilsResponse.py
index 97c057b687..9575571c0a 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteMultipleCoilsResponse.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteMultipleCoilsResponse.py
@@ -25,6 +25,7 @@ from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 import math
 
 
@@ -33,29 +34,24 @@ class ModbusPDUWriteMultipleCoilsResponse(PlcMessage, ModbusPDU):
     starting_address: c_uint16
     quantity: c_uint16
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x0F
-    response: c_bool = True
+    response: c_bool = c_bool(true)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUWriteMultipleCoilsResponse")
 
         # Simple Field (startingAddress)
-        write_simple_field(
-            "startingAddress",
-            self.starting_address,
-            write_unsigned_int(write_buffer, 16),
+        write_buffer.write_unsigned_short(
+            self.starting_address, logical_name="startingAddress"
         )
 
         # Simple Field (quantity)
-        write_simple_field(
-            "quantity", self.quantity, write_unsigned_int(write_buffer, 16)
-        )
+        write_buffer.write_unsigned_short(self.quantity, logical_name="quantity")
 
         write_buffer.pop_context("ModbusPDUWriteMultipleCoilsResponse")
 
@@ -77,8 +73,7 @@ class ModbusPDUWriteMultipleCoilsResponse(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUWriteMultipleCoilsResponse")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         starting_address: c_uint16 = read_simple_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteMultipleHoldingRegistersRequest.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteMultipleHoldingRegistersRequest.py
index 22f71b303c..d8c827ce03 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteMultipleHoldingRegistersRequest.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteMultipleHoldingRegistersRequest.py
@@ -26,6 +26,7 @@ from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 from typing import List
 import math
 
@@ -36,38 +37,31 @@ class ModbusPDUWriteMultipleHoldingRegistersRequest(PlcMessage, ModbusPDU):
     quantity: c_uint16
     value: List[c_byte]
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x10
-    response: c_bool = False
+    response: c_bool = c_bool(false)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUWriteMultipleHoldingRegistersRequest")
 
         # Simple Field (startingAddress)
-        write_simple_field(
-            "startingAddress",
-            self.starting_address,
-            write_unsigned_int(write_buffer, 16),
+        write_buffer.write_unsigned_short(
+            self.starting_address, logical_name="startingAddress"
         )
 
         # Simple Field (quantity)
-        write_simple_field(
-            "quantity", self.quantity, write_unsigned_int(write_buffer, 16)
-        )
+        write_buffer.write_unsigned_short(self.quantity, logical_name="quantity")
 
         # Implicit Field (byte_count) (Used for parsing, but its value is not stored as it's implicitly given by the objects content)
-        byte_count: c_uint8 = c_uint8((COUNT(self.value())))
-        write_implicit_field(
-            "byteCount", byte_count, write_unsigned_short(write_buffer, 8)
-        )
+        byte_count: c_uint8 = c_uint8(len(self.value))
+        write_buffer.write_unsigned_byte(byte_count, logical_name="byteCount")
 
         # Array Field (value)
-        write_byte_array_field("value", self.value, writeByteArray(write_buffer, 8))
+        write_buffer.write_byte_array(self.value, 8, logical_name="value")
 
         write_buffer.pop_context("ModbusPDUWriteMultipleHoldingRegistersRequest")
 
@@ -96,8 +90,7 @@ class ModbusPDUWriteMultipleHoldingRegistersRequest(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUWriteMultipleHoldingRegistersRequest")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         starting_address: c_uint16 = read_simple_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteMultipleHoldingRegistersResponse.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteMultipleHoldingRegistersResponse.py
index 2a3d442adb..4ea61b0482 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteMultipleHoldingRegistersResponse.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteMultipleHoldingRegistersResponse.py
@@ -25,6 +25,7 @@ from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 import math
 
 
@@ -33,29 +34,24 @@ class ModbusPDUWriteMultipleHoldingRegistersResponse(PlcMessage, ModbusPDU):
     starting_address: c_uint16
     quantity: c_uint16
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x10
-    response: c_bool = True
+    response: c_bool = c_bool(true)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUWriteMultipleHoldingRegistersResponse")
 
         # Simple Field (startingAddress)
-        write_simple_field(
-            "startingAddress",
-            self.starting_address,
-            write_unsigned_int(write_buffer, 16),
+        write_buffer.write_unsigned_short(
+            self.starting_address, logical_name="startingAddress"
         )
 
         # Simple Field (quantity)
-        write_simple_field(
-            "quantity", self.quantity, write_unsigned_int(write_buffer, 16)
-        )
+        write_buffer.write_unsigned_short(self.quantity, logical_name="quantity")
 
         write_buffer.pop_context("ModbusPDUWriteMultipleHoldingRegistersResponse")
 
@@ -77,8 +73,7 @@ class ModbusPDUWriteMultipleHoldingRegistersResponse(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUWriteMultipleHoldingRegistersResponse")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         starting_address: c_uint16 = read_simple_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteSingleCoilRequest.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteSingleCoilRequest.py
index ecd89d263f..8ce893a370 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteSingleCoilRequest.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteSingleCoilRequest.py
@@ -25,6 +25,7 @@ from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 import math
 
 
@@ -33,25 +34,22 @@ class ModbusPDUWriteSingleCoilRequest(PlcMessage, ModbusPDU):
     address: c_uint16
     value: c_uint16
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x05
-    response: c_bool = False
+    response: c_bool = c_bool(false)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUWriteSingleCoilRequest")
 
         # Simple Field (address)
-        write_simple_field(
-            "address", self.address, write_unsigned_int(write_buffer, 16)
-        )
+        write_buffer.write_unsigned_short(self.address, logical_name="address")
 
         # Simple Field (value)
-        write_simple_field("value", self.value, write_unsigned_int(write_buffer, 16))
+        write_buffer.write_unsigned_short(self.value, logical_name="value")
 
         write_buffer.pop_context("ModbusPDUWriteSingleCoilRequest")
 
@@ -73,8 +71,7 @@ class ModbusPDUWriteSingleCoilRequest(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUWriteSingleCoilRequest")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         address: c_uint16 = read_simple_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteSingleCoilResponse.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteSingleCoilResponse.py
index 530937d2c3..d7d8728e1e 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteSingleCoilResponse.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteSingleCoilResponse.py
@@ -25,6 +25,7 @@ from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 import math
 
 
@@ -33,25 +34,22 @@ class ModbusPDUWriteSingleCoilResponse(PlcMessage, ModbusPDU):
     address: c_uint16
     value: c_uint16
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x05
-    response: c_bool = True
+    response: c_bool = c_bool(true)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUWriteSingleCoilResponse")
 
         # Simple Field (address)
-        write_simple_field(
-            "address", self.address, write_unsigned_int(write_buffer, 16)
-        )
+        write_buffer.write_unsigned_short(self.address, logical_name="address")
 
         # Simple Field (value)
-        write_simple_field("value", self.value, write_unsigned_int(write_buffer, 16))
+        write_buffer.write_unsigned_short(self.value, logical_name="value")
 
         write_buffer.pop_context("ModbusPDUWriteSingleCoilResponse")
 
@@ -73,8 +71,7 @@ class ModbusPDUWriteSingleCoilResponse(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUWriteSingleCoilResponse")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         address: c_uint16 = read_simple_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteSingleRegisterRequest.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteSingleRegisterRequest.py
index c5b747a557..c6e6276f39 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteSingleRegisterRequest.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteSingleRegisterRequest.py
@@ -25,6 +25,7 @@ from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 import math
 
 
@@ -33,25 +34,22 @@ class ModbusPDUWriteSingleRegisterRequest(PlcMessage, ModbusPDU):
     address: c_uint16
     value: c_uint16
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x06
-    response: c_bool = False
+    response: c_bool = c_bool(false)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUWriteSingleRegisterRequest")
 
         # Simple Field (address)
-        write_simple_field(
-            "address", self.address, write_unsigned_int(write_buffer, 16)
-        )
+        write_buffer.write_unsigned_short(self.address, logical_name="address")
 
         # Simple Field (value)
-        write_simple_field("value", self.value, write_unsigned_int(write_buffer, 16))
+        write_buffer.write_unsigned_short(self.value, logical_name="value")
 
         write_buffer.pop_context("ModbusPDUWriteSingleRegisterRequest")
 
@@ -73,8 +71,7 @@ class ModbusPDUWriteSingleRegisterRequest(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUWriteSingleRegisterRequest")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         address: c_uint16 = read_simple_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteSingleRegisterResponse.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteSingleRegisterResponse.py
index a390983f66..2a9adefeed 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteSingleRegisterResponse.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusPDUWriteSingleRegisterResponse.py
@@ -25,6 +25,7 @@ from ctypes import c_uint8
 from plc4py.api.messages.PlcMessage import PlcMessage
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDUBuilder
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 import math
 
 
@@ -33,25 +34,22 @@ class ModbusPDUWriteSingleRegisterResponse(PlcMessage, ModbusPDU):
     address: c_uint16
     value: c_uint16
     # Accessors for discriminator values.
-    error_flag: c_bool = False
+    error_flag: c_bool = c_bool(false)
     function_flag: c_uint8 = 0x06
-    response: c_bool = True
+    response: c_bool = c_bool(true)
 
     def __post_init__(self):
         super().__init__()
 
     def serialize_modbus_pdu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusPDUWriteSingleRegisterResponse")
 
         # Simple Field (address)
-        write_simple_field(
-            "address", self.address, write_unsigned_int(write_buffer, 16)
-        )
+        write_buffer.write_unsigned_short(self.address, logical_name="address")
 
         # Simple Field (value)
-        write_simple_field("value", self.value, write_unsigned_int(write_buffer, 16))
+        write_buffer.write_unsigned_short(self.value, logical_name="value")
 
         write_buffer.pop_context("ModbusPDUWriteSingleRegisterResponse")
 
@@ -73,8 +71,7 @@ class ModbusPDUWriteSingleRegisterResponse(PlcMessage, ModbusPDU):
     @staticmethod
     def static_parse_builder(read_buffer: ReadBuffer, response: c_bool):
         read_buffer.pull_context("ModbusPDUWriteSingleRegisterResponse")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         address: c_uint16 = read_simple_field(
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusRtuADU.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusRtuADU.py
index 1c4cab2ad6..9386f1e799 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusRtuADU.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusRtuADU.py
@@ -27,6 +27,7 @@ from plc4py.protocols.modbus.readwrite.DriverType import DriverType
 from plc4py.protocols.modbus.readwrite.ModbusADU import ModbusADU
 from plc4py.protocols.modbus.readwrite.ModbusADU import ModbusADUBuilder
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 import math
 
 
@@ -37,37 +38,26 @@ class ModbusRtuADU(PlcMessage, ModbusADU):
     # Arguments.
     response: c_bool
     # Accessors for discriminator values.
-    driver_type: DriverType = DriverType.MODBUS_RTU
+    driver_type: DriverType = DriverType.get_modbu_s__rtu()
 
     def __post_init__(self):
         super().__init__(self.response)
 
     def serialize_modbus_adu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusRtuADU")
 
         # Simple Field (address)
-        write_simple_field(
-            "address",
-            self.address,
-            write_unsigned_short(write_buffer, 8),
-            WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN),
-        )
+        write_buffer.write_unsigned_byte(self.address, logical_name="address")
 
         # Simple Field (pdu)
-        write_simple_field(
-            "pdu",
-            self.pdu,
-            DataWriterComplexDefault(write_buffer),
-            WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN),
+        write_buffer.DataWriterComplexDefault(write_buffer)(
+            self.pdu, logical_name="pdu"
         )
 
         # Checksum Field (checksum) (Calculated)
-        write_checksum_field(
-            "crc",
-            c_uint16(modbus.readwrite.utils.StaticHelper.rtuCrcCheck(address, pdu)),
-            write_unsigned_int(write_buffer, 16),
+        write_buffer.write_unsigned_short(
+            c_uint16(rtu_crc_check(address, pdu)), logical_name="crc"
         )
 
         write_buffer.pop_context("ModbusRtuADU")
@@ -95,14 +85,13 @@ class ModbusRtuADU(PlcMessage, ModbusADU):
         read_buffer: ReadBuffer, driver_type: DriverType, response: c_bool
     ):
         read_buffer.pull_context("ModbusRtuADU")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         address: c_uint8 = read_simple_field(
             "address",
             read_unsigned_short(read_buffer, 8),
-            WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN),
+            WithOption.WithByteOrder(get_bi_g__endian()),
         )
 
         pdu: ModbusPDU = read_simple_field(
@@ -110,14 +99,14 @@ class ModbusRtuADU(PlcMessage, ModbusADU):
             DataReaderComplexDefault(
                 ModbusPDU.static_parse(read_buffer, c_bool(response)), read_buffer
             ),
-            WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN),
+            WithOption.WithByteOrder(get_bi_g__endian()),
         )
 
         crc: c_uint16 = read_checksum_field(
             "crc",
             read_unsigned_int(read_buffer, 16),
-            (c_uint16)(modbus.readwrite.utils.StaticHelper.rtuCrcCheck(address, pdu)),
-            WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN),
+            (c_uint16)(rtu_crc_check(address, pdu)),
+            WithOption.WithByteOrder(get_bi_g__endian()),
         )
 
         read_buffer.close_context("ModbusRtuADU")
diff --git a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusTcpADU.py b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusTcpADU.py
index 5fb53a9d18..b8016d45cb 100644
--- a/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusTcpADU.py
+++ b/sandbox/plc4py/plc4py/protocols/modbus/readwrite/ModbusTcpADU.py
@@ -27,6 +27,7 @@ from plc4py.protocols.modbus.readwrite.DriverType import DriverType
 from plc4py.protocols.modbus.readwrite.ModbusADU import ModbusADU
 from plc4py.protocols.modbus.readwrite.ModbusADU import ModbusADUBuilder
 from plc4py.protocols.modbus.readwrite.ModbusPDU import ModbusPDU
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 import math
 
 
@@ -39,49 +40,39 @@ class ModbusTcpADU(PlcMessage, ModbusADU):
     response: c_bool
     PROTOCOLIDENTIFIER: c_uint16 = 0x0000
     # Accessors for discriminator values.
-    driver_type: DriverType = DriverType.MODBUS_TCP
+    driver_type: DriverType = DriverType.get_modbu_s__tcp()
 
     def __post_init__(self):
         super().__init__(self.response)
 
     def serialize_modbus_adu_child(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("ModbusTcpADU")
 
         # Simple Field (transactionIdentifier)
-        write_simple_field(
-            "transactionIdentifier",
-            self.transaction_identifier,
-            write_unsigned_int(write_buffer, 16),
-            WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN),
+        write_buffer.write_unsigned_short(
+            self.transaction_identifier, logical_name="transactionIdentifier"
         )
 
         # Const Field (protocolIdentifier)
-        write_const_field(
-            "protocolIdentifier",
-            self.protocol_identifier,
-            write_unsigned_int(write_buffer, 16),
+        write_buffer.write_unsigned_short(
+            self.protocol_identifier.value, logical_name="protocolIdentifier"
         )
 
         # Implicit Field (length) (Used for parsing, but its value is not stored as it's implicitly given by the objects content)
-        length: c_uint16 = c_uint16(((self.pdu().self.length_in_bytes()) + (1)))
-        write_implicit_field("length", length, write_unsigned_int(write_buffer, 16))
+        length: c_uint16 = c_uint16(self.pdu.getlength_in_bytes(ctx)) + c_uint16(
+            c_uint16(1)
+        )
+        write_buffer.write_unsigned_short(length, logical_name="length")
 
         # Simple Field (unitIdentifier)
-        write_simple_field(
-            "unitIdentifier",
-            self.unit_identifier,
-            write_unsigned_short(write_buffer, 8),
-            WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN),
+        write_buffer.write_unsigned_byte(
+            self.unit_identifier, logical_name="unitIdentifier"
         )
 
         # Simple Field (pdu)
-        write_simple_field(
-            "pdu",
-            self.pdu,
-            DataWriterComplexDefault(write_buffer),
-            WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN),
+        write_buffer.DataWriterComplexDefault(write_buffer)(
+            self.pdu, logical_name="pdu"
         )
 
         write_buffer.pop_context("ModbusTcpADU")
@@ -115,33 +106,32 @@ class ModbusTcpADU(PlcMessage, ModbusADU):
         read_buffer: ReadBuffer, driver_type: DriverType, response: c_bool
     ):
         read_buffer.pull_context("ModbusTcpADU")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         transaction_identifier: c_uint16 = read_simple_field(
             "transactionIdentifier",
             read_unsigned_int(read_buffer, 16),
-            WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN),
+            WithOption.WithByteOrder(get_bi_g__endian()),
         )
 
         protocol_identifier: c_uint16 = read_const_field(
             "protocolIdentifier",
             read_unsigned_int(read_buffer, 16),
             ModbusTcpADU.PROTOCOLIDENTIFIER,
-            WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN),
+            WithOption.WithByteOrder(get_bi_g__endian()),
         )
 
         length: c_uint16 = read_implicit_field(
             "length",
             read_unsigned_int(read_buffer, 16),
-            WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN),
+            WithOption.WithByteOrder(get_bi_g__endian()),
         )
 
         unit_identifier: c_uint8 = read_simple_field(
             "unitIdentifier",
             read_unsigned_short(read_buffer, 8),
-            WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN),
+            WithOption.WithByteOrder(get_bi_g__endian()),
         )
 
         pdu: ModbusPDU = read_simple_field(
@@ -149,7 +139,7 @@ class ModbusTcpADU(PlcMessage, ModbusADU):
             DataReaderComplexDefault(
                 ModbusPDU.static_parse(read_buffer, c_bool(response)), read_buffer
             ),
-            WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN),
+            WithOption.WithByteOrder(get_bi_g__endian()),
         )
 
         read_buffer.close_context("ModbusTcpADU")
diff --git a/sandbox/plc4py/plc4py/protocols/simulated/readwrite/DataItem.py b/sandbox/plc4py/plc4py/protocols/simulated/readwrite/DataItem.py
index 1843b14718..e64f50970e 100644
--- a/sandbox/plc4py/plc4py/protocols/simulated/readwrite/DataItem.py
+++ b/sandbox/plc4py/plc4py/protocols/simulated/readwrite/DataItem.py
@@ -39,7 +39,7 @@ class DataItem:
         read_buffer: ReadBuffer, data_type: str, number_of_values: c_uint16
     ):
         if EvaluationHelper.equals(data_type, "_bool") and EvaluationHelper.equals(
-            number_of_values, 1
+            number_of_values, c_uint16(1)
         ):  # BOOL
             # Simple Field (value)
             value: c_bool = read_buffer.readBit("")
@@ -63,7 +63,7 @@ class DataItem:
 
             return PlcList(value)
         if EvaluationHelper.equals(data_type, "_byte") and EvaluationHelper.equals(
-            number_of_values, 1
+            number_of_values, c_uint16(1)
         ):  # BYTE
             # Simple Field (value)
             value: c_uint8 = read_buffer.readUnsignedShort("", 8)
@@ -87,7 +87,7 @@ class DataItem:
 
             return PlcList(value)
         if EvaluationHelper.equals(data_type, "_word") and EvaluationHelper.equals(
-            number_of_values, 1
+            number_of_values, c_uint16(1)
         ):  # WORD
             # Simple Field (value)
             value: c_uint16 = read_buffer.readUnsignedInt("", 16)
@@ -111,7 +111,7 @@ class DataItem:
 
             return PlcList(value)
         if EvaluationHelper.equals(data_type, "_dword") and EvaluationHelper.equals(
-            number_of_values, 1
+            number_of_values, c_uint16(1)
         ):  # DWORD
             # Simple Field (value)
             value: c_uint32 = read_buffer.readUnsignedLong("", 32)
@@ -135,7 +135,7 @@ class DataItem:
 
             return PlcList(value)
         if EvaluationHelper.equals(data_type, "_lword") and EvaluationHelper.equals(
-            number_of_values, 1
+            number_of_values, c_uint16(1)
         ):  # LWORD
             # Simple Field (value)
             value: c_uint64 = read_buffer.readUnsignedBigInteger("", 64)
@@ -161,7 +161,7 @@ class DataItem:
 
             return PlcList(value)
         if EvaluationHelper.equals(data_type, "_sint") and EvaluationHelper.equals(
-            number_of_values, 1
+            number_of_values, c_uint16(1)
         ):  # SINT
             # Simple Field (value)
             value: c_int8 = read_buffer.readSignedByte("", 8)
@@ -185,7 +185,7 @@ class DataItem:
 
             return PlcList(value)
         if EvaluationHelper.equals(data_type, "_int") and EvaluationHelper.equals(
-            number_of_values, 1
+            number_of_values, c_uint16(1)
         ):  # INT
             # Simple Field (value)
             value: c_int16 = read_buffer.readShort("", 16)
@@ -209,7 +209,7 @@ class DataItem:
 
             return PlcList(value)
         if EvaluationHelper.equals(data_type, "_dint") and EvaluationHelper.equals(
-            number_of_values, 1
+            number_of_values, c_uint16(1)
         ):  # DINT
             # Simple Field (value)
             value: c_int32 = read_buffer.readInt("", 32)
@@ -233,7 +233,7 @@ class DataItem:
 
             return PlcList(value)
         if EvaluationHelper.equals(data_type, "_lint") and EvaluationHelper.equals(
-            number_of_values, 1
+            number_of_values, c_uint16(1)
         ):  # LINT
             # Simple Field (value)
             value: c_int64 = read_buffer.readLong("", 64)
@@ -257,7 +257,7 @@ class DataItem:
 
             return PlcList(value)
         if EvaluationHelper.equals(data_type, "_usint") and EvaluationHelper.equals(
-            number_of_values, 1
+            number_of_values, c_uint16(1)
         ):  # USINT
             # Simple Field (value)
             value: c_uint8 = read_buffer.readUnsignedShort("", 8)
@@ -281,7 +281,7 @@ class DataItem:
 
             return PlcList(value)
         if EvaluationHelper.equals(data_type, "_uint") and EvaluationHelper.equals(
-            number_of_values, 1
+            number_of_values, c_uint16(1)
         ):  # UINT
             # Simple Field (value)
             value: c_uint16 = read_buffer.readUnsignedInt("", 16)
@@ -305,7 +305,7 @@ class DataItem:
 
             return PlcList(value)
         if EvaluationHelper.equals(data_type, "_udint") and EvaluationHelper.equals(
-            number_of_values, 1
+            number_of_values, c_uint16(1)
         ):  # UDINT
             # Simple Field (value)
             value: c_uint32 = read_buffer.readUnsignedLong("", 32)
@@ -329,7 +329,7 @@ class DataItem:
 
             return PlcList(value)
         if EvaluationHelper.equals(data_type, "_ulint") and EvaluationHelper.equals(
-            number_of_values, 1
+            number_of_values, c_uint16(1)
         ):  # ULINT
             # Simple Field (value)
             value: c_uint64 = read_buffer.readUnsignedBigInteger("", 64)
@@ -355,7 +355,7 @@ class DataItem:
 
             return PlcList(value)
         if EvaluationHelper.equals(data_type, "_real") and EvaluationHelper.equals(
-            number_of_values, 1
+            number_of_values, c_uint16(1)
         ):  # REAL
             # Simple Field (value)
             value: c_float = read_buffer.readFloat("", 32)
@@ -379,7 +379,7 @@ class DataItem:
 
             return PlcList(value)
         if EvaluationHelper.equals(data_type, "_lreal") and EvaluationHelper.equals(
-            number_of_values, 1
+            number_of_values, c_uint16(1)
         ):  # LREAL
             # Simple Field (value)
             value: c_double = read_buffer.readDouble("", 64)
@@ -403,7 +403,7 @@ class DataItem:
 
             return PlcList(value)
         if EvaluationHelper.equals(data_type, "_char") and EvaluationHelper.equals(
-            number_of_values, 1
+            number_of_values, c_uint16(1)
         ):  # CHAR
             # Simple Field (value)
             value: str = read_buffer.readString("", 8, "UTF-8")
@@ -427,7 +427,7 @@ class DataItem:
 
             return PlcList(value)
         if EvaluationHelper.equals(data_type, "_wchar") and EvaluationHelper.equals(
-            number_of_values, 1
+            number_of_values, c_uint16(1)
         ):  # WCHAR
             # Simple Field (value)
             value: str = read_buffer.readString("", 16, "UTF-16")
@@ -482,234 +482,234 @@ class DataItem:
         byteOrder: ByteOrder,
     ) -> None:
         if EvaluationHelper.equals(dataType, "BOOL") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # BOOL
             # Simple Field (value)
             value: c_bool = _value.getC_bool()
-            writeBuffer.writeBit("", bool((value)))
+            writeBuffer.WriteBit("value", (value))
         if EvaluationHelper.equals(dataType, "BOOL"):  # List
             values: PlcList = _value
 
             for val in values.getList():
                 value: c_bool = val.getC_bool()
-                writeBuffer.writeBit("", bool((value)))
+                writeBuffer.WriteBit("value", (value))
 
         if EvaluationHelper.equals(dataType, "BYTE") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # BYTE
             # Simple Field (value)
             value: c_uint8 = _value.getC_uint8()
-            writeBuffer.writeUnsignedShort("", 8, (value).shortValue())
+            writeBuffer.WriteUint8("value", 8, (value))
         if EvaluationHelper.equals(dataType, "BYTE"):  # List
             values: PlcList = _value
 
             for val in values.getList():
                 value: c_uint8 = val.getC_uint8()
-                writeBuffer.writeUnsignedShort("", 8, (value).shortValue())
+                writeBuffer.WriteUint8("value", 8, (value))
 
         if EvaluationHelper.equals(dataType, "WORD") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # WORD
             # Simple Field (value)
             value: c_uint16 = _value.getC_uint16()
-            writeBuffer.writeUnsignedInt("", 16, (value).intValue())
+            writeBuffer.WriteUint16("value", 16, (value))
         if EvaluationHelper.equals(dataType, "WORD"):  # List
             values: PlcList = _value
 
             for val in values.getList():
                 value: c_uint16 = val.getC_uint16()
-                writeBuffer.writeUnsignedInt("", 16, (value).intValue())
+                writeBuffer.WriteUint16("value", 16, (value))
 
         if EvaluationHelper.equals(dataType, "DWORD") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # DWORD
             # Simple Field (value)
             value: c_uint32 = _value.getC_uint32()
-            writeBuffer.writeUnsignedLong("", 32, (value).longValue())
+            writeBuffer.WriteUint32("value", 32, (value))
         if EvaluationHelper.equals(dataType, "DWORD"):  # List
             values: PlcList = _value
 
             for val in values.getList():
                 value: c_uint32 = val.getC_uint32()
-                writeBuffer.writeUnsignedLong("", 32, (value).longValue())
+                writeBuffer.WriteUint32("value", 32, (value))
 
         if EvaluationHelper.equals(dataType, "LWORD") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # LWORD
             # Simple Field (value)
             value: c_uint64 = _value.getC_uint64()
-            writeBuffer.writeUnsignedBigInteger("", 64, (value))
+            writeBuffer.WriteUint64("value", 64, (value))
         if EvaluationHelper.equals(dataType, "LWORD"):  # List
             values: PlcList = _value
 
             for val in values.getList():
                 value: c_uint64 = val.getC_uint64()
-                writeBuffer.writeUnsignedBigInteger("", 64, (value))
+                writeBuffer.WriteUint64("value", 64, (value))
 
         if EvaluationHelper.equals(dataType, "SINT") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # SINT
             # Simple Field (value)
             value: c_int8 = _value.getC_int8()
-            writeBuffer.writeSignedByte("", 8, (value).byteValue())
+            writeBuffer.WriteInt8("value", 8, (value))
         if EvaluationHelper.equals(dataType, "SINT"):  # List
             values: PlcList = _value
 
             for val in values.getList():
                 value: c_int8 = val.getC_int8()
-                writeBuffer.writeSignedByte("", 8, (value).byteValue())
+                writeBuffer.WriteInt8("value", 8, (value))
 
         if EvaluationHelper.equals(dataType, "INT") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # INT
             # Simple Field (value)
             value: c_int16 = _value.getC_int16()
-            writeBuffer.writeShort("", 16, (value).shortValue())
+            writeBuffer.WriteInt16("value", 16, (value))
         if EvaluationHelper.equals(dataType, "INT"):  # List
             values: PlcList = _value
 
             for val in values.getList():
                 value: c_int16 = val.getC_int16()
-                writeBuffer.writeShort("", 16, (value).shortValue())
+                writeBuffer.WriteInt16("value", 16, (value))
 
         if EvaluationHelper.equals(dataType, "DINT") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # DINT
             # Simple Field (value)
             value: c_int32 = _value.getC_int32()
-            writeBuffer.writeInt("", 32, (value).intValue())
+            writeBuffer.WriteInt32("value", 32, (value))
         if EvaluationHelper.equals(dataType, "DINT"):  # List
             values: PlcList = _value
 
             for val in values.getList():
                 value: c_int32 = val.getC_int32()
-                writeBuffer.writeInt("", 32, (value).intValue())
+                writeBuffer.WriteInt32("value", 32, (value))
 
         if EvaluationHelper.equals(dataType, "LINT") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # LINT
             # Simple Field (value)
             value: c_int64 = _value.getC_int64()
-            writeBuffer.writeLong("", 64, (value).longValue())
+            writeBuffer.WriteInt64("value", 64, (value))
         if EvaluationHelper.equals(dataType, "LINT"):  # List
             values: PlcList = _value
 
             for val in values.getList():
                 value: c_int64 = val.getC_int64()
-                writeBuffer.writeLong("", 64, (value).longValue())
+                writeBuffer.WriteInt64("value", 64, (value))
 
         if EvaluationHelper.equals(dataType, "USINT") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # USINT
             # Simple Field (value)
             value: c_uint8 = _value.getC_uint8()
-            writeBuffer.writeUnsignedShort("", 8, (value).shortValue())
+            writeBuffer.WriteUint8("value", 8, (value))
         if EvaluationHelper.equals(dataType, "USINT"):  # List
             values: PlcList = _value
 
             for val in values.getList():
                 value: c_uint8 = val.getC_uint8()
-                writeBuffer.writeUnsignedShort("", 8, (value).shortValue())
+                writeBuffer.WriteUint8("value", 8, (value))
 
         if EvaluationHelper.equals(dataType, "UINT") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # UINT
             # Simple Field (value)
             value: c_uint16 = _value.getC_uint16()
-            writeBuffer.writeUnsignedInt("", 16, (value).intValue())
+            writeBuffer.WriteUint16("value", 16, (value))
         if EvaluationHelper.equals(dataType, "UINT"):  # List
             values: PlcList = _value
 
             for val in values.getList():
                 value: c_uint16 = val.getC_uint16()
-                writeBuffer.writeUnsignedInt("", 16, (value).intValue())
+                writeBuffer.WriteUint16("value", 16, (value))
 
         if EvaluationHelper.equals(dataType, "UDINT") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # UDINT
             # Simple Field (value)
             value: c_uint32 = _value.getC_uint32()
-            writeBuffer.writeUnsignedLong("", 32, (value).longValue())
+            writeBuffer.WriteUint32("value", 32, (value))
         if EvaluationHelper.equals(dataType, "UDINT"):  # List
             values: PlcList = _value
 
             for val in values.getList():
                 value: c_uint32 = val.getC_uint32()
-                writeBuffer.writeUnsignedLong("", 32, (value).longValue())
+                writeBuffer.WriteUint32("value", 32, (value))
 
         if EvaluationHelper.equals(dataType, "ULINT") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # ULINT
             # Simple Field (value)
             value: c_uint64 = _value.getC_uint64()
-            writeBuffer.writeUnsignedBigInteger("", 64, (value))
+            writeBuffer.WriteUint64("value", 64, (value))
         if EvaluationHelper.equals(dataType, "ULINT"):  # List
             values: PlcList = _value
 
             for val in values.getList():
                 value: c_uint64 = val.getC_uint64()
-                writeBuffer.writeUnsignedBigInteger("", 64, (value))
+                writeBuffer.WriteUint64("value", 64, (value))
 
         if EvaluationHelper.equals(dataType, "REAL") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # REAL
             # Simple Field (value)
             value: c_float = _value.getC_float()
-            writeBuffer.writeFloat("", 32, (value))
+            writeBuffer.WriteFloat32("value", 32, (value))
         if EvaluationHelper.equals(dataType, "REAL"):  # List
             values: PlcList = _value
 
             for val in values.getList():
                 value: c_float = val.getC_float()
-                writeBuffer.writeFloat("", 32, (value))
+                writeBuffer.WriteFloat32("value", 32, (value))
 
         if EvaluationHelper.equals(dataType, "LREAL") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # LREAL
             # Simple Field (value)
             value: c_double = _value.getC_double()
-            writeBuffer.writeDouble("", 64, (value))
+            writeBuffer.WriteFloat64("value", 64, (value))
         if EvaluationHelper.equals(dataType, "LREAL"):  # List
             values: PlcList = _value
 
             for val in values.getList():
                 value: c_double = val.getC_double()
-                writeBuffer.writeDouble("", 64, (value))
+                writeBuffer.WriteFloat64("value", 64, (value))
 
         if EvaluationHelper.equals(dataType, "CHAR") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # CHAR
             # Simple Field (value)
             value: str = _value.getStr()
-            writeBuffer.writeString("", 8, "UTF-8", (String)(value))
+            writeBuffer.WriteString("value", uint32(8), "UTF-8", (value))
         if EvaluationHelper.equals(dataType, "CHAR"):  # List
             values: PlcList = _value
 
             for val in values.getList():
                 value: str = val.getStr()
-                writeBuffer.writeString("", 8, "UTF-8", (String)(value))
+                writeBuffer.WriteString("value", uint32(8), "UTF-8", (value))
 
         if EvaluationHelper.equals(dataType, "WCHAR") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # WCHAR
             # Simple Field (value)
             value: str = _value.getStr()
-            writeBuffer.writeString("", 16, "UTF-16", (String)(value))
+            writeBuffer.WriteString("value", uint32(16), "UTF-16", (value))
         if EvaluationHelper.equals(dataType, "WCHAR"):  # List
             values: PlcList = _value
 
             for val in values.getList():
                 value: str = val.getStr()
-                writeBuffer.writeString("", 16, "UTF-16", (String)(value))
+                writeBuffer.WriteString("value", uint32(16), "UTF-16", (value))
 
         if EvaluationHelper.equals(dataType, "STRING"):  # STRING
             # Simple Field (value)
             value: str = _value.getStr()
-            writeBuffer.writeString("", 255, "UTF-8", (String)(value))
+            writeBuffer.WriteString("value", uint32(255), "UTF-8", (value))
         if EvaluationHelper.equals(dataType, "WSTRING"):  # STRING
             # Simple Field (value)
             value: str = _value.getStr()
-            writeBuffer.writeString("", 255, "UTF-16", (String)(value))
+            writeBuffer.WriteString("value", uint32(255), "UTF-16", (value))
 
     @staticmethod
     def get_length_in_bytes(
@@ -725,7 +725,7 @@ class DataItem:
     ) -> int:
         sizeInBits: int = 0
         if EvaluationHelper.equals(dataType, "BOOL") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # BOOL
             # Simple Field (value)
             sizeInBits += 1
@@ -733,7 +733,7 @@ class DataItem:
             values: PlcList = _value
             sizeInBits += values.getList().size() * 1
         if EvaluationHelper.equals(dataType, "BYTE") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # BYTE
             # Simple Field (value)
             sizeInBits += 8
@@ -741,7 +741,7 @@ class DataItem:
             values: PlcList = _value
             sizeInBits += values.getList().size() * 8
         if EvaluationHelper.equals(dataType, "WORD") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # WORD
             # Simple Field (value)
             sizeInBits += 16
@@ -749,7 +749,7 @@ class DataItem:
             values: PlcList = _value
             sizeInBits += values.getList().size() * 16
         if EvaluationHelper.equals(dataType, "DWORD") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # DWORD
             # Simple Field (value)
             sizeInBits += 32
@@ -757,7 +757,7 @@ class DataItem:
             values: PlcList = _value
             sizeInBits += values.getList().size() * 32
         if EvaluationHelper.equals(dataType, "LWORD") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # LWORD
             # Simple Field (value)
             sizeInBits += 64
@@ -765,7 +765,7 @@ class DataItem:
             values: PlcList = _value
             sizeInBits += values.getList().size() * 64
         if EvaluationHelper.equals(dataType, "SINT") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # SINT
             # Simple Field (value)
             sizeInBits += 8
@@ -773,7 +773,7 @@ class DataItem:
             values: PlcList = _value
             sizeInBits += values.getList().size() * 8
         if EvaluationHelper.equals(dataType, "INT") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # INT
             # Simple Field (value)
             sizeInBits += 16
@@ -781,7 +781,7 @@ class DataItem:
             values: PlcList = _value
             sizeInBits += values.getList().size() * 16
         if EvaluationHelper.equals(dataType, "DINT") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # DINT
             # Simple Field (value)
             sizeInBits += 32
@@ -789,7 +789,7 @@ class DataItem:
             values: PlcList = _value
             sizeInBits += values.getList().size() * 32
         if EvaluationHelper.equals(dataType, "LINT") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # LINT
             # Simple Field (value)
             sizeInBits += 64
@@ -797,7 +797,7 @@ class DataItem:
             values: PlcList = _value
             sizeInBits += values.getList().size() * 64
         if EvaluationHelper.equals(dataType, "USINT") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # USINT
             # Simple Field (value)
             sizeInBits += 8
@@ -805,7 +805,7 @@ class DataItem:
             values: PlcList = _value
             sizeInBits += values.getList().size() * 8
         if EvaluationHelper.equals(dataType, "UINT") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # UINT
             # Simple Field (value)
             sizeInBits += 16
@@ -813,7 +813,7 @@ class DataItem:
             values: PlcList = _value
             sizeInBits += values.getList().size() * 16
         if EvaluationHelper.equals(dataType, "UDINT") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # UDINT
             # Simple Field (value)
             sizeInBits += 32
@@ -821,7 +821,7 @@ class DataItem:
             values: PlcList = _value
             sizeInBits += values.getList().size() * 32
         if EvaluationHelper.equals(dataType, "ULINT") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # ULINT
             # Simple Field (value)
             sizeInBits += 64
@@ -829,7 +829,7 @@ class DataItem:
             values: PlcList = _value
             sizeInBits += values.getList().size() * 64
         if EvaluationHelper.equals(dataType, "REAL") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # REAL
             # Simple Field (value)
             sizeInBits += 32
@@ -837,7 +837,7 @@ class DataItem:
             values: PlcList = _value
             sizeInBits += values.getList().size() * 32
         if EvaluationHelper.equals(dataType, "LREAL") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # LREAL
             # Simple Field (value)
             sizeInBits += 64
@@ -845,7 +845,7 @@ class DataItem:
             values: PlcList = _value
             sizeInBits += values.getList().size() * 64
         if EvaluationHelper.equals(dataType, "CHAR") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # CHAR
             # Simple Field (value)
             sizeInBits += 8
@@ -853,7 +853,7 @@ class DataItem:
             values: PlcList = _value
             sizeInBits += values.getList().size() * 8
         if EvaluationHelper.equals(dataType, "WCHAR") and EvaluationHelper.equals(
-            numberOfValues, 1
+            numberOfValues, c_uint16(1)
         ):  # WCHAR
             # Simple Field (value)
             sizeInBits += 16
diff --git a/sandbox/plc4py/plc4py/protocols/simulated/readwrite/Dummy.py b/sandbox/plc4py/plc4py/protocols/simulated/readwrite/Dummy.py
index 9f7050dd6b..7a4c5e59a5 100644
--- a/sandbox/plc4py/plc4py/protocols/simulated/readwrite/Dummy.py
+++ b/sandbox/plc4py/plc4py/protocols/simulated/readwrite/Dummy.py
@@ -21,6 +21,7 @@ from dataclasses import dataclass
 
 from ctypes import c_uint16
 from plc4py.api.messages.PlcMessage import PlcMessage
+from plc4py.spi.generation.WriteBuffer import WriteBuffer
 import math
 
 
@@ -32,17 +33,11 @@ class Dummy(PlcMessage):
         super().__init__()
 
     def serialize(self, write_buffer: WriteBuffer):
-        position_aware: PositionAware = write_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = write_buffer.get_pos()
         write_buffer.push_context("Dummy")
 
         # Simple Field (dummy)
-        write_simple_field(
-            "dummy",
-            self.dummy,
-            write_unsigned_int(write_buffer, 16),
-            WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN),
-        )
+        write_buffer.write_unsigned_short(self.dummy, logical_name="dummy")
 
         write_buffer.pop_context("Dummy")
 
@@ -59,20 +54,18 @@ class Dummy(PlcMessage):
         return length_in_bits
 
     def static_parse(read_buffer: ReadBuffer, args):
-        position_aware: PositionAware = read_buffer
         return staticParse(read_buffer)
 
     @staticmethod
     def static_parse_context(read_buffer: ReadBuffer):
         read_buffer.pull_context("Dummy")
-        position_aware: PositionAware = read_buffer
-        start_pos: int = position_aware.get_pos()
+        start_pos: int = read_buffer.get_pos()
         cur_pos: int = 0
 
         dummy: c_uint16 = read_simple_field(
             "dummy",
             read_unsigned_int(read_buffer, 16),
-            WithOption.WithByteOrder(ByteOrder.BIG_ENDIAN),
+            WithOption.WithByteOrder(get_bi_g__endian()),
         )
 
         read_buffer.close_context("Dummy")
diff --git a/sandbox/plc4py/plc4py/protocols/simulated/readwrite/SimulatedDataTypeSizes.py b/sandbox/plc4py/plc4py/protocols/simulated/readwrite/SimulatedDataTypeSizes.py
index fdcdd77e0e..928671c12e 100644
--- a/sandbox/plc4py/plc4py/protocols/simulated/readwrite/SimulatedDataTypeSizes.py
+++ b/sandbox/plc4py/plc4py/protocols/simulated/readwrite/SimulatedDataTypeSizes.py
@@ -19,10 +19,10 @@
 
 # Code generated by code-generation. DO NOT EDIT.
 from ctypes import c_uint8
-from enum import Enum
+from enum import IntEnum
 
 
-class SimulatedDataTypeSizes(Enum):
+class SimulatedDataTypeSizes(IntEnum):
     BOOL: c_uint8 = (1, c_uint8(1))
     BYTE: c_uint8 = (2, c_uint8(1))
     WORD: c_uint8 = (3, c_uint8(2))
@@ -51,7 +51,7 @@ class SimulatedDataTypeSizes(Enum):
     STRING: c_uint8 = (26, c_uint8(255))
     WSTRING: c_uint8 = (27, c_uint8(127))
 
-    def __new__(cls, value, dataTypeSize):
+    def __new__(cls, value, data_type_size):
         obj = object.__new__(cls)
         obj._value_ = value
         obj.dataTypeSize = dataTypeSize
diff --git a/sandbox/plc4py/plc4py/spi/generation/WriteBuffer.py b/sandbox/plc4py/plc4py/spi/generation/WriteBuffer.py
index 31fa7ed6e2..25c85c0c5b 100644
--- a/sandbox/plc4py/plc4py/spi/generation/WriteBuffer.py
+++ b/sandbox/plc4py/plc4py/spi/generation/WriteBuffer.py
@@ -14,8 +14,21 @@
 #  KIND, either express or implied.  See the License for the
 #  specific language governing permissions and limitations
 #  under the License.
-from ctypes import c_bool, c_byte, c_ubyte, c_uint16, c_uint32, c_uint64, c_int16, c_int32, c_int64, c_float, c_double, \
-    c_int8, c_uint8
+from ctypes import (
+    c_bool,
+    c_byte,
+    c_ubyte,
+    c_uint16,
+    c_uint32,
+    c_uint64,
+    c_int16,
+    c_int32,
+    c_int64,
+    c_float,
+    c_double,
+    c_int8,
+    c_uint8,
+)
 from dataclasses import dataclass
 from typing import List, Union
 
@@ -27,7 +40,6 @@ from plc4py.utils.GenericTypes import ByteOrder, ByteOrderAware
 
 
 class PositionAware:
-
     def get_pos(self) -> int:
         raise NotImplementedError
 
@@ -51,40 +63,64 @@ class WriteBuffer(ByteOrderAware, PositionAware):
     def write_byte(self, value: c_byte, logical_name: str = "", **kwargs) -> None:
         self.write_signed_byte(value, 8, logical_name, **kwargs)
 
-    def write_byte_array(self, value: List[c_byte], logical_name: str = "", **kwargs) -> None:
+    def write_byte_array(
+        self, value: List[c_byte], logical_name: str = "", **kwargs
+    ) -> None:
         raise NotImplementedError
 
-    def write_unsigned_byte(self, value: c_ubyte, bit_length: int = 8, logical_name: str = "", **kwargs) -> None:
+    def write_unsigned_byte(
+        self, value: c_uint8, bit_length: int = 8, logical_name: str = "", **kwargs
+    ) -> None:
         raise NotImplementedError
 
-    def write_unsigned_short(self, value: c_uint16, bit_length: int = 16, logical_name: str = "", **kwargs) -> None:
+    def write_unsigned_short(
+        self, value: c_uint16, bit_length: int = 16, logical_name: str = "", **kwargs
+    ) -> None:
         raise NotImplementedError
 
-    def write_unsigned_int(self, value: c_uint32, bit_length: int = 32, logical_name: str = "", **kwargs) -> None:
+    def write_unsigned_int(
+        self, value: c_uint32, bit_length: int = 32, logical_name: str = "", **kwargs
+    ) -> None:
         raise NotImplementedError
 
-    def write_unsigned_long(self, value: c_uint64, bit_length: int = 64, logical_name: str = "", **kwargs) -> None:
+    def write_unsigned_long(
+        self, value: c_uint64, bit_length: int = 64, logical_name: str = "", **kwargs
+    ) -> None:
         raise NotImplementedError
 
-    def write_signed_byte(self, value: c_int8, bit_length: int = 8, logical_name: str = "", **kwargs) -> None:
+    def write_signed_byte(
+        self, value: c_int8, bit_length: int = 8, logical_name: str = "", **kwargs
+    ) -> None:
         raise NotImplementedError
 
-    def write_short(self, value: c_int16, bit_length: int = 16, logical_name: str = "", **kwargs) -> None:
+    def write_short(
+        self, value: c_int16, bit_length: int = 16, logical_name: str = "", **kwargs
+    ) -> None:
         raise NotImplementedError
 
-    def write_int(self, value: c_int32, bit_length: int = 32, logical_name: str = "", **kwargs) -> None:
+    def write_int(
+        self, value: c_int32, bit_length: int = 32, logical_name: str = "", **kwargs
+    ) -> None:
         raise NotImplementedError
 
-    def write_long(self, value: c_int64, bit_length: int = 64, logical_name: str = "", **kwargs) -> None:
+    def write_long(
+        self, value: c_int64, bit_length: int = 64, logical_name: str = "", **kwargs
+    ) -> None:
         raise NotImplementedError
 
-    def write_float(self, value: c_float, bit_length: int = 32, logical_name: str = "", **kwargs) -> None:
+    def write_float(
+        self, value: c_float, bit_length: int = 32, logical_name: str = "", **kwargs
+    ) -> None:
         raise NotImplementedError
 
-    def write_double(self, value: c_double, bit_length: int = 64, logical_name: str = "", **kwargs) -> None:
+    def write_double(
+        self, value: c_double, bit_length: int = 64, logical_name: str = "", **kwargs
+    ) -> None:
         raise NotImplementedError
 
-    def write_str(self, value: str, bit_length: int = -1, logical_name: str = "", **kwargs) -> None:
+    def write_str(
+        self, value: str, bit_length: int = -1, logical_name: str = "", **kwargs
+    ) -> None:
         raise NotImplementedError
 
     def write_virtual(self, value: str, logical_name: str = "", **kwargs) -> None:
@@ -105,7 +141,19 @@ class WriteBufferByteBased(WriteBuffer):
     position: int = 0
     bb: bitarray
 
-    NUMERIC_UNION = Union[c_byte, c_uint8, c_uint16, c_uint32, c_uint64, c_int8, c_int16, c_int32, c_int64, c_float, c_double]
+    NUMERIC_UNION = Union[
+        c_byte,
+        c_uint8,
+        c_uint16,
+        c_uint32,
+        c_uint64,
+        c_int8,
+        c_int16,
+        c_int32,
+        c_int64,
+        c_float,
+        c_double,
+    ]
 
     def __init__(self, size: int, byte_order: ByteOrder):
         self.bb = zeros(size * 8, endian=ByteOrder.get_short_name(byte_order))
@@ -126,13 +174,17 @@ class WriteBufferByteBased(WriteBuffer):
         self.position += 1
 
     def write_byte(self, value: c_byte, logical_name: str = "", **kwargs) -> None:
-        self.write_signed_byte(value, logical_name, **kwargs)
+        self.write_signed_byte(value, 8, logical_name, **kwargs)
 
-    def write_byte_array(self, value: List[c_byte], logical_name: str = "", **kwargs) -> None:
+    def write_byte_array(
+        self, value: List[c_byte], logical_name: str = "", **kwargs
+    ) -> None:
         for a_byte in value:
-            self.write_signed_byte(a_byte, logical_name, **kwargs)
+            self.write_signed_byte(a_byte, 8, logical_name, **kwargs)
 
-    def write_unsigned_byte(self, value: c_byte, bit_length: int = 8, logical_name: str = "", **kwargs) -> None:
+    def write_unsigned_byte(
+        self, value: c_uint8, bit_length: int = 8, logical_name: str = "", **kwargs
+    ) -> None:
         if bit_length <= 0:
             raise SerializationException("unsigned byte must contain at least 1 bit")
         elif bit_length > 8:
@@ -140,7 +192,9 @@ class WriteBufferByteBased(WriteBuffer):
         else:
             self._handle_numeric_encoding(c_byte(value.value), bit_length, **kwargs)
 
-    def write_unsigned_short(self, value: c_uint16, bit_length: int = 16, logical_name: str = "", **kwargs) -> None:
+    def write_unsigned_short(
+        self, value: c_uint16, bit_length: int = 16, logical_name: str = "", **kwargs
+    ) -> None:
         if bit_length <= 0:
             raise SerializationException("unsigned short must contain at least 1 bit")
         elif bit_length > 16:
@@ -148,7 +202,9 @@ class WriteBufferByteBased(WriteBuffer):
         else:
             self._handle_numeric_encoding(c_uint16(value.value), bit_length, **kwargs)
 
-    def write_unsigned_int(self, value: c_uint32, bit_length: int = 32, logical_name: str = "", **kwargs) -> None:
+    def write_unsigned_int(
+        self, value: c_uint32, bit_length: int = 32, logical_name: str = "", **kwargs
+    ) -> None:
         if bit_length <= 0:
             raise SerializationException("unsigned int must contain at least 1 bit")
         elif bit_length > 32:
@@ -156,7 +212,9 @@ class WriteBufferByteBased(WriteBuffer):
         else:
             self._handle_numeric_encoding(c_uint32(value.value), bit_length, **kwargs)
 
-    def write_unsigned_long(self, value: c_uint64, bit_length: int = 64, logical_name: str = "", **kwargs) -> None:
+    def write_unsigned_long(
+        self, value: c_uint64, bit_length: int = 64, logical_name: str = "", **kwargs
+    ) -> None:
         if bit_length <= 0:
             raise SerializationException("unsigned long must contain at least 1 bit")
         elif bit_length > 64:
@@ -164,42 +222,54 @@ class WriteBufferByteBased(WriteBuffer):
         else:
             self._handle_numeric_encoding(c_uint64(value.value), bit_length, **kwargs)
 
-    def write_signed_byte(self, value: c_int8, bit_length: int = 8, logical_name: str = "", **kwargs) -> None:
+    def write_signed_byte(
+        self, value: c_int8, bit_length: int = 8, logical_name: str = "", **kwargs
+    ) -> None:
         if bit_length <= 0:
             raise SerializationException("Signed byte must contain at least 1 bit")
         elif bit_length > 8:
             raise SerializationException("Signed byte can only contain max 8 bits")
         self._handle_numeric_encoding(c_int8(value.value), bit_length, **kwargs)
 
-    def write_short(self, value: c_int16, bit_length: int = 16, logical_name: str = "", **kwargs) -> None:
+    def write_short(
+        self, value: c_int16, bit_length: int = 16, logical_name: str = "", **kwargs
+    ) -> None:
         if bit_length <= 0:
             raise SerializationException("Signed short must contain at least 1 bit")
         elif bit_length > 16:
             raise SerializationException("Signed short can only contain max 16 bits")
         self._handle_numeric_encoding(c_int16(value.value), bit_length, **kwargs)
 
-    def write_int(self, value: c_int32, bit_length: int = 32, logical_name: str = "", **kwargs) -> None:
+    def write_int(
+        self, value: c_int32, bit_length: int = 32, logical_name: str = "", **kwargs
+    ) -> None:
         if bit_length <= 0:
             raise SerializationException("Signed int must contain at least 1 bit")
         elif bit_length > 32:
             raise SerializationException("Signed int can only contain max 32 bits")
         self._handle_numeric_encoding(c_int32(value.value), bit_length, **kwargs)
 
-    def write_long(self, value: c_int64, bit_length: int = 64, logical_name: str = "", **kwargs) -> None:
+    def write_long(
+        self, value: c_int64, bit_length: int = 64, logical_name: str = "", **kwargs
+    ) -> None:
         if bit_length <= 0:
             raise SerializationException("Signed long must contain at least 1 bit")
         elif bit_length > 64:
             raise SerializationException("Signed long can only contain max 64 bits")
         self._handle_numeric_encoding(c_int64(value.value), bit_length, **kwargs)
 
-    def write_float(self, value: c_float, bit_length: int = 32, logical_name: str = "", **kwargs) -> None:
+    def write_float(
+        self, value: c_float, bit_length: int = 32, logical_name: str = "", **kwargs
+    ) -> None:
         if bit_length <= 0:
             raise SerializationException("Float must contain at least 1 bit")
         elif bit_length > 32:
             raise SerializationException("Float can only contain max 32 bits")
         self._handle_numeric_encoding(c_float(value.value), bit_length, **kwargs)
 
-    def write_double(self, value: c_double, bit_length: int = 64, logical_name: str = "", **kwargs) -> None:
+    def write_double(
+        self, value: c_double, bit_length: int = 64, logical_name: str = "", **kwargs
+    ) -> None:
         if bit_length <= 0:
             raise SerializationException("Double must contain at least 1 bit")
         elif bit_length > 64:
@@ -212,19 +282,24 @@ class WriteBufferByteBased(WriteBuffer):
         if value_encoding == "ASCII":
             if bit_length % 8 != 0:
                 raise SerializationException(
-                    "'ASCII' encoded fields must have a length that is a multiple of 8 bits long")
+                    "'ASCII' encoded fields must have a length that is a multiple of 8 bits long"
+                )
             char_len: int = int(bit_length / 8)
-            max_value: int = int(10 ** char_len - 1)
+            max_value: int = int(10**char_len - 1)
             if value.value > max_value:
                 raise SerializationException(
-                    "Provided value of " + str(value) + " exceeds the max value of " + str(max_value))
+                    "Provided value of "
+                    + str(value)
+                    + " exceeds the max value of "
+                    + str(max_value)
+                )
             string_value: str = "{}".format(value.value)
             src = bitarray(endian=ByteOrder.get_short_name(byte_order))
             src.frombytes(bytearray(string_value, value_encoding))
-            self.bb[self.position:bit_length] = src[:bit_length]
+            self.bb[self.position : bit_length] = src[:bit_length]
             self.position += bit_length
         elif value_encoding == "default":
             src = bitarray(endian=ByteOrder.get_short_name(byte_order))
             src.frombytes(value)
-            self.bb[self.position:bit_length] = src[:bit_length]
+            self.bb[self.position : bit_length] = src[:bit_length]
             self.position += bit_length
diff --git a/sandbox/plc4py/plc4py/spi/generation/__init__.py b/sandbox/plc4py/plc4py/spi/generation/__init__.py
index c3434ab60d..a67d5ea255 100644
--- a/sandbox/plc4py/plc4py/spi/generation/__init__.py
+++ b/sandbox/plc4py/plc4py/spi/generation/__init__.py
@@ -14,4 +14,3 @@
 #  KIND, either express or implied.  See the License for the
 #  specific language governing permissions and limitations
 #  under the License.
-
diff --git a/sandbox/plc4py/plc4py/spi/values/Common.py b/sandbox/plc4py/plc4py/spi/values/Common.py
index 886a61162e..a407235b3f 100644
--- a/sandbox/plc4py/plc4py/spi/values/Common.py
+++ b/sandbox/plc4py/plc4py/spi/values/Common.py
@@ -21,6 +21,5 @@ from plc4py.spi.generation import WriteBuffer
 
 
 class Serializable:
-
     def serialize(self, write_buffer: WriteBuffer):
-        pass
\ No newline at end of file
+        pass
diff --git a/sandbox/plc4py/setup.py b/sandbox/plc4py/setup.py
index 6543000684..8a7416a31e 100644
--- a/sandbox/plc4py/setup.py
+++ b/sandbox/plc4py/setup.py
@@ -44,7 +44,7 @@ setup(
         "black",
         "pip",
         "aenum",
-        "bitarray"
+        "bitarray",
     ],
     extras_require={
         "dev": [
diff --git a/sandbox/plc4py/tests/unit/plc4py/spi/test_write_buffer.py b/sandbox/plc4py/tests/unit/plc4py/spi/test_write_buffer.py
index af25806dfb..1c313ac4c6 100644
--- a/sandbox/plc4py/tests/unit/plc4py/spi/test_write_buffer.py
+++ b/sandbox/plc4py/tests/unit/plc4py/spi/test_write_buffer.py
@@ -29,34 +29,34 @@ from plc4py.utils.GenericTypes import ByteOrder
 def test_write_buffer_get_bytes(mocker) -> None:
     wb: WriteBufferByteBased = WriteBufferByteBased(10, ByteOrder.LITTLE_ENDIAN)
     ba: memoryview = wb.get_bytes()
-    assert(10 == ba.nbytes)
+    assert 10 == ba.nbytes
 
 
 def test_write_buffer_get_pos(mocker) -> None:
     wb: WriteBufferByteBased = WriteBufferByteBased(10, ByteOrder.LITTLE_ENDIAN)
     pos: int = wb.get_pos()
-    assert(0 == pos)
+    assert 0 == pos
 
 
 def test_write_buffer_set_bit_little_endian(mocker) -> None:
     wb: WriteBufferByteBased = WriteBufferByteBased(1, ByteOrder.LITTLE_ENDIAN)
     wb.write_bit(c_bool(True))
     ba: memoryview = wb.get_bytes()
-    assert(b'\x01' == ba.tobytes())
+    assert b"\x01" == ba.tobytes()
 
 
 def test_write_buffer_set_bit_big_endian(mocker) -> None:
     wb: WriteBufferByteBased = WriteBufferByteBased(1, ByteOrder.BIG_ENDIAN)
     wb.write_bit(c_bool(True))
     ba: memoryview = wb.get_bytes()
-    assert(b'\x80' == ba.tobytes())
+    assert b"\x80" == ba.tobytes()
 
 
 def test_write_buffer_set_bit_get_pos(mocker) -> None:
     wb: WriteBufferByteBased = WriteBufferByteBased(1, ByteOrder.LITTLE_ENDIAN)
     wb.write_bit(c_bool(True))
     pos: int = wb.get_pos()
-    assert(1 == pos)
+    assert 1 == pos
 
 
 def test_write_buffer_set_bit_x2_little_endian(mocker) -> None:
@@ -64,7 +64,7 @@ def test_write_buffer_set_bit_x2_little_endian(mocker) -> None:
     wb.write_bit(c_bool(True))
     wb.write_bit(c_bool(True))
     ba: memoryview = wb.get_bytes()
-    assert (b'\x03' == ba.tobytes())
+    assert b"\x03" == ba.tobytes()
 
 
 def test_write_buffer_set_bit_x2_big_endian(mocker) -> None:
@@ -72,7 +72,7 @@ def test_write_buffer_set_bit_x2_big_endian(mocker) -> None:
     wb.write_bit(c_bool(True))
     wb.write_bit(c_bool(True))
     ba: memoryview = wb.get_bytes()
-    assert (b'\xc0' == ba.tobytes())
+    assert b"\xc0" == ba.tobytes()
 
 
 def test_write_buffer_set_bit_get_pos_dual(mocker) -> None:
@@ -80,56 +80,56 @@ def test_write_buffer_set_bit_get_pos_dual(mocker) -> None:
     wb.write_bit(c_bool(True))
     wb.write_bit(c_bool(True))
     pos: int = wb.get_pos()
-    assert(pos == 2)
+    assert pos == 2
 
 
 def test_write_buffer_set_unsigned_byte_get_pos(mocker) -> None:
     wb: WriteBufferByteBased = WriteBufferByteBased(1, ByteOrder.LITTLE_ENDIAN)
     wb.write_unsigned_byte(c_byte(0xFF), 8)
     pos: int = wb.get_pos()
-    assert(pos == 8)
+    assert pos == 8
 
 
 def test_write_buffer_set_unsigned_byte_little_endian(mocker) -> None:
     wb: WriteBufferByteBased = WriteBufferByteBased(1, ByteOrder.LITTLE_ENDIAN)
     wb.write_unsigned_byte(c_byte(0x12), 8)
     ba: memoryview = wb.get_bytes()
-    assert (ba.obj == bitarray("01001000"))
+    assert ba.obj == bitarray("01001000")
 
 
 def test_write_buffer_set_unsigned_byte_big_endian(mocker) -> None:
     wb: WriteBufferByteBased = WriteBufferByteBased(1, ByteOrder.BIG_ENDIAN)
     wb.write_unsigned_byte(c_byte(0x12), 8)
     ba: memoryview = wb.get_bytes()
-    assert (ba.obj == bitarray("00010010"))
+    assert ba.obj == bitarray("00010010")
 
 
 def test_write_buffer_set_unsigned_byte_little_endian_niblet(mocker) -> None:
     wb: WriteBufferByteBased = WriteBufferByteBased(1, ByteOrder.LITTLE_ENDIAN)
     wb.write_unsigned_byte(c_byte(0x12), 4)
     ba: memoryview = wb.get_bytes()
-    assert (ba.obj == bitarray("01000000"))
+    assert ba.obj == bitarray("01000000")
 
 
 def test_write_buffer_set_unsigned_byte_big_endian_niblet(mocker) -> None:
     wb: WriteBufferByteBased = WriteBufferByteBased(1, ByteOrder.BIG_ENDIAN)
     wb.write_unsigned_byte(c_byte(0x12), 4)
     ba: memoryview = wb.get_bytes()
-    assert (ba.obj == bitarray("00010000"))
+    assert ba.obj == bitarray("00010000")
 
 
 def test_write_buffer_write_unsigned_short_little_endian(mocker) -> None:
     wb: WriteBufferByteBased = WriteBufferByteBased(2, ByteOrder.LITTLE_ENDIAN)
     wb.write_unsigned_short(c_uint16(0x12), 16)
     ba: memoryview = wb.get_bytes()
-    assert (ba.obj == bitarray("01001000 00000000", endian="little"))
+    assert ba.obj == bitarray("01001000 00000000", endian="little")
 
 
 def test_write_buffer_write_unsigned_short_big_endian(mocker) -> None:
     wb: WriteBufferByteBased = WriteBufferByteBased(2, ByteOrder.BIG_ENDIAN)
     wb.write_unsigned_short(c_uint16(0x12), 16)
     ba: memoryview = wb.get_bytes()
-    assert (ba.obj == bitarray("00010010 00000000", endian="big"))
+    assert ba.obj == bitarray("00010010 00000000", endian="big")
 
 
 def test_write_buffer_write_unsigned_short_little_endian_dual(mocker) -> None:
@@ -137,7 +137,7 @@ def test_write_buffer_write_unsigned_short_little_endian_dual(mocker) -> None:
     wb.write_unsigned_short(c_uint16(0x12), 16)
     wb.write_unsigned_short(c_uint16(0x34), 16)
     ba: memoryview = wb.get_bytes()
-    assert (ba.obj == bitarray("01001000 00000000 00101100 00000000", endian="little"))
+    assert ba.obj == bitarray("01001000 00000000 00101100 00000000", endian="little")
 
 
 def test_write_buffer_write_unsigned_short_big_endian_dual(mocker) -> None:
@@ -145,14 +145,14 @@ def test_write_buffer_write_unsigned_short_big_endian_dual(mocker) -> None:
     wb.write_unsigned_short(c_uint16(0x12), 16)
     wb.write_unsigned_short(c_uint16(0x34), 16)
     ba: memoryview = wb.get_bytes()
-    assert (ba.obj == bitarray("00010010 00000000 00110100 00000000", endian="big"))
+    assert ba.obj == bitarray("00010010 00000000 00110100 00000000", endian="big")
 
 
 def test_write_buffer_write_unsigned_short_big_endian_full(mocker) -> None:
     wb: WriteBufferByteBased = WriteBufferByteBased(2, ByteOrder.BIG_ENDIAN)
     wb.write_unsigned_short(c_uint16(-1), 16)
     ba: memoryview = wb.get_bytes()
-    assert (ba.obj == bitarray("11111111 11111111", endian="big"))
+    assert ba.obj == bitarray("11111111 11111111", endian="big")
 
 
 def test_write_buffer_write_unsigned_short_bit_big_endian_full(mocker) -> None:
@@ -161,21 +161,25 @@ def test_write_buffer_write_unsigned_short_bit_big_endian_full(mocker) -> None:
     wb.write_bit(c_bool(False))
     wb.write_unsigned_short(c_uint16(-1), 16)
     ba: memoryview = wb.get_bytes()
-    assert (ba.obj == bitarray("10 11111111 11111111", endian="big"))
+    assert ba.obj == bitarray("10 11111111 11111111", endian="big")
 
 
 def test_write_buffer_write_unsigned_short_ascii_encoding_little_endian(mocker) -> None:
     wb: WriteBufferByteBased = WriteBufferByteBased(2, ByteOrder.LITTLE_ENDIAN)
-    wb.write_unsigned_short(c_uint16(1), 16, "ASCII Value of 1 - 0x31", encoding="ASCII")
+    wb.write_unsigned_short(
+        c_uint16(1), 16, "ASCII Value of 1 - 0x31", encoding="ASCII"
+    )
     ba: memoryview = wb.get_bytes()
-    assert (ba.obj == bitarray("10001100", endian="little"))
+    assert ba.obj == bitarray("10001100", endian="little")
 
 
 def test_write_buffer_write_unsigned_short_ascii_encoding_big_endian(mocker) -> None:
     wb: WriteBufferByteBased = WriteBufferByteBased(2, ByteOrder.BIG_ENDIAN)
-    wb.write_unsigned_short(c_uint16(1), 16, "ASCII Value of 1 - 0x31", encoding="ASCII")
+    wb.write_unsigned_short(
+        c_uint16(1), 16, "ASCII Value of 1 - 0x31", encoding="ASCII"
+    )
     ba: memoryview = wb.get_bytes()
-    assert (ba.obj == bitarray("00110001", endian="big"))
+    assert ba.obj == bitarray("00110001", endian="big")
 
 
 def test_write_buffer_write_unsigned_int_little_endian(mocker) -> None:
@@ -183,7 +187,7 @@ def test_write_buffer_write_unsigned_int_little_endian(mocker) -> None:
     # Testing incompatible format being sent to it.
     wb.write_unsigned_int(c_uint16(0x12), 32)
     ba: memoryview = wb.get_bytes()
-    assert (ba.obj == bitarray("01001000 00000000 00000000 00000000", endian="little"))
+    assert ba.obj == bitarray("01001000 00000000 00000000 00000000", endian="little")
 
 
 def test_write_buffer_write_unsigned_int_big_endian(mocker) -> None:
@@ -191,62 +195,82 @@ def test_write_buffer_write_unsigned_int_big_endian(mocker) -> None:
     # Testing incompatible format being sent to it.
     wb.write_unsigned_int(c_uint16(0x12), 32)
     ba: memoryview = wb.get_bytes()
-    assert (ba.obj == bitarray("00010010 00000000 00000000 00000000", endian="big"))
+    assert ba.obj == bitarray("00010010 00000000 00000000 00000000", endian="big")
 
 
 def test_write_buffer_write_unsigned_long_little_endian(mocker) -> None:
     wb: WriteBufferByteBased = WriteBufferByteBased(2, ByteOrder.LITTLE_ENDIAN)
     wb.write_unsigned_long(c_uint64(0x12), 64)
     ba: memoryview = wb.get_bytes()
-    assert (ba.obj == bitarray("01001000 00000000 00000000 00000000 00000000 00000000 00000000 00000000", endian="little"))
+    assert ba.obj == bitarray(
+        "01001000 00000000 00000000 00000000 00000000 00000000 00000000 00000000",
+        endian="little",
+    )
 
 
 def test_write_buffer_write_unsigned_long_big_endian(mocker) -> None:
     wb: WriteBufferByteBased = WriteBufferByteBased(2, ByteOrder.BIG_ENDIAN)
     wb.write_unsigned_long(c_uint64(0x12), 64)
     ba: memoryview = wb.get_bytes()
-    assert (ba.obj == bitarray("00010010 00000000 00000000 00000000 00000000 00000000 00000000 00000000", endian="big"))
+    assert ba.obj == bitarray(
+        "00010010 00000000 00000000 00000000 00000000 00000000 00000000 00000000",
+        endian="big",
+    )
 
 
 def test_write_buffer_write_unsigned_long_ascii_encoding_little_endian(mocker) -> None:
     wb: WriteBufferByteBased = WriteBufferByteBased(8, ByteOrder.LITTLE_ENDIAN)
-    wb.write_unsigned_long(c_uint64(11111111), 64, "ASCII Value of 1111 1111 - 0x3131313131313131", encoding="ASCII")
+    wb.write_unsigned_long(
+        c_uint64(11111111),
+        64,
+        "ASCII Value of 1111 1111 - 0x3131313131313131",
+        encoding="ASCII",
+    )
     ba: memoryview = wb.get_bytes()
-    assert (ba.obj == bitarray("10001100 10001100 10001100 10001100 10001100 10001100 10001100 10001100", endian="little"))
+    assert ba.obj == bitarray(
+        "10001100 10001100 10001100 10001100 10001100 10001100 10001100 10001100",
+        endian="little",
+    )
 
 
 def test_write_buffer_write_unsigned_long_ascii_encoding_big_endian(mocker) -> None:
     wb: WriteBufferByteBased = WriteBufferByteBased(8, ByteOrder.BIG_ENDIAN)
-    wb.write_unsigned_long(c_uint64(11111111), 64, "ASCII Value of 1111 1111 - 0x3131313131313131", encoding="ASCII")
+    wb.write_unsigned_long(
+        c_uint64(11111111),
+        64,
+        "ASCII Value of 1111 1111 - 0x3131313131313131",
+        encoding="ASCII",
+    )
     ba: memoryview = wb.get_bytes()
-    assert (ba.obj == bitarray("00110001 00110001 00110001 00110001 00110001 00110001 00110001 00110001", endian="big"))
+    assert ba.obj == bitarray(
+        "00110001 00110001 00110001 00110001 00110001 00110001 00110001 00110001",
+        endian="big",
+    )
 
 
 def test_write_buffer_set_signed_byte(mocker) -> None:
     wb: WriteBufferByteBased = WriteBufferByteBased(1, ByteOrder.LITTLE_ENDIAN)
     wb.write_signed_byte(c_int8(-1), 8)
     ba: memoryview = wb.get_bytes()
-    assert (ba.obj == bitarray("11111111",
-                               endian="little"))
+    assert ba.obj == bitarray("11111111", endian="little")
 
 
 def test_write_buffer_set_signed_byte_three(mocker) -> None:
     wb: WriteBufferByteBased = WriteBufferByteBased(1, ByteOrder.LITTLE_ENDIAN)
     wb.write_signed_byte(c_int8(3), 8)
     ba: memoryview = wb.get_bytes()
-    assert (ba.obj == bitarray("11000000",
-                               endian="little"))
+    assert ba.obj == bitarray("11000000", endian="little")
+
 
 def test_write_buffer_set_float_little_endian(mocker) -> None:
     wb: WriteBufferByteBased = WriteBufferByteBased(1, ByteOrder.LITTLE_ENDIAN)
     wb.write_float(c_float(-1), 32)
     ba: memoryview = wb.get_bytes()
-    assert (ba.obj == bitarray("00000000000000000000000111111101",
-                               endian="little"))
+    assert ba.obj == bitarray("00000000000000000000000111111101", endian="little")
+
 
 def test_write_buffer_set_float_big_endian(mocker) -> None:
     wb: WriteBufferByteBased = WriteBufferByteBased(1, ByteOrder.BIG_ENDIAN)
     wb.write_float(c_float(-1), 32)
     ba: memoryview = wb.get_bytes()
-    assert (ba.obj == bitarray("00000000000000001000000010111111",
-                               endian="big"))
+    assert ba.obj == bitarray("00000000000000001000000010111111", endian="big")


[plc4x] 03/03: Merge remote-tracking branch 'origin/develop' into develop

Posted by hu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

hutcheb pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit e8baa8e27f0642d7c69bf038440e39ec503401d7
Merge: 3cbd8f52e0 d89e40f73f
Author: Ben Hutcheson <be...@gmail.com>
AuthorDate: Wed May 17 06:10:23 2023 +0200

    Merge remote-tracking branch 'origin/develop' into develop

 .asf.yaml                                          |    9 +
 code-generation/language-base-freemarker/pom.xml   |    4 +
 code-generation/protocol-base-mspec/pom.xml        |    9 +-
 .../src/test/resources/logback-test.xml            |    2 +-
 .../apache/plc4x/java/test/readwrite/EnumType.java |    2 +-
 .../plc4x/java/test/readwrite/EnumTypeBit.java     |    2 +-
 .../plc4x/java/test/readwrite/EnumTypeInt.java     |    2 +-
 .../java/test/readwrite/EnumTypeParameters.java    |   22 +-
 plc4go/assets/testing/logback-test.xml             |    2 +-
 plc4go/examples/ads/discovery/Discovery.go         |    4 +-
 plc4go/examples/ads/subscribe/Subscribe.go         |    5 +-
 .../hello_world_plc4go_bacnet_discovery.go         |   10 +-
 .../discovery/hello_world_plc4go_knx_discovery.go  |   11 +-
 .../hello_world_plc4go_knx_read_group_address.go   |    4 +-
 .../hello_world_plc4go_knx_subscription.go         |   20 +-
 plc4go/examples/read/hello_world_plc4go_read.go    |    4 +-
 plc4go/examples/write/hello_world_plc4go_write.go  |    4 +-
 plc4go/internal/ads/Browser.go                     |   40 +-
 plc4go/internal/ads/Connection.go                  |   69 +-
 plc4go/internal/ads/Discoverer.go                  |   18 +-
 plc4go/internal/ads/Driver.go                      |    4 +-
 plc4go/internal/ads/DriverContext.go               |   32 +-
 plc4go/internal/ads/Interactions.go                |   12 +-
 plc4go/internal/ads/Reader.go                      |   95 +-
 plc4go/internal/ads/Subscriber.go                  |   61 +-
 plc4go/internal/ads/TagHandler.go                  |   26 +-
 plc4go/internal/ads/TagHandler_test.go             |  188 +-
 plc4go/internal/ads/ValueHandler.go                |   29 +-
 plc4go/internal/ads/Writer.go                      |   99 +-
 plc4go/internal/ads/mock_SymbolicPlcQuery_test.go  |    2 +-
 plc4go/internal/ads/model/AdsSubscriptionHandle.go |   12 +-
 plc4go/internal/ads/model/Tag.go                   |   43 +-
 plc4go/internal/bacnetip/Connection.go             |    8 +-
 plc4go/internal/bacnetip/Discoverer.go             |   36 +-
 plc4go/internal/bacnetip/Driver.go                 |   18 +-
 plc4go/internal/bacnetip/Reader.go                 |   45 +-
 plc4go/internal/bacnetip/Subscriber.go             |   18 +-
 plc4go/internal/bacnetip/Tag.go                    |   14 +-
 plc4go/internal/bacnetip/TagHandler.go             |    7 +-
 plc4go/internal/bacnetip/mock_BacNetPlcTag_test.go |    2 +-
 .../bacnetip/mock_OneShotTaskRequirements_test.go  |    2 +-
 plc4go/internal/bacnetip/mock_PDUOption_test.go    |    2 +-
 .../mock_RecurringTaskRequirements_test.go         |    2 +-
 .../mock_SSMProcessingRequirements_test.go         |    2 +-
 .../bacnetip/mock_SSMSAPRequirements_test.go       |    2 +-
 .../mock_WhoIsIAmServicesRequirements_test.go      |    2 +-
 .../mock__ApplicationServiceElement_test.go        |    2 +-
 plc4go/internal/bacnetip/mock__BIPSAP_test.go      |    2 +-
 plc4go/internal/bacnetip/mock__Client_test.go      |    2 +-
 plc4go/internal/bacnetip/mock__IOCB_test.go        |    2 +-
 .../internal/bacnetip/mock__IOController_test.go   |    2 +-
 .../internal/bacnetip/mock__IOQController_test.go  |    2 +-
 plc4go/internal/bacnetip/mock__PDU_test.go         |    2 +-
 plc4go/internal/bacnetip/mock__Server_test.go      |    2 +-
 .../bacnetip/mock__ServiceAccessPoint_test.go      |    2 +-
 .../bacnetip/mock__TaskRequirements_test.go        |    2 +-
 plc4go/internal/bacnetip/mock_option_test.go       |    2 +-
 plc4go/internal/cbus/Browser.go                    |   18 +-
 plc4go/internal/cbus/Connection.go                 |   10 +-
 plc4go/internal/cbus/Discoverer.go                 |   17 +-
 plc4go/internal/cbus/Reader.go                     |   34 +-
 plc4go/internal/cbus/Subscriber.go                 |   15 +-
 plc4go/internal/cbus/Writer.go                     |   42 +-
 plc4go/internal/cbus/mock_CALGetStatusTag_test.go  |    2 +-
 plc4go/internal/cbus/mock_CALIdentifyTag_test.go   |    2 +-
 plc4go/internal/cbus/mock_CALRecallTag_test.go     |    2 +-
 plc4go/internal/cbus/mock_CalTag_test.go           |    2 +-
 .../cbus/mock_CommandAndArgumentsCount_test.go     |    2 +-
 plc4go/internal/cbus/mock_MMIMonitorTag_test.go    |    2 +-
 .../internal/cbus/mock_RequestTransaction_test.go  |    2 +-
 plc4go/internal/cbus/mock_SALMonitorTag_test.go    |    2 +-
 plc4go/internal/cbus/mock_SALTag_test.go           |    2 +-
 plc4go/internal/cbus/mock_StatusTag_test.go        |    2 +-
 plc4go/internal/cbus/mock_Tag_test.go              |    2 +-
 plc4go/internal/cbus/mock_UnitInfoQuery_test.go    |    2 +-
 plc4go/internal/cbus/mock_addressProvider_test.go  |    2 +-
 plc4go/internal/eip/Connection.go                  |   10 +-
 plc4go/internal/eip/Reader.go                      |   39 +-
 plc4go/internal/eip/Tag.go                         |   26 +-
 plc4go/internal/eip/TagHandler.go                  |    6 +-
 plc4go/internal/eip/Writer.go                      |   40 +-
 plc4go/internal/eip/mock_EIPPlcTag_test.go         |    2 +-
 plc4go/internal/knxnetip/Browser.go                |   49 +-
 plc4go/internal/knxnetip/Connection.go             |    6 +-
 .../knxnetip/ConnectionDriverSpecificOperations.go |   14 +-
 .../knxnetip/ConnectionInternalOperations.go       |   48 +-
 plc4go/internal/knxnetip/Discoverer.go             |   17 +-
 plc4go/internal/knxnetip/Reader.go                 |   12 +-
 plc4go/internal/knxnetip/Subscriber.go             |   16 +-
 plc4go/internal/knxnetip/SubscriptionEvent.go      |   10 +-
 plc4go/internal/knxnetip/ValueHandler.go           |    6 +-
 plc4go/internal/knxnetip/Writer.go                 |   20 +-
 plc4go/internal/knxnetip/mock_DeviceTag_test.go    |    2 +-
 .../internal/knxnetip/mock_GroupAddressTag_test.go |    2 +-
 plc4go/internal/knxnetip/mock_Tag_test.go          |    2 +-
 plc4go/internal/modbus/Connection.go               |    2 +-
 plc4go/internal/modbus/Reader.go                   |   84 +-
 plc4go/internal/modbus/Tag.go                      |   33 +-
 plc4go/internal/modbus/TagHandler.go               |   29 +-
 plc4go/internal/modbus/Writer.go                   |   59 +-
 plc4go/internal/s7/Connection.go                   |   20 +-
 plc4go/internal/s7/Reader.go                       |   82 +-
 plc4go/internal/s7/Tag.go                          |   22 +-
 plc4go/internal/s7/TagHandler.go                   |    7 +-
 plc4go/internal/s7/Writer.go                       |   37 +-
 plc4go/internal/s7/mock_PlcTag_test.go             |    2 +-
 plc4go/internal/simulated/Connection.go            |   20 +-
 plc4go/internal/simulated/Connection_test.go       |   14 +-
 plc4go/internal/simulated/Driver_test.go           |    4 +-
 plc4go/internal/simulated/Reader.go                |   28 +-
 plc4go/internal/simulated/Reader_test.go           |   86 +-
 plc4go/internal/simulated/Subscriber.go            |   12 +-
 plc4go/internal/simulated/TagHandler_test.go       |   18 +-
 plc4go/internal/simulated/ValueHandler.go          |    6 +-
 plc4go/internal/simulated/Writer.go                |   18 +-
 plc4go/internal/simulated/Writer_test.go           |  108 +-
 plc4go/internal/simulated/mock_Tag_test.go         |    2 +-
 .../mock_PlcConnectionCacheCloseResult_test.go     |    2 +-
 .../pkg/api/cache/mock_PlcConnectionCache_test.go  |    2 +-
 .../cache/mock_WithConnectionCacheOption_test.go   |    2 +-
 plc4go/pkg/api/cache/mock_connectionEvent_test.go  |    2 +-
 .../pkg/api/cache/mock_connectionListener_test.go  |    2 +-
 .../pkg/api/cache/mock_tracedPlcConnection_test.go |    2 +-
 plc4go/pkg/api/cache/plcConnectionLease.go         |   17 +-
 plc4go/pkg/api/cache/plcConnectionLease_test.go    |   28 +
 plc4go/pkg/api/connection.go                       |    1 +
 plc4go/pkg/api/driverManager.go                    |    4 +-
 .../pkg/api/mock_PlcConnectionCloseResult_test.go  |    2 +-
 .../api/mock_PlcConnectionConnectResult_test.go    |    2 +-
 .../pkg/api/mock_PlcConnectionPingResult_test.go   |    2 +-
 plc4go/pkg/api/mock_PlcConnection_test.go          |    2 +-
 plc4go/pkg/api/mock_PlcDriverManager_test.go       |    2 +-
 plc4go/pkg/api/mock_PlcDriver_test.go              |    2 +-
 plc4go/pkg/api/mock_WithDiscoveryOption_test.go    |    2 +-
 plc4go/pkg/api/model/mock_ArrayInfo_test.go        |    2 +-
 plc4go/pkg/api/model/mock_PlcBrowseItem_test.go    |    2 +-
 .../api/model/mock_PlcBrowseRequestBuilder_test.go |    2 +-
 .../api/model/mock_PlcBrowseRequestResult_test.go  |    2 +-
 plc4go/pkg/api/model/mock_PlcBrowseRequest_test.go |    2 +-
 .../pkg/api/model/mock_PlcBrowseResponse_test.go   |    2 +-
 .../api/model/mock_PlcConnectionMetadata_test.go   |    2 +-
 .../api/model/mock_PlcConsumerRegistration_test.go |    2 +-
 plc4go/pkg/api/model/mock_PlcDiscoveryItem_test.go |    2 +-
 plc4go/pkg/api/model/mock_PlcMessage_test.go       |    2 +-
 plc4go/pkg/api/model/mock_PlcQuery_test.go         |    2 +-
 .../api/model/mock_PlcReadRequestBuilder_test.go   |    2 +-
 .../api/model/mock_PlcReadRequestResult_test.go    |    2 +-
 plc4go/pkg/api/model/mock_PlcReadRequest_test.go   |    2 +-
 plc4go/pkg/api/model/mock_PlcReadResponse_test.go  |    2 +-
 plc4go/pkg/api/model/mock_PlcRequest_test.go       |    2 +-
 plc4go/pkg/api/model/mock_PlcResponse_test.go      |    2 +-
 .../mock_PlcSubscriptionEventConsumer_test.go      |    2 +-
 .../api/model/mock_PlcSubscriptionEvent_test.go    |    2 +-
 .../api/model/mock_PlcSubscriptionHandle_test.go   |    2 +-
 .../mock_PlcSubscriptionRequestBuilder_test.go     |    2 +-
 .../mock_PlcSubscriptionRequestResult_test.go      |    2 +-
 .../api/model/mock_PlcSubscriptionRequest_test.go  |    2 +-
 .../api/model/mock_PlcSubscriptionResponse_test.go |    2 +-
 plc4go/pkg/api/model/mock_PlcTag_test.go           |    2 +-
 .../mock_PlcUnsubscriptionRequestBuilder_test.go   |    2 +-
 .../mock_PlcUnsubscriptionRequestResult_test.go    |    2 +-
 .../model/mock_PlcUnsubscriptionRequest_test.go    |    2 +-
 .../model/mock_PlcUnsubscriptionResponse_test.go   |    2 +-
 .../api/model/mock_PlcWriteRequestBuilder_test.go  |    2 +-
 .../api/model/mock_PlcWriteRequestResult_test.go   |    2 +-
 plc4go/pkg/api/model/mock_PlcWriteRequest_test.go  |    2 +-
 plc4go/pkg/api/model/mock_PlcWriteResponse_test.go |    2 +-
 plc4go/pkg/api/values/mock_PlcValue_test.go        |    2 +-
 plc4go/pkg/api/values/mock_RawPlcValue_test.go     |    2 +-
 .../knxnetip/readwrite/model/KnxManufacturer.go    |   40 +-
 plc4go/spi/default/DefaultBrowser.go               |   16 +-
 plc4go/spi/default/DefaultConnection.go            |   18 +-
 plc4go/spi/default/DefaultConnection_test.go       |   22 +-
 .../mock_DefaultBrowserRequirements_test.go        |    2 +-
 plc4go/spi/default/mock_DefaultBrowser_test.go     |    2 +-
 .../default/mock_DefaultCodecRequirements_test.go  |    2 +-
 plc4go/spi/default/mock_DefaultCodec_test.go       |    2 +-
 .../mock_DefaultConnectionRequirements_test.go     |    2 +-
 plc4go/spi/default/mock_DefaultConnection_test.go  |    2 +-
 .../default/mock_DefaultDriverRequirements_test.go |    2 +-
 plc4go/spi/default/mock_DefaultDriver_test.go      |    2 +-
 .../mock_DefaultPlcConnectionCloseResult_test.go   |    2 +-
 .../mock_DefaultPlcConnectionConnectResult_test.go |    2 +-
 .../mock_DefaultPlcConnectionPingResult_test.go    |    2 +-
 plc4go/spi/default/mock_MessageCodec_test.go       |    2 +-
 plc4go/spi/default/mock_Message_test.go            |    2 +-
 .../mock_PlcConnectionConnectResult_test.go        |    2 +-
 plc4go/spi/default/mock_PlcConnection_test.go      |    2 +-
 plc4go/spi/default/mock_PlcQuery_test.go           |    2 +-
 plc4go/spi/default/mock_PlcTagHandler_test.go      |    2 +-
 plc4go/spi/default/mock_TransportInstance_test.go  |    2 +-
 plc4go/spi/interceptors/RequestInterceptor.go      |   11 +-
 .../interceptors/mock_PlcReadRequestResult_test.go |    2 +-
 .../spi/interceptors/mock_PlcReadRequest_test.go   |    2 +-
 .../spi/interceptors/mock_PlcReadResponse_test.go  |    2 +-
 .../mock_PlcWriteRequestResult_test.go             |    2 +-
 .../spi/interceptors/mock_PlcWriteRequest_test.go  |    2 +-
 .../spi/interceptors/mock_PlcWriteResponse_test.go |    2 +-
 .../mock_ReadRequestInterceptorExposer_test.go     |    2 +-
 .../mock_ReadRequestInterceptor_test.go            |    2 +-
 plc4go/spi/interceptors/mock_ReaderExposer_test.go |    2 +-
 .../interceptors/mock_RequestInterceptor_test.go   |    2 +-
 .../mock_WriteRequestInterceptorExposer_test.go    |    2 +-
 .../mock_WriteRequestInterceptor_test.go           |    2 +-
 plc4go/spi/interceptors/mock_WriterExposer_test.go |    2 +-
 .../interceptors/mock_readRequestFactory_test.go   |    2 +-
 .../interceptors/mock_readResponseFactory_test.go  |    2 +-
 .../interceptors/mock_writeRequestFactory_test.go  |    2 +-
 .../interceptors/mock_writeResponseFactory_test.go |    2 +-
 plc4go/spi/mock_AcceptsMessage_test.go             |    2 +-
 plc4go/spi/mock_CompletableFuture_test.go          |    2 +-
 plc4go/spi/mock_CompletionFuture_test.go           |    2 +-
 plc4go/spi/mock_Expectation_test.go                |    2 +-
 plc4go/spi/mock_HandleError_test.go                |    2 +-
 plc4go/spi/mock_HandleMessage_test.go              |    2 +-
 plc4go/spi/mock_HandlerExposer_test.go             |    2 +-
 plc4go/spi/mock_MessageCodec_test.go               |    2 +-
 plc4go/spi/mock_Message_test.go                    |    2 +-
 plc4go/spi/mock_PlcBrowser_test.go                 |    2 +-
 plc4go/spi/mock_PlcDiscoverer_test.go              |    2 +-
 plc4go/spi/mock_PlcReader_test.go                  |    2 +-
 plc4go/spi/mock_PlcSubscriber_test.go              |    2 +-
 plc4go/spi/mock_PlcTagHandler_test.go              |    2 +-
 plc4go/spi/mock_PlcValueHandler_test.go            |    2 +-
 plc4go/spi/mock_PlcWriter_test.go                  |    2 +-
 .../mock_RequestTransactionManagerOption_test.go   |    2 +-
 plc4go/spi/mock_RequestTransactionManager_test.go  |    2 +-
 plc4go/spi/mock_RequestTransactionRunnable_test.go |    2 +-
 plc4go/spi/mock_RequestTransaction_test.go         |    2 +-
 plc4go/spi/mock_TracerProvider_test.go             |    2 +-
 plc4go/spi/mock_TransportAware_test.go             |    2 +-
 plc4go/spi/mock_TransportInstanceExposer_test.go   |    2 +-
 plc4go/spi/model/DefaultPlcBrowseRequest_test.go   |  154 +-
 plc4go/spi/model/DefaultPlcReadRequest.go          |    4 +-
 plc4go/spi/model/DefaultPlcReadRequest_test.go     |  590 +++
 .../spi/model/DefaultPlcSubscriptionEventItem.go   |   18 +-
 .../model/DefaultPlcSubscriptionRequest_test.go    |  806 ++++
 plc4go/spi/model/DefaultPlcSubscriptionResponse.go |   18 +-
 .../model/DefaultPlcSubscriptionResponse_test.go   |  309 ++
 .../spi/model/DefaultPlcUnsubscriptionRequest.go   |    7 +-
 plc4go/spi/model/DefaultPlcWriteRequest.go         |    7 +-
 plc4go/spi/model/DefaultPlcWriteRequest_test.go    |  747 ++++
 plc4go/spi/model/DefaultPlcWriteResponse_test.go   |  141 +
 ...DefaultPlcSubscriptionEventRequirements_test.go |    2 +-
 plc4go/spi/model/mock_PlcBrowseItem_test.go        |    2 +-
 plc4go/spi/{ => model}/mock_PlcBrowser_test.go     |   45 +-
 plc4go/spi/model/mock_PlcQuery_test.go             |    2 +-
 plc4go/spi/{ => model}/mock_PlcReader_test.go      |   25 +-
 plc4go/spi/{ => model}/mock_PlcSubscriber_test.go  |   73 +-
 plc4go/spi/model/mock_PlcTagHandler_test.go        |    2 +-
 plc4go/spi/model/mock_PlcTag_test.go               |    2 +-
 .../spi/{ => model}/mock_PlcValueHandler_test.go   |   22 +-
 plc4go/spi/{ => model}/mock_PlcWriter_test.go      |   25 +-
 .../mock_ReadRequestInterceptor_test.go            |   45 +-
 .../mock_WriteRequestInterceptor_test.go           |   45 +-
 plc4go/spi/model/mock_requirements.go              |   36 +
 .../options/mock_DiscoveryOptionDeviceName_test.go |    2 +-
 .../mock_DiscoveryOptionLocalAddress_test.go       |    2 +-
 .../mock_DiscoveryOptionProtocolSpecific_test.go   |    2 +-
 .../options/mock_DiscoveryOptionProtocol_test.go   |    2 +-
 .../mock_DiscoveryOptionRemoteAddress_test.go      |    2 +-
 .../options/mock_DiscoveryOptionTransport_test.go  |    2 +-
 .../spi/options/mock_WithDiscoveryOption_test.go   |    2 +-
 plc4go/spi/options/mock_WithOption_test.go         |    2 +-
 plc4go/spi/testutils/ManualTestRunner.go           |   16 +-
 .../mock_ConnectionConnectAwaiter_test.go          |    2 +-
 plc4go/spi/testutils/mock_Parser_test.go           |    2 +-
 .../testutils/mock_TestTransportInstance_test.go   |    2 +-
 plc4go/spi/testutils/mock_WithOption_test.go       |    2 +-
 .../spi/testutils/mock_WithTestCaseOption_test.go  |    2 +-
 plc4go/spi/testutils/mock_XmlParser_test.go        |    2 +-
 ...ltBufferedTransportInstanceRequirements_test.go |    2 +-
 .../mock_DefaultBufferedTransportInstance_test.go  |    2 +-
 .../spi/transports/mock_TransportInstance_test.go  |    2 +-
 plc4go/spi/transports/mock_Transport_test.go       |    2 +-
 plc4go/spi/transports/utils/mock_Option_test.go    |    2 +-
 plc4go/spi/utils/Net.go                            |    2 +-
 plc4go/spi/utils/WorkerPool.go                     |   78 +-
 plc4go/spi/utils/WorkerPool_test.go                |  208 +-
 plc4go/spi/utils/mock_AsciiBoxWriter_test.go       |    2 +-
 plc4go/spi/utils/mock_AsciiBoxer_test.go           |    2 +-
 plc4go/spi/utils/mock_CompletionFuture_test.go     |    2 +-
 plc4go/spi/utils/mock_ErrorIdentify_test.go        |    2 +-
 plc4go/spi/utils/mock_ExecutorOption_test.go       |    2 +-
 plc4go/spi/utils/mock_Executor_test.go             |    2 +-
 plc4go/spi/utils/mock_LengthAware_test.go          |    2 +-
 plc4go/spi/utils/mock_PositionAware_test.go        |    2 +-
 plc4go/spi/utils/mock_ReadBufferByteBased_test.go  |    2 +-
 plc4go/spi/utils/mock_ReadBuffer_test.go           |    2 +-
 plc4go/spi/utils/mock_Runnable_test.go             |    2 +-
 plc4go/spi/utils/mock_Serializable_test.go         |    2 +-
 plc4go/spi/utils/mock_WithReaderArgs_test.go       |    2 +-
 plc4go/spi/utils/mock_WithReaderWriterArgs_test.go |    2 +-
 plc4go/spi/utils/mock_WithWriterArgs_test.go       |    2 +-
 plc4go/spi/utils/mock_WriteBufferBoxBased_test.go  |    2 +-
 plc4go/spi/utils/mock_WriteBufferByteBased_test.go |    2 +-
 plc4go/spi/utils/mock_WriteBufferJsonBased_test.go |    2 +-
 plc4go/spi/utils/mock_WriteBufferXmlBased_test.go  |    2 +-
 plc4go/spi/utils/mock_WriteBuffer_test.go          |    2 +-
 plc4go/spi/values/PlcValueHandler.go               |   76 +-
 .../values/mock_WriteBufferPlcValueBased_test.go   |    2 +-
 .../drivers/tests/manual_bacnet_PcapTest_test.go   |    4 +-
 .../tests/drivers/tests/manual_cbus_driver_test.go |   10 +-
 plc4go/tools/plc4xbrowser/ui/commands.go           |    9 +-
 plc4go/tools/plc4xbrowser/ui/ui.go                 |   12 +-
 .../internal/common/mock_FilteredPackage_test.go   |    2 +-
 plc4go/tools/plc4xpcapanalyzer/ui/common.go        |   12 +-
 plc4go/tools/plc4xpcapanalyzer/ui/ui.go            |   14 +-
 .../bacnet/src/test/resources/logback-test.xml     |    2 +-
 .../c-bus/src/test/resources/logback-test.xml      |    2 +-
 .../eip/src/test/resources/logback-test.xml        |    2 +-
 .../java/knxnetip/readwrite/KnxManufacturer.java   |    6 +-
 .../modbus/src/test/resources/logback-test.xml     |    2 +-
 .../src/test/resources/logback-test.xml            |    2 +-
 plc4j/drivers/plc4x/pom.xml                        |    4 +
 plc4j/drivers/profinet/pom.xml                     |   17 +-
 .../profinet/src/test/resources/logback-test.xml   |    2 +-
 .../src/main/resources/logback.xml                 |    2 +-
 .../src/main/resources/logback.xml                 |    2 +-
 plc4j/examples/hello-connectivity-mqtt/pom.xml     |    9 +-
 .../hello-nats/src/main/resources/logback.xml      |    2 +-
 .../src/main/resources/logback.xml                 |    2 +-
 .../src/main/resources/logback.xml                 |    2 +-
 plc4j/examples/plc4j-s7event/pom.xml               |    9 +-
 .../examples/plc4j/s7event/CycSubscription.java    |    2 -
 .../examples/plc4j/s7event/EventSubscription.java  |    3 -
 .../plc4x/examples/plc4j/s7event/SzlRequest.java   |    2 -
 plc4j/examples/pom.xml                             |    6 -
 plc4j/integrations/apache-nifi/pom.xml             |    2 +-
 plc4j/integrations/opcua-server/pom.xml            |    5 +-
 plc4j/integrations/pom.xml                         |   16 +-
 plc4j/tools/capture-replay/pom.xml                 |    6 -
 .../src/test/resources/logback-test.xml            |    4 +-
 plc4j/tools/plc4x-server/pom.xml                   |    7 +-
 plc4j/tools/ui/pom.xml                             |    4 +
 plc4j/transports/serial/pom.xml                    |    1 -
 .../base/connection/SerialChannelFactoryTest.java  |    1 -
 plc4j/utils/pcap-replay/pom.xml                    |    4 +
 plc4j/utils/pcap-shared/pom.xml                    |    4 +
 plc4j/utils/plc-simulator/pom.xml                  |   14 -
 .../plc-simulator/src/main/resources/logback.xml   |    2 +-
 plc4j/utils/raw-sockets/pom.xml                    |    4 +
 plc4j/utils/test-generator/pom.xml                 |    5 +-
 .../knxnetip-test/resources/logback-test.xml       |    2 +-
 .../knxnetip/readwrite/model/KnxDatapoint.cs       |   38 +-
 .../knxnetip/readwrite/model/KnxManufacturer.cs    | 4128 ++++++++++----------
 pom.xml                                            |   32 +-
 .../ab-eth/src/test/resources/logback-test.xml     |    2 +-
 protocols/ads/src/test/resources/logback-test.xml  |    2 +-
 .../bacnetip/src/test/resources/logback-test.xml   |    2 +-
 .../c-bus/src/test/resources/logback-test.xml      |    2 +-
 .../canopen/src/test/resources/logback-test.xml    |    2 +-
 protocols/df1/src/test/resources/logback-test.xml  |    2 +-
 protocols/eip/src/test/resources/logback-test.xml  |    2 +-
 .../firmata/src/test/resources/logback-test.xml    |    2 +-
 .../genericcan/src/test/resources/logback-test.xml |    2 +-
 protocols/knxnetip/pom.xml                         |   10 +-
 .../knxnetip/src/test/resources/logback-test.xml   |    2 +-
 .../modbus/src/test/resources/logback-test.xml     |    2 +-
 .../opcua/src/test/resources/logback-test.xml      |    2 +-
 protocols/open-protocol/pom.xml                    |    9 +-
 .../src/test/resources/logback-test.xml            |    2 +-
 .../plc4x-api/src/test/resources/logback-test.xml  |    2 +-
 .../plc4x/src/test/resources/logback-test.xml      |    2 +-
 .../profinet/src/test/resources/logback-test.xml   |    2 +-
 protocols/s7/src/test/resources/logback-test.xml   |    2 +-
 .../simulated/src/test/resources/logback-test.xml  |    2 +-
 .../socketcan/src/test/resources/logback-test.xml  |    2 +-
 sandbox/discovery/pom.xml                          |    5 -
 sandbox/test-java-df1-driver/pom.xml               |    4 -
 src/main/script/prerequisiteCheck.groovy           |    2 +
 371 files changed, 6818 insertions(+), 3838 deletions(-)


[plc4x] 01/03: feat(plc4py): WriteBuffer Add local byte_order check

Posted by hu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

hutcheb pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit 3f7001b18472645e45b1082eb10de7466b829e3c
Author: Ben Hutcheson <be...@gmail.com>
AuthorDate: Sun May 14 05:18:11 2023 +0200

    feat(plc4py): WriteBuffer Add local byte_order check
---
 sandbox/plc4py/plc4py/spi/generation/WriteBuffer.py | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/sandbox/plc4py/plc4py/spi/generation/WriteBuffer.py b/sandbox/plc4py/plc4py/spi/generation/WriteBuffer.py
index 187d1aa0af..31fa7ed6e2 100644
--- a/sandbox/plc4py/plc4py/spi/generation/WriteBuffer.py
+++ b/sandbox/plc4py/plc4py/spi/generation/WriteBuffer.py
@@ -107,7 +107,6 @@ class WriteBufferByteBased(WriteBuffer):
 
     NUMERIC_UNION = Union[c_byte, c_uint8, c_uint16, c_uint32, c_uint64, c_int8, c_int16, c_int32, c_int64, c_float, c_double]
 
-
     def __init__(self, size: int, byte_order: ByteOrder):
         self.bb = zeros(size * 8, endian=ByteOrder.get_short_name(byte_order))
         self.byte_order = byte_order
@@ -208,6 +207,7 @@ class WriteBufferByteBased(WriteBuffer):
         self._handle_numeric_encoding(c_double(value.value), bit_length, **kwargs)
 
     def _handle_numeric_encoding(self, value: NUMERIC_UNION, bit_length: int, **kwargs):
+        byte_order = kwargs.get("byte_order", self.byte_order)
         value_encoding: str = kwargs.get("encoding", "default")
         if value_encoding == "ASCII":
             if bit_length % 8 != 0:
@@ -219,12 +219,12 @@ class WriteBufferByteBased(WriteBuffer):
                 raise SerializationException(
                     "Provided value of " + str(value) + " exceeds the max value of " + str(max_value))
             string_value: str = "{}".format(value.value)
-            src = bitarray(endian=ByteOrder.get_short_name(self.byte_order))
+            src = bitarray(endian=ByteOrder.get_short_name(byte_order))
             src.frombytes(bytearray(string_value, value_encoding))
             self.bb[self.position:bit_length] = src[:bit_length]
             self.position += bit_length
         elif value_encoding == "default":
-            src = bitarray(endian=ByteOrder.get_short_name(self.byte_order))
+            src = bitarray(endian=ByteOrder.get_short_name(byte_order))
             src.frombytes(value)
             self.bb[self.position:bit_length] = src[:bit_length]
             self.position += bit_length