Merge branch 'develop' of https://gitbox.apache.org/repos/asf/plc4x into feature/plc4c
diff --git a/build-utils/language-base-freemarker/src/main/java/org/apache/plc4x/plugins/codegenerator/protocol/freemarker/BaseFreemarkerLanguageTemplateHelper.java b/build-utils/language-base-freemarker/src/main/java/org/apache/plc4x/plugins/codegenerator/protocol/freemarker/BaseFreemarkerLanguageTemplateHelper.java
index af8fe22..80bd00e 100644
--- a/build-utils/language-base-freemarker/src/main/java/org/apache/plc4x/plugins/codegenerator/protocol/freemarker/BaseFreemarkerLanguageTemplateHelper.java
+++ b/build-utils/language-base-freemarker/src/main/java/org/apache/plc4x/plugins/codegenerator/protocol/freemarker/BaseFreemarkerLanguageTemplateHelper.java
@@ -89,11 +89,11 @@
         return thisType;
     }
 
-    protected String getProtocolName() {
+    public String getProtocolName() {
         return protocolName;
     }
 
-    protected String getFlavorName() {
+    public String getFlavorName() {
         return flavorName;
     }
 
diff --git a/build-utils/language-c/src/main/java/org/apache/plc4x/language/c/CLanguageOutput.java b/build-utils/language-c/src/main/java/org/apache/plc4x/language/c/CLanguageOutput.java
index 6aa840f..31c43d5 100644
--- a/build-utils/language-c/src/main/java/org/apache/plc4x/language/c/CLanguageOutput.java
+++ b/build-utils/language-c/src/main/java/org/apache/plc4x/language/c/CLanguageOutput.java
@@ -63,7 +63,9 @@
 
     @Override
     protected List<Template> getDataIoTemplates(Configuration freemarkerConfiguration) throws IOException {
-        return Collections.emptyList();
+        return Arrays.asList(
+            freemarkerConfiguration.getTemplate("templates/c/data-io-template-h.ftlh"),
+            freemarkerConfiguration.getTemplate("templates/c/data-io-template-c.ftlh"));
     }
 
     @Override
diff --git a/build-utils/language-c/src/main/java/org/apache/plc4x/language/c/CLanguageTemplateHelper.java b/build-utils/language-c/src/main/java/org/apache/plc4x/language/c/CLanguageTemplateHelper.java
index e7ef5dc..8bcbb38 100644
--- a/build-utils/language-c/src/main/java/org/apache/plc4x/language/c/CLanguageTemplateHelper.java
+++ b/build-utils/language-c/src/main/java/org/apache/plc4x/language/c/CLanguageTemplateHelper.java
@@ -18,6 +18,7 @@
 */
 package org.apache.plc4x.language.c;
 
+import jdk.nashorn.internal.runtime.regexp.joni.constants.StringType;
 import org.apache.commons.lang3.math.NumberUtils;
 import org.apache.plc4x.plugins.codegenerator.protocol.freemarker.BaseFreemarkerLanguageTemplateHelper;
 import org.apache.plc4x.plugins.codegenerator.protocol.freemarker.FreemarkerException;
@@ -41,7 +42,7 @@
     }
 
     public String getIncludesDirectory() {
-        return String.join("", getProtocolName().split("-")) + ".includes";
+        return String.join("", getProtocolName().split("-")) + ".include";
     }
 
     /**
@@ -222,11 +223,11 @@
                 case STRING:
                     return "char*";
                 case TIME:
-                    throw new FreemarkerException("Unsupported time type.");
+                    return "time_t";//throw new FreemarkerException("Unsupported time type.");
                 case DATE:
-                    throw new FreemarkerException("Unsupported date type.");
+                    return "time_t";//throw new FreemarkerException("Unsupported date type.");
                 case DATETIME:
-                    throw new FreemarkerException("Unsupported date-time type.");
+                    return "time_t";//throw new FreemarkerException("Unsupported date-time type.");
             }
             throw new FreemarkerException("Unsupported simple type. " + simpleTypeReference.getBaseType());
         } else {
@@ -349,48 +350,48 @@
     public String getReadBufferReadMethodCall(SimpleTypeReference simpleTypeReference, String valueString) {
         switch (simpleTypeReference.getBaseType()) {
             case BIT:
-                return "plc4c_spi_read_bit(buf, (bool*) " + valueString + ")";
+                return "plc4c_spi_read_bit(io, (bool*) " + valueString + ")";
             case UINT:
                 IntegerTypeReference unsignedIntegerTypeReference = (IntegerTypeReference) simpleTypeReference;
                 if (unsignedIntegerTypeReference.getSizeInBits() <= 8) {
-                    return "plc4c_spi_read_unsigned_byte(buf, " + unsignedIntegerTypeReference.getSizeInBits() + ", (uint8_t*) " + valueString + ")";
+                    return "plc4c_spi_read_unsigned_byte(io, " + unsignedIntegerTypeReference.getSizeInBits() + ", (uint8_t*) " + valueString + ")";
                 }
                 if (unsignedIntegerTypeReference.getSizeInBits() <= 16) {
-                    return "plc4c_spi_read_unsigned_short(buf, " + unsignedIntegerTypeReference.getSizeInBits() + ", (uint16_t*) " + valueString + ")";
+                    return "plc4c_spi_read_unsigned_short(io, " + unsignedIntegerTypeReference.getSizeInBits() + ", (uint16_t*) " + valueString + ")";
                 }
                 if (unsignedIntegerTypeReference.getSizeInBits() <= 32) {
-                    return "plc4c_spi_read_unsigned_int(buf, " + unsignedIntegerTypeReference.getSizeInBits() + ", (uint32_t*) " + valueString + ")";
+                    return "plc4c_spi_read_unsigned_int(io, " + unsignedIntegerTypeReference.getSizeInBits() + ", (uint32_t*) " + valueString + ")";
                 }
                 if (unsignedIntegerTypeReference.getSizeInBits() <= 64) {
-                    return "plc4c_spi_read_unsigned_long(buf, " + unsignedIntegerTypeReference.getSizeInBits() + ", (uint64_t*) " + valueString + ")";
+                    return "plc4c_spi_read_unsigned_long(io, " + unsignedIntegerTypeReference.getSizeInBits() + ", (uint64_t*) " + valueString + ")";
                 }
                 throw new FreemarkerException("Unsupported unsigned integer type with " + unsignedIntegerTypeReference.getSizeInBits() + " bits");
             case INT:
                 IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
                 if (integerTypeReference.getSizeInBits() <= 8) {
-                    return "plc4c_spi_read_signed_byte(buf, " + integerTypeReference.getSizeInBits() + ", (int8_t*) " + valueString + ")";
+                    return "plc4c_spi_read_signed_byte(io, " + integerTypeReference.getSizeInBits() + ", (int8_t*) " + valueString + ")";
                 }
                 if (integerTypeReference.getSizeInBits() <= 16) {
-                    return "plc4c_spi_read_signed_short(buf, " + integerTypeReference.getSizeInBits() + ", (int16_t*) " + valueString + ")";
+                    return "plc4c_spi_read_signed_short(io, " + integerTypeReference.getSizeInBits() + ", (int16_t*) " + valueString + ")";
                 }
                 if (integerTypeReference.getSizeInBits() <= 32) {
-                    return "plc4c_spi_read_signed_int(buf, " + integerTypeReference.getSizeInBits() + ", (int32_t*) " + valueString + ")";
+                    return "plc4c_spi_read_signed_int(io, " + integerTypeReference.getSizeInBits() + ", (int32_t*) " + valueString + ")";
                 }
                 if (integerTypeReference.getSizeInBits() <= 64) {
-                    return "plc4c_spi_read_signed_long(buf, " + integerTypeReference.getSizeInBits() + ", (int64_t*) " + valueString + ")";
+                    return "plc4c_spi_read_signed_long(io, " + integerTypeReference.getSizeInBits() + ", (int64_t*) " + valueString + ")";
                 }
                 throw new FreemarkerException("Unsupported signed integer type with " + integerTypeReference.getSizeInBits() + " bits");
             case FLOAT:
                 FloatTypeReference floatTypeReference = (FloatTypeReference) simpleTypeReference;
                 if (floatTypeReference.getSizeInBits() <= 32) {
-                    return "plc4c_spi_read_float(buf, " + floatTypeReference.getSizeInBits() + ", (float*) " + valueString + ")";
+                    return "plc4c_spi_read_float(io, " + floatTypeReference.getSizeInBits() + ", (float*) " + valueString + ")";
                 } else if(floatTypeReference.getSizeInBits() <= 64) {
-                    return "plc4c_spi_read_double(buf, " + floatTypeReference.getSizeInBits() + ", (double*) " + valueString + ")";
+                    return "plc4c_spi_read_double(io, " + floatTypeReference.getSizeInBits() + ", (double*) " + valueString + ")";
                 }
                 throw new FreemarkerException("Unsupported float type with " + floatTypeReference.getSizeInBits() + " bits");
             case STRING:
                 StringTypeReference stringTypeReference = (StringTypeReference) simpleTypeReference;
-                return "plc4c_spi_read_string(buf, " + stringTypeReference.getSizeInBits() + ", \"" +
+                return "plc4c_spi_read_string(io, " + stringTypeReference.getSizeInBits() + ", \"" +
                     stringTypeReference.getEncoding() + "\"" + ", (char**) " + valueString + ")";
             default:
                 throw new FreemarkerException("Unsupported type " + simpleTypeReference.getBaseType().name());
@@ -401,48 +402,48 @@
     public String getWriteBufferWriteMethodCall(SimpleTypeReference simpleTypeReference, String fieldName) {
         switch (simpleTypeReference.getBaseType()) {
             case BIT:
-                return "plc4c_spi_write_bit(buf, " + fieldName + ")";
+                return "plc4c_spi_write_bit(io, " + fieldName + ")";
             case UINT:
                 IntegerTypeReference unsignedIntegerTypeReference = (IntegerTypeReference) simpleTypeReference;
                 if (unsignedIntegerTypeReference.getSizeInBits() <= 8) {
-                    return "plc4c_spi_write_unsigned_byte(buf, " + unsignedIntegerTypeReference.getSizeInBits() + ", " + fieldName + ")";
+                    return "plc4c_spi_write_unsigned_byte(io, " + unsignedIntegerTypeReference.getSizeInBits() + ", " + fieldName + ")";
                 }
                 if (unsignedIntegerTypeReference.getSizeInBits() <= 16) {
-                    return "plc4c_spi_write_unsigned_short(buf, " + unsignedIntegerTypeReference.getSizeInBits() + ", " + fieldName + ")";
+                    return "plc4c_spi_write_unsigned_short(io, " + unsignedIntegerTypeReference.getSizeInBits() + ", " + fieldName + ")";
                 }
                 if (unsignedIntegerTypeReference.getSizeInBits() <= 32) {
-                    return "plc4c_spi_write_unsigned_int(buf, " + unsignedIntegerTypeReference.getSizeInBits() + ", " + fieldName + ")";
+                    return "plc4c_spi_write_unsigned_int(io, " + unsignedIntegerTypeReference.getSizeInBits() + ", " + fieldName + ")";
                 }
                 if (unsignedIntegerTypeReference.getSizeInBits() <= 64) {
-                    return "plc4c_spi_write_unsigned_long(buf, " + unsignedIntegerTypeReference.getSizeInBits() + ", " + fieldName + ")";
+                    return "plc4c_spi_write_unsigned_long(io, " + unsignedIntegerTypeReference.getSizeInBits() + ", " + fieldName + ")";
                 }
                 throw new FreemarkerException("Unsupported unsigned integer type with " + unsignedIntegerTypeReference.getSizeInBits() + " bits");
             case INT:
                 IntegerTypeReference integerTypeReference = (IntegerTypeReference) simpleTypeReference;
                 if (integerTypeReference.getSizeInBits() <= 8) {
-                    return "plc4c_spi_write_signed_byte(buf, " + integerTypeReference.getSizeInBits() + ", " + fieldName + ")";
+                    return "plc4c_spi_write_signed_byte(io, " + integerTypeReference.getSizeInBits() + ", " + fieldName + ")";
                 }
                 if (integerTypeReference.getSizeInBits() <= 16) {
                     return "plc4c_spi_write_signed_short(buf, " + integerTypeReference.getSizeInBits() + ", " + fieldName + ")";
                 }
                 if (integerTypeReference.getSizeInBits() <= 32) {
-                    return "plc4c_spi_write_signed_int(buf, " + integerTypeReference.getSizeInBits() + ", " + fieldName + ")";
+                    return "plc4c_spi_write_signed_int(io, " + integerTypeReference.getSizeInBits() + ", " + fieldName + ")";
                 }
                 if (integerTypeReference.getSizeInBits() <= 64) {
-                    return "plc4c_spi_write_signed_long(buf, " + integerTypeReference.getSizeInBits() + ", " + fieldName + ")";
+                    return "plc4c_spi_write_signed_long(io, " + integerTypeReference.getSizeInBits() + ", " + fieldName + ")";
                 }
                 throw new FreemarkerException("Unsupported signed integer type with " + integerTypeReference.getSizeInBits() + " bits");
             case FLOAT:
                 FloatTypeReference floatTypeReference = (FloatTypeReference) simpleTypeReference;
                 if (floatTypeReference.getSizeInBits() <= 32) {
-                    return "plc4c_spi_write_float(buf, " + floatTypeReference.getSizeInBits() + ", " + fieldName + ")";
+                    return "plc4c_spi_write_float(io, " + floatTypeReference.getSizeInBits() + ", " + fieldName + ")";
                 } else if(floatTypeReference.getSizeInBits() <= 64) {
-                    return "plc4c_spi_write_double(buf, " + floatTypeReference.getSizeInBits() + ", " + fieldName + ")";
+                    return "plc4c_spi_write_double(io, " + floatTypeReference.getSizeInBits() + ", " + fieldName + ")";
                 }
                 throw new FreemarkerException("Unsupported float type with " + floatTypeReference.getSizeInBits() + " bits");
             case STRING:
                 StringTypeReference stringTypeReference = (StringTypeReference) simpleTypeReference;
-                return "plc4c_spi_write_string(buf, " + stringTypeReference.getSizeInBits() + ", \"" +
+                return "plc4c_spi_write_string(io, " + stringTypeReference.getSizeInBits() + ", \"" +
                     stringTypeReference.getEncoding() + "\", " + fieldName + ")";
             default:
                 throw new FreemarkerException("Unsupported type " + simpleTypeReference.getBaseType().name());
@@ -479,20 +480,28 @@
         }
     }
 
+    public String getReservedValue(ReservedField reservedField) {
+        final String languageTypeName = getLanguageTypeNameForTypeReference(reservedField.getType());
+        if("BigInteger".equals(languageTypeName)) {
+            return "BigInteger.valueOf(" + reservedField.getReferenceValue() + ")";
+        } else {
+            return "(" + languageTypeName + ") " + reservedField.getReferenceValue();
+        }
+    }
 
 
 
 
 
-    public String toParseExpression(ComplexTypeDefinition baseType, Field field, Term term, Argument[] parserArguments) {
+    public String toParseExpression(TypeDefinition baseType, Field field, Term term, Argument[] parserArguments) {
         return toExpression(baseType, field, term, term1 -> toVariableParseExpression(baseType, field, term1, parserArguments));
     }
 
-    public String toSerializationExpression(ComplexTypeDefinition baseType, Field field, Term term, Argument[] parserArguments) {
+    public String toSerializationExpression(TypeDefinition baseType, Field field, Term term, Argument[] parserArguments) {
         return toExpression(baseType, field, term, term1 -> toVariableSerializationExpression(baseType, field, term1, parserArguments));
     }
 
-    private String toExpression(ComplexTypeDefinition baseType, Field field, Term term, Function<Term, String> variableExpressionGenerator) {
+    private String toExpression(TypeDefinition baseType, Field field, Term term, Function<Term, String> variableExpressionGenerator) {
         if (term == null) {
             return "";
         }
@@ -508,17 +517,17 @@
             } else if (term instanceof VariableLiteral) {
                 VariableLiteral variableLiteral = (VariableLiteral) term;
                 if(variableLiteral.contains("lengthInBytes")) {
-                    ComplexTypeDefinition lengthType;
+                    TypeDefinition lengthType;
                     String lengthExpression;
                     if(variableLiteral.getName().equals("lengthInBytes")) {
                         lengthType = (baseType.getParentType() == null) ? baseType : (ComplexTypeDefinition) baseType.getParentType();
                         lengthExpression = "_message";
                     } else {
-                        final Optional<TypeReference> typeReferenceForProperty = getTypeReferenceForProperty(baseType, variableLiteral.getName());
+                        final Optional<TypeReference> typeReferenceForProperty = getTypeReferenceForProperty( (ComplexTypeDefinition) baseType, variableLiteral.getName());
                         if(!typeReferenceForProperty.isPresent()) {
                             throw new FreemarkerException("Unknown type for property " + variableLiteral.getName());
                         }
-                        lengthType = (ComplexTypeDefinition) getTypeDefinitionForTypeReference(typeReferenceForProperty.get());
+                        lengthType = getTypeDefinitionForTypeReference(typeReferenceForProperty.get());
                         lengthExpression = variableExpressionGenerator.apply(term);
                     }
                     return getCTypeName(lengthType.getName()) + "_length_in_bytes(" + lengthExpression + ")";
@@ -570,7 +579,7 @@
         }
     }
 
-    public String toVariableParseExpression(ComplexTypeDefinition baseType, Field field, Term term, Argument[] parserArguments) {
+    public String toVariableParseExpression(TypeDefinition baseType, Field field, Term term, Argument[] parserArguments) {
         VariableLiteral vl = (VariableLiteral) term;
         if("CAST".equals(vl.getName())) {
 
@@ -600,15 +609,37 @@
                     appendVariableExpressionRest(sb, baseType, vl.getChild());
                 } else {
                     sb.append("->");
-                    appendVariableExpressionRest(sb, (ComplexTypeDefinition) castType, vl.getChild());
+                    appendVariableExpressionRest(sb, castType, vl.getChild());
                 }
             }
             return sb.toString();
         }
+        // STATIC_CALL implies that driver specific static logic should be called
+        if ("STATIC_CALL".equals(vl.getName())) {
+            String functionName = ((StringLiteral) vl.getArgs().get(0)).getValue();
+            // We'll cut off the java package structure and just take the segment after the last "."
+            functionName = functionName.substring(functionName.lastIndexOf('.') + 1, functionName.length() -1);
+            // But to make the function name unique, well add the driver prefix to it.
+            StringBuilder sb = new StringBuilder(getCTypeName(functionName));
+            if (vl.getArgs().size() > 1) {
+                sb.append("(");
+                boolean firstArg = true;
+                for (int i = 1; i < vl.getArgs().size(); i++) {
+                    Term arg = vl.getArgs().get(i);
+                    if (!firstArg) {
+                        sb.append(", ");
+                    }
+                    sb.append(toParseExpression(baseType, field, arg, parserArguments));
+                    firstArg = false;
+                }
+                sb.append(")");
+            }
+            return sb.toString();
+        }
         // Any name that is full upper-case is considered a function call.
         // These are generally defined in the spi file evaluation_helper.c.
         // All should have a name prefix "plc4c_spi_evaluation_helper_".
-        if (vl.getName().equals(vl.getName().toUpperCase())) {
+        else if (vl.getName().equals(vl.getName().toUpperCase())) {
             StringBuilder sb = new StringBuilder("plc4c_spi_evaluation_helper_" + vl.getName().toLowerCase());
             if (vl.getArgs() != null) {
                 sb.append("(");
@@ -630,13 +661,39 @@
                 appendVariableExpressionRest(sb, baseType, vl.getChild());
             }
             return sb.toString();
+        } else if("io".equals(vl.getName())) {
+            StringBuilder sb = new StringBuilder("io");
+            if(vl.getChild() != null) {
+                sb.append(".");
+                appendVariableExpressionRest(sb, baseType, vl.getChild());
+            }
+            return sb.toString();
+        } else if("_type".equals(vl.getName())) {
+            if((vl.getChild() != null) && "encoding".equals(vl.getChild().getName()) && (field instanceof TypedField) && (((TypedField) field).getType() instanceof StringTypeReference)) {
+                TypedField typedField = (TypedField) field;
+                StringTypeReference stringTypeReference = (StringTypeReference) typedField.getType();
+                return "\"" + stringTypeReference.getEncoding().substring(1, stringTypeReference.getEncoding().length() - 1) + "\"";
+            } else {
+                throw new FreemarkerException("_type is currently pretty much hard-coded for some usecases, please check CLanguageTemplateHelper.toVariableParseExpression");
+            }
         }
 
         final String name = vl.getName();
 
+        // In case of DataIo types, we'll just check the arguments.
+        if(baseType instanceof DataIoTypeDefinition) {
+            if(baseType.getParserArguments() != null) {
+                for (Argument parserArgument : baseType.getParserArguments()) {
+                    if(parserArgument.getName().equals(name)) {
+                        return name;
+                    }
+                }
+            }
+        }
+
         // Try to find the type of the addressed property.
         final Optional<TypeReference> propertyTypeOptional =
-            getTypeReferenceForProperty(baseType, name);
+            getTypeReferenceForProperty((ComplexTypeDefinition) baseType, name);
 
         // If we couldn't find the type, we didn't find the property.
         if(!propertyTypeOptional.isPresent()) {
@@ -687,7 +744,7 @@
         return sb.toString();
     }
 
-    private String toVariableSerializationExpression(ComplexTypeDefinition baseType, Field field, Term term, Argument[] serialzerArguments) {
+    private String toVariableSerializationExpression(TypeDefinition baseType, Field field, Term term, Argument[] serialzerArguments) {
         VariableLiteral vl = (VariableLiteral) term;
         if ("STATIC_CALL".equals(vl.getName())) {
             StringBuilder sb = new StringBuilder();
@@ -870,7 +927,7 @@
 
             // If this expression references enum constants we need to do things differently
             final Optional<TypeReference> typeReferenceForProperty =
-                getTypeReferenceForProperty(baseType, vl.getName());
+                getTypeReferenceForProperty((ComplexTypeDefinition) baseType, vl.getName());
             if(typeReferenceForProperty.isPresent()) {
                 final TypeReference typeReference = typeReferenceForProperty.get();
                 if(typeReference instanceof ComplexTypeReference) {
@@ -890,7 +947,7 @@
         }
     }
 
-    private void appendVariableExpressionRest(StringBuilder sb, ComplexTypeDefinition baseType, VariableLiteral vl) {
+    private void appendVariableExpressionRest(StringBuilder sb, TypeDefinition baseType, VariableLiteral vl) {
         if(vl.isIndexed()) {
             sb.insert(0, "plc4c_utils_list_get_value(");
             sb.append(camelCaseToSnakeCase(vl.getName()));
diff --git a/build-utils/language-c/src/main/resources/templates/c/data-io-template-c.ftlh b/build-utils/language-c/src/main/resources/templates/c/data-io-template-c.ftlh
new file mode 100644
index 0000000..602bb14
--- /dev/null
+++ b/build-utils/language-c/src/main/resources/templates/c/data-io-template-c.ftlh
@@ -0,0 +1,245 @@
+<#--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<#-- Prevent freemarker from escaping stuff -->
+<#outputformat "undefined">
+<#-- Declare the name and type of variables passed in to the template -->
+<#-- @ftlvariable name="languageName" type="java.lang.String" -->
+<#-- @ftlvariable name="protocolName" type="java.lang.String" -->
+<#-- @ftlvariable name="outputFlavor" type="java.lang.String" -->
+<#-- @ftlvariable name="helper" type="org.apache.plc4x.language.c.CLanguageTemplateHelper" -->
+<#-- @ftlvariable name="type" type="org.apache.plc4x.plugins.codegenerator.types.definitions.ComplexTypeDefinition" -->
+<#-- Declare the name and type of variables declared locally inside the template -->
+<#-- @ftlvariable name="arrayField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ArrayField" -->
+<#-- @ftlvariable name="checksumField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ChecksumField" -->
+<#-- @ftlvariable name="constField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ConstField" -->
+<#-- @ftlvariable name="discriminatorField" type="org.apache.plc4x.plugins.codegenerator.types.fields.DiscriminatorField" -->
+<#-- @ftlvariable name="enumField" type="org.apache.plc4x.plugins.codegenerator.types.fields.EnumField" -->
+<#-- @ftlvariable name="implicitField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ImplicitField" -->
+<#-- @ftlvariable name="manualArrayField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ManualArrayField" -->
+<#-- @ftlvariable name="manualField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ManualField" -->
+<#-- @ftlvariable name="optionalField" type="org.apache.plc4x.plugins.codegenerator.types.fields.OptionalField" -->
+<#-- @ftlvariable name="paddingField" type="org.apache.plc4x.plugins.codegenerator.types.fields.PaddingField" -->
+<#-- @ftlvariable name="reservedField" type="org.apache.plc4x.plugins.codegenerator.types.fields.ReservedField" -->
+<#-- @ftlvariable name="simpleField" type="org.apache.plc4x.plugins.codegenerator.types.fields.SimpleField" -->
+<#-- @ftlvariable name="switchField" type="org.apache.plc4x.plugins.codegenerator.types.fields.SwitchField" -->
+<#-- @ftlvariable name="virtualField" type="org.apache.plc4x.plugins.codegenerator.types.fields.VirtualField" -->
+<#-- @ftlvariable name="simpleTypeReference" type="org.apache.plc4x.plugins.codegenerator.types.references.SimpleTypeReference" -->
+<#-- @ftlvariable name="complexTypeReference" type="org.apache.plc4x.plugins.codegenerator.types.references.ComplexTypeReference" -->
+<#if !helper.isDiscriminatedChildTypeDefinition(type)>${helper.getSourceDirectory()?replace(".", "/")}/${helper.camelCaseToSnakeCase(type.name)}.c
+/*
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+*/
+
+#include <stdio.h>
+#include <time.h>
+#include <plc4c/data.h>
+#include <plc4c/spi/evaluation_helper.h>
+#include <plc4c/driver_${helper.getProtocolName()}.h>
+#include "${helper.camelCaseToSnakeCase(type.name)}.h"
+
+// Parse function.
+plc4c_return_code ${helper.getCTypeName(type.name)}_parse(plc4c_spi_read_buffer* io, <#if type.parserArguments?has_content><#list type.parserArguments as parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type)}<#if !helper.isSimpleTypeReference(parserArgument.type)>*</#if> ${parserArgument.name}<#sep>, </#list>, </#if>plc4c_data** data_item) {
+    uint16_t startPos = plc4c_spi_read_get_pos(io);
+    uint16_t curPos;
+    plc4c_return_code _res = OK;
+
+    <#list type.switchField.cases as case>
+        <#if case.discriminatorValues?has_content>if(<#list case.discriminatorValues as discriminatorValue><#if case.discriminatorValues?size &gt; 1>(</#if>${helper.toParseExpression(type, null, type.switchField.discriminatorExpressions[discriminatorValue?index], type.parserArguments)} == ${discriminatorValue}<#if case.discriminatorValues?size &gt; 1>)</#if><#sep> && </#sep></#list>) </#if>{ /* ${case.name} */
+<#--        (*_message)->_type = ${helper.getCTypeName(type.name)}_type_${helper.getCTypeName(case.name)};-->
+        <#assign skipReturn=false>
+        <#list case.fields as field>
+            <#switch field.typeName>
+                <#case "array">
+
+                    // Array field (${field.name})
+                <#-- Only update curPos if the length expression uses it
+                    <#if field.loopExpression.contains("curPos")>
+                        curPos = io.getPos() - startPos;
+                    </#if>
+                <#- If this is a count array, we can directly initialize an array with the given size ->
+                    <#if helper.isCountArrayField(field)>
+                        // Count array
+                        if(${helper.toParseExpression(type, field, field.loopExpression, type.parserArguments)} > Integer.MAX_VALUE) {
+                        throw new ParseException("Array count of " + (${helper.toParseExpression(type, field, field.loopExpression, type.parserArguments)}) + " exceeds the maximum allowed count of " + Integer.MAX_VALUE);
+                        }
+                        ${helper.getLanguageTypeNameForField(field)}[] ${field.name};
+                        {
+                        int itemCount = (int) ${helper.toParseExpression(type, field, field.loopExpression, type.parserArguments)};
+                        ${field.name} = new ${helper.getLanguageTypeNameForField(field)}[itemCount];
+                        for(int curItem = 0; curItem < itemCount; curItem++) {
+                        ${field.name}[curItem] = <#if helper.isSimpleTypeReference(field.type)>${helper.getReadBufferReadMethodCall(field.type)}<#else>${field.type.name}IO.staticParse(io<#if field.params?has_content>, <#list field.params as parserArgument>(${helper.getLanguageTypeNameForTypeReference(helper.getArgumentType(field.type, parserArgument?index), true)}) (${helper.toParseExpression(type, field, parserArgument, type.parserArguments)})<#sep>, </#sep></#list></#if>)</#if>;
+                        }
+                        }
+                    <#- In all other cases do we have to work with a list, that is later converted to an array ->
+                    <#else>
+                    <#- For a length array, we read data till the read position of the buffer reaches a given position ->
+                        <#if helper.isLengthArrayField(field)>
+                            // Length array
+                            int _${field.name}Length = ${helper.toParseExpression(type, field, field.loopExpression, type.parserArguments)};
+                            List<${helper.getLanguageTypeNameForField(field)}> _${field.name}List = new LinkedList<>();
+                            int ${field.name}EndPos = io.getPos() + _${field.name}Length;
+                            while(io.getPos() < ${field.name}EndPos) {
+                            _${field.name}List.add(<#if helper.isSimpleTypeReference(field.type)>${helper.getReadBufferReadMethodCall(field.type)}<#else>${field.type.name}IO.staticParse(io<#if field.params?has_content>, <#list field.params as parserArgument>(${helper.getLanguageTypeNameForTypeReference(helper.getArgumentType(field.type, parserArgument?index), true)}) (${helper.toParseExpression(type, field, parserArgument, type.parserArguments)})<#sep>, </#sep></#list></#if>)</#if>);
+                        <#- After parsing, update the current position, but only if it's needed ->
+                            <#if field.loopExpression.contains("curPos")>
+                                curPos = io.getPos() - startPos;
+                            </#if>
+                            }
+                        <#- A terminated array keeps on reading data as long as the termination expression evaluates to false ->
+                        <#elseif helper.isTerminatedArrayField(field)>
+                            // Terminated array
+                            List<${helper.getLanguageTypeNameForField(field)}> _${field.name}List = new LinkedList<>();
+                            while(!((boolean) (${helper.toParseExpression(type, field, field.loopExpression, type.parserArguments)}))) {
+                            _${field.name}List.add(<#if helper.isSimpleTypeReference(field.type)>${helper.getReadBufferReadMethodCall(field.type)}<#else>${field.type.name}IO.staticParse(io<#if field.params?has_content>, <#list field.params as parserArgument>(${helper.getLanguageTypeNameForTypeReference(helper.getArgumentType(field.type, parserArgument?index), true)}) (${helper.toParseExpression(type, field, parserArgument, type.parserArguments)})<#sep>, </#sep></#list></#if>)</#if>);
+
+                        <#- After parsing, update the current position, but only if it's needed ->
+                            <#if field.loopExpression.contains("curPos")>
+                                curPos = io.getPos() - startPos;
+                            </#if>
+                            }
+                        </#if>
+                    <#-
+                        Convert the list into an array. However if the array is of a primitive
+                        type we have to iterate over it's elements and explicitly cast them.
+                        Otherwise a simple toArray call is fine.
+                    ->
+                        <#if helper.isSimpleTypeReference(field.type)>
+                            ${helper.getLanguageTypeNameForField(field)}[] ${field.name} = new ${helper.getLanguageTypeNameForField(field)}[_${field.name}List.size()];
+                            for(int i = 0; i < _${field.name}List.size(); i++) {
+                            ${field.name}[i] = (${helper.getLanguageTypeNameForField(field)}) _${field.name}List.get(i);
+                            }
+                        <#else>
+                            ${helper.getLanguageTypeNameForField(field)}[] ${field.name} = _${field.name}List.toArray(new ${helper.getLanguageTypeNameForField(field)}[0]);
+                        </#if>
+                    </#if>
+                    -->
+                    <#break>
+                <#case "const">
+
+                    // Const Field (${field.name})
+                    ${helper.getLanguageTypeNameForField(field)} ${field.name} = ${helper.getReadBufferReadMethodCall(field.type)};
+                    if(${field.name} != ${type.name}.${field.name?upper_case}) {
+                    throw new ParseException("Expected constant value " + ${type.name}.${field.name?upper_case} + " but got " + ${field.name});
+                    }
+                    <#break>
+                <#case "enum">
+
+                    // Enum field (${field.name})
+                    ${helper.getLanguageTypeNameForField(field)} ${field.name} = ${helper.getLanguageTypeNameForField(field)}.valueOf(${helper.getReadBufferReadMethodCall(helper.getEnumBaseTypeReference(field.type))});
+                    <#break>
+                <#case "manual">
+
+                    // Manual Field (${field.name})
+                    ${helper.getLanguageTypeNameForField(field)} ${field.name} = (${helper.getLanguageTypeNameForField(field)}) (${helper.toParseExpression(type, field, field.parseExpression, type.parserArguments)});
+                    <#--<#switch case.name>
+                        <#case "Time">
+                            return new PlcTime(${field.name});
+                            <#break>
+                        <#case "Date">
+                            return new PlcDate(${field.name});
+                            <#break>
+                        <#case "DateTime">
+                            return new PlcDateTime(${field.name});
+                            <#break>
+                        <#case "Struct">
+                            return new PlcStruct(${field.name});
+                            <#break>
+                        <#case "String">
+                            return new PlcString(${field.name});
+                            <#break>
+                        <#default>
+                            return new Plc${case.name}(${field.name});
+                    </#switch>
+                    <#assign skipReturn=true>
+                    -->
+                    <#break>
+                <#case "reserved">
+
+                // Reserved Field (Compartmentalized so the "reserved" variable can't leak)
+                {
+                    ${helper.getLanguageTypeNameForField(field)} _reserved = ${helper.getNullValueForTypeReference(field.type)};
+                    _res = ${helper.getReadBufferReadMethodCall(field.type, "&_reserved")};
+                    if(_res != OK) {
+                        return _res;
+                    }
+                    if(_reserved != ${field.referenceValue}) {
+                      printf("Expected constant value '%d' but got '%d' for reserved field.", ${field.referenceValue}, _reserved);
+                    }
+                }
+                    <#break>
+                <#case "simple">
+
+                // Simple Field (${field.name})
+                <#-- Inizialize a local variable with the simple type (Intentionally keeping the java-style names so they can be used in expressions) -->
+                <#if helper.isSimpleTypeReference(field.type)>
+                ${helper.getLanguageTypeNameForField(field)} ${field.name} = ${helper.getNullValueForTypeReference(field.type)};
+                _res = ${helper.getReadBufferReadMethodCall(field.type, "&" + field.name)};
+                <#else>
+                <#-- Inizialize a local variable with the complex type (Intentionally keeping the java-style names so they can be used in expressions) -->
+                ${helper.getLanguageTypeNameForField(field)}* ${field.name};
+                _res = ${helper.getCTypeName(field.type.name)}_parse(io<#if field.params?has_content>, <#list field.params as parserTerm>${helper.toParseExpression(baseType, field, parserTerm, baseType.parserArguments)}<#sep>, </#sep></#list></#if>, (void*) &${field.name});
+                </#if>
+                if(_res != OK) {
+                    return _res;
+                }
+
+                *data_item = plc4c_data_create_${helper.getLanguageTypeNameForField(field)}_data(${field.name});
+
+                    <#break>
+            </#switch>
+        </#list>
+        }<#sep> else </#sep>
+    </#list>
+
+  return OK;
+}
+
+plc4c_return_code ${helper.getCTypeName(type.name)}_serialize(plc4c_spi_write_buffer* io, plc4c_data** data_item<#if helper.getSerializerArguments(type.parserArguments)?has_content>, <#list helper.getSerializerArguments(type.parserArguments) as parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type)} ${parserArgument.name}<#sep>, </#sep></#list></#if>) {
+  plc4c_return_code _res = OK;
+
+  return OK;
+}
+
+uint16_t ${helper.getCTypeName(type.name)}_length_in_bytes(plc4c_data* data_item) {
+  return ${helper.getCTypeName(type.name)}_length_in_bits(data_item) / 8;
+}
+
+uint16_t ${helper.getCTypeName(type.name)}_length_in_bits(plc4c_data* data_item) {
+  uint16_t lengthInBits = 0;
+
+  return lengthInBits;
+}
+
+</#if>
+</#outputformat>
\ No newline at end of file
diff --git a/build-utils/language-c/src/main/resources/templates/c/data-io-template-h.ftlh b/build-utils/language-c/src/main/resources/templates/c/data-io-template-h.ftlh
new file mode 100644
index 0000000..145df09
--- /dev/null
+++ b/build-utils/language-c/src/main/resources/templates/c/data-io-template-h.ftlh
@@ -0,0 +1,88 @@
+<#--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<#-- Prevent freemarker from escaping stuff -->
+<#outputformat "undefined">
+<#-- Declare the name and type of variables passed in to the template -->
+<#-- @ftlvariable name="languageName" type="java.lang.String" -->
+<#-- @ftlvariable name="protocolName" type="java.lang.String" -->
+<#-- @ftlvariable name="outputFlavor" type="java.lang.String" -->
+<#-- @ftlvariable name="helper" type="org.apache.plc4x.language.c.CLanguageTemplateHelper" -->
+<#-- @ftlvariable name="type" type="org.apache.plc4x.plugins.codegenerator.types.definitions.ComplexTypeDefinition" -->
+<#-- Declare the name and type of variables declared locally inside the template -->
+<#-- @ftlvariable name="field" type="org.apache.plc4x.plugins.codegenerator.types.fields.NamedField" -->
+<#if !helper.isDiscriminatedChildTypeDefinition(type)>${helper.getIncludesDirectory()?replace(".", "/")}/${helper.camelCaseToSnakeCase(type.name)}.h
+/*
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+*/
+#ifndef ${helper.getCTypeName(type.name)?upper_case}_H_
+#define ${helper.getCTypeName(type.name)?upper_case}_H_
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <plc4c/spi/read_buffer.h>
+#include <plc4c/spi/write_buffer.h>
+#include <plc4c/utils/list.h>
+<#--
+    Add any import statements for partent-types, complex types used in properties or parser arguments.
+-->
+<#if helper.getComplexTypeReferences()?has_content>
+    <#list helper.getComplexTypeReferences() as typeReference>
+#include "${helper.camelCaseToSnakeCase(typeReference)}.h"
+    </#list>
+</#if>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+<#--
+    Define the parse-method for elements of this tpye
+-->
+plc4c_return_code ${helper.getCTypeName(type.name)}_parse(plc4c_spi_read_buffer* buf, <#if type.parserArguments?has_content><#list type.parserArguments as parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type)}<#if !helper.isSimpleTypeReference(parserArgument.type)>*</#if> ${parserArgument.name}<#sep>, </#list>, </#if>plc4c_data** data_item);
+
+<#--
+    Define the serialize-method for elements of this tpye
+-->
+plc4c_return_code ${helper.getCTypeName(type.name)}_serialize(plc4c_spi_write_buffer* buf, plc4c_data** data_item<#if helper.getSerializerArguments(type.parserArguments)?has_content>, <#list helper.getSerializerArguments(type.parserArguments) as parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type)} ${parserArgument.name}<#sep>, </#sep></#list></#if>);
+
+uint16_t ${helper.getCTypeName(type.name)}_length_in_bytes(plc4c_data* data_item);
+
+uint16_t ${helper.getCTypeName(type.name)}_length_in_bits(plc4c_data* data_item);
+
+#ifdef __cplusplus
+}
+#endif
+#endif  // ${helper.getCTypeName(type.name)?upper_case}_H_
+</#if>
+</#outputformat>
\ No newline at end of file
diff --git a/build-utils/language-c/src/main/resources/templates/c/enum-template-c.ftlh b/build-utils/language-c/src/main/resources/templates/c/enum-template-c.ftlh
index 647a63d..f8d9d20 100644
--- a/build-utils/language-c/src/main/resources/templates/c/enum-template-c.ftlh
+++ b/build-utils/language-c/src/main/resources/templates/c/enum-template-c.ftlh
@@ -37,6 +37,7 @@
 */
 
 #include "${helper.camelCaseToSnakeCase(typeName)}.h"
+#include <string.h>
 
 <#--
     Add any import statements for partent-types, complex types used in properties or parser arguments.
@@ -54,11 +55,36 @@
   return ${helper.getCTypeName(type.name)}_null_const;
 }
 
-<#--
-    If this enum also defines constant values, output one function for each.
-    Each of these functions consist of a simple switch statement using the enum as switch-value
-    returning the constant for a given enum value.
--->
+${helper.getCTypeName(type.name)} ${helper.getCTypeName(type.name)}_value_of(char* value_string) {
+<#list helper.getUniqueEnumValues(type.enumValues) as enumValue>
+    if(strcmp(value_string, "${enumValue.name}") == 0) {
+        return ${enumValue.value};
+    }
+</#list>
+    return -1;
+}
+
+int ${helper.getCTypeName(type.name)}_num_values() {
+  return ${type.enumValues?size};
+}
+
+${helper.getCTypeName(type.name)} ${helper.getCTypeName(type.name)}_value_for_index(int index) {
+    switch(index) {
+    <#list helper.getUniqueEnumValues(type.enumValues) as enumValue>
+      case ${enumValue?index}: {
+        return ${enumValue.value};
+      }
+    </#list>
+      default: {
+        return -1;
+      }
+    }
+}
+    <#--
+        If this enum also defines constant values, output one function for each.
+        Each of these functions consist of a simple switch statement using the enum as switch-value
+        returning the constant for a given enum value.
+    -->
 <#if type.constantNames?has_content>
     <#list type.constantNames as constantName>
 
diff --git a/build-utils/language-c/src/main/resources/templates/c/enum-template-h.ftlh b/build-utils/language-c/src/main/resources/templates/c/enum-template-h.ftlh
index 65e6b2e..223294b 100644
--- a/build-utils/language-c/src/main/resources/templates/c/enum-template-h.ftlh
+++ b/build-utils/language-c/src/main/resources/templates/c/enum-template-h.ftlh
@@ -68,6 +68,11 @@
 // Get an empty NULL-struct
 ${helper.getCTypeName(type.name)} ${helper.getCTypeName(type.name)}_null();
 
+${helper.getCTypeName(type.name)} ${helper.getCTypeName(type.name)}_value_of(char* value_string);
+
+int ${helper.getCTypeName(type.name)}_num_values();
+
+${helper.getCTypeName(type.name)} ${helper.getCTypeName(type.name)}_value_for_index(int index);
 <#--
     If this enum also defines constant values, output one function for each.
     Each of these functions consist of a simple switch statement using the enum as switch-value
diff --git a/build-utils/language-c/src/main/resources/templates/c/pojo-template-c.ftlh b/build-utils/language-c/src/main/resources/templates/c/pojo-template-c.ftlh
index d1f3875..fb38e1a 100644
--- a/build-utils/language-c/src/main/resources/templates/c/pojo-template-c.ftlh
+++ b/build-utils/language-c/src/main/resources/templates/c/pojo-template-c.ftlh
@@ -105,8 +105,8 @@
 </#if>
 
 // Parse function.
-plc4c_return_code ${helper.getCTypeName(type.name)}_parse(plc4c_spi_read_buffer* buf, <#if type.parserArguments?has_content><#list type.parserArguments as parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type)}<#if !helper.isSimpleTypeReference(parserArgument.type)>*</#if> ${parserArgument.name}<#sep>, </#list>, </#if>${helper.getCTypeName(type.name)}** _message) {
-  uint16_t startPos = plc4c_spi_read_get_pos(buf);
+plc4c_return_code ${helper.getCTypeName(type.name)}_parse(plc4c_spi_read_buffer* io, <#if type.parserArguments?has_content><#list type.parserArguments as parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type)}<#if !helper.isSimpleTypeReference(parserArgument.type)>*</#if> ${parserArgument.name}<#sep>, </#list>, </#if>${helper.getCTypeName(type.name)}** _message) {
+  uint16_t startPos = plc4c_spi_read_get_pos(io);
   uint16_t curPos;
   plc4c_return_code _res = OK;
 
@@ -124,7 +124,7 @@
 <#if indentContent>  </#if>  // Array field (${arrayField.name})
             <#-- Only update curPos if the length expression uses it -->
             <#if arrayField.loopExpression.contains("curPos")>
-<#if indentContent>  </#if>  curPos = plc4c_spi_read_get_pos(buf) - startPos;
+<#if indentContent>  </#if>  curPos = plc4c_spi_read_get_pos(io) - startPos;
             </#if>
             <#-- In all other cases do we have to work with a list, that is later converted to an array -->
 <#if indentContent>  </#if>  plc4c_list* ${arrayField.name} = NULL;
@@ -139,49 +139,49 @@
 <#if indentContent>  </#if>    for(int curItem = 0; curItem < itemCount; curItem++) {
 <#if indentContent>  </#if>      <#if !helper.isSimpleTypeReference(arrayField.type)>bool lastItem = curItem == (itemCount - 1);</#if>
       <#-- Inizialize a local variable with the simple type (Intentionally keeping the java-style names so they can be used in expressions) -->
-<#if indentContent>  </#if>                <#if helper.isSimpleTypeReference(arrayField.type)>
+<#if helper.isSimpleTypeReference(arrayField.type)>
 <#if indentContent>  </#if>      ${helper.getLanguageTypeNameForTypeReference(arrayField.type)}* _value = malloc(sizeof(${helper.getLanguageTypeNameForTypeReference(arrayField.type)}));
 <#if indentContent>  </#if>      _res = ${helper.getReadBufferReadMethodCall(arrayField.type, "_value")};
 <#if indentContent>  </#if>      if(_res != OK) {
 <#if indentContent>  </#if>        return _res;
 <#if indentContent>  </#if>      }
 <#if indentContent>  </#if>      plc4c_utils_list_insert_head_value(${arrayField.name}, _value);
-                <#else>
+<#else>
       <#-- Inizialize a local variable with the complex type (Intentionally keeping the java-style names so they can be used in expressions) -->
-<#if indentContent>  </#if>      ${helper.getLanguageTypeNameForField(field)}* _value = NULL;
-<#if indentContent>  </#if>      _res = ${helper.getCTypeName(arrayField.type.name)}_parse(buf<#if field.params?has_content>, <#list field.params as parserTerm>${helper.toParseExpression(baseType, field, parserTerm, baseType.parserArguments)}<#sep>, </#sep></#list></#if>, (void*) &_value);
+<#if indentContent>  </#if>      ${helper.getCTypeName(arrayField.type.name)}* _value = NULL;
+<#if indentContent>  </#if>      _res = ${helper.getCTypeName(arrayField.type.name)}_parse(io<#if field.params?has_content>, <#list field.params as parserTerm>${helper.toParseExpression(baseType, field, parserTerm, baseType.parserArguments)}<#sep>, </#sep></#list></#if>, (void*) &_value);
 <#if indentContent>  </#if>      if(_res != OK) {
 <#if indentContent>  </#if>        return _res;
 <#if indentContent>  </#if>      }
 <#if indentContent>  </#if>      plc4c_utils_list_insert_head_value(${arrayField.name}, _value);
-                </#if>
+</#if>
 <#if indentContent>  </#if>    }
             <#-- For a length array, we read data till the read position of the buffer reaches a given position -->
             <#elseif helper.isLengthArrayField(field)>
 <#if indentContent>  </#if>    // Length array
 <#if indentContent>  </#if>    uint8_t _${arrayField.name}Length = ${helper.toParseExpression(baseType, arrayField, arrayField.loopExpression, baseType.parserArguments)};
-<#if indentContent>  </#if>    uint8_t ${arrayField.name}EndPos = plc4c_spi_read_get_pos(buf) + _${arrayField.name}Length;
-<#if indentContent>  </#if>    while(plc4c_spi_read_get_pos(buf) < ${arrayField.name}EndPos) {
+<#if indentContent>  </#if>    uint8_t ${arrayField.name}EndPos = plc4c_spi_read_get_pos(io) + _${arrayField.name}Length;
+<#if indentContent>  </#if>    while(plc4c_spi_read_get_pos(io) < ${arrayField.name}EndPos) {
                 <#-- Inizialize a local variable with the simple type (Intentionally keeping the java-style names so they can be used in expressions) -->
-                <#if helper.isSimpleTypeReference(arrayField.type)>
+<#if helper.isSimpleTypeReference(arrayField.type)>
 <#if indentContent>  </#if>      ${helper.getLanguageTypeNameForTypeReference(arrayField.type)} _value = ${helper.getNullValueForTypeReference(arrayField.type)};
 <#if indentContent>  </#if>      _res = ${helper.getReadBufferReadMethodCall(arrayField.type, "&_value")};
 <#if indentContent>  </#if>      if(_res != OK) {
 <#if indentContent>  </#if>        return _res;
 <#if indentContent>  </#if>      }
 <#if indentContent>  </#if>      plc4c_utils_list_insert_head_value(${arrayField.name}, &_value);
-                <#else>
+<#else>
                 <#-- Inizialize a local variable with the complex type (Intentionally keeping the java-style names so they can be used in expressions) -->
-<#if indentContent>  </#if>      ${helper.getLanguageTypeNameForField(field)}* _value = NULL;
-<#if indentContent>  </#if>      _res = ${helper.getCTypeName(arrayField.type.name)}_parse(buf<#if field.params?has_content>, <#list field.params as parserTerm>${helper.toParseExpression(baseType, field, parserTerm, baseType.parserArguments)}<#sep>, </#sep></#list></#if>, (void*) &_value);
+<#if indentContent>  </#if>      ${helper.getCTypeName(arrayField.type.name)}* _value = NULL;
+<#if indentContent>  </#if>      _res = ${helper.getCTypeName(arrayField.type.name)}_parse(io<#if field.params?has_content>, <#list field.params as parserTerm>${helper.toParseExpression(baseType, field, parserTerm, baseType.parserArguments)}<#sep>, </#sep></#list></#if>, (void*) &_value);
 <#if indentContent>  </#if>      if(_res != OK) {
 <#if indentContent>  </#if>        return _res;
 <#if indentContent>  </#if>      }
 <#if indentContent>  </#if>      plc4c_utils_list_insert_head_value(${arrayField.name}, _value);
-                </#if>
+</#if>
                 <#-- After parsing, update the current position, but only if it's needed -->
                 <#if arrayField.loopExpression.contains("curPos")>
-<#if indentContent>  </#if>      curPos = plc4c_spi_read_get_pos(buf) - startPos;
+<#if indentContent>  </#if>      curPos = plc4c_spi_read_get_pos(io) - startPos;
                 </#if>
 <#if indentContent>  </#if>    }
             <#-- A terminated array keeps on reading data as long as the termination expression evaluates to false -->
@@ -189,25 +189,25 @@
 <#if indentContent>  </#if>    // Terminated array
 <#if indentContent>  </#if>    while(!((boolean) (${helper.toParseExpression(baseType, arrayField, arrayField.loopExpression, baseType.parserArguments)}))) {
             <#-- Inizialize a local variable with the simple type (Intentionally keeping the java-style names so they can be used in expressions) -->
-                <#if helper.isSimpleTypeReference(arrayField.type)>
+<#if helper.isSimpleTypeReference(arrayField.type)>
 <#if indentContent>  </#if>      ${helper.getLanguageTypeNameForTypeReference(arrayField.type)} _value = ${helper.getNullValueForTypeReference(arrayField.type)};
 <#if indentContent>  </#if>      _res = ${helper.getReadBufferReadMethodCall(arrayField.type, "&_value")};
 <#if indentContent>  </#if>      if(_res != OK) {
 <#if indentContent>  </#if>        return _res;
 <#if indentContent>  </#if>      }
 <#if indentContent>  </#if>      plc4c_utils_list_insert_head_value(${arrayField.name}, &_value);
-                <#else>
+<#else>
                 <#-- Inizialize a local variable with the complex type (Intentionally keeping the java-style names so they can be used in expressions) -->
-<#if indentContent>  </#if>      ${helper.getLanguageTypeNameForField(field)}* _value = NULL;
-<#if indentContent>  </#if>      _res = ${helper.getCTypeName(arrayField.type.name)}_parse(buf<#if field.params?has_content>, <#list field.params as parserTerm>${helper.toParseExpression(baseType, field, parserTerm, baseType.parserArguments)}<#sep>, </#sep></#list></#if>, (void*) &_value);
+<#if indentContent>  </#if>      ${helper.getCTypeName(arrayField.type.name)}* _value = NULL;
+<#if indentContent>  </#if>      _res = ${helper.getCTypeName(arrayField.type.name)}_parse(io<#if field.params?has_content>, <#list field.params as parserTerm>${helper.toParseExpression(baseType, field, parserTerm, baseType.parserArguments)}<#sep>, </#sep></#list></#if>, (void*) &_value);
 <#if indentContent>  </#if>      if(_res != OK) {
 <#if indentContent>  </#if>        return _res;
 <#if indentContent>  </#if>      }
 <#if indentContent>  </#if>      plc4c_utils_list_insert_head_value(${arrayField.name}, _value);
-                </#if>
+</#if>
               <#-- After parsing, update the current position, but only if it's needed -->
               <#if arrayField.loopExpression.contains("curPos")>
-<#if indentContent>  </#if>      curPos = plc4c_spi_read_get_pos(buf) - startPos;
+<#if indentContent>  </#if>      curPos = plc4c_spi_read_get_pos(io) - startPos;
               </#if>
 <#if indentContent>  </#if>    }
             </#if>
@@ -221,7 +221,7 @@
 <#if indentContent>  </#if>  // Checksum Field (${checksumField.name})
 <#if indentContent>  </#if>  {
 <#if indentContent>  </#if>    // Create an array of all the bytes read in this message element so far.
-<#if indentContent>  </#if>    byte[] checksumRawData = plc4c_spi_read_get_bytes(buf, startPos, plc4c_spi_read_get_pos(buf));
+<#if indentContent>  </#if>    byte[] checksumRawData = plc4c_spi_read_get_bytes(io, startPos, plc4c_spi_read_get_pos(io));
 <#if indentContent>  </#if>    ${helper.getLanguageTypeNameForField(field)} _checksumRef = ${helper.getNullValueForTypeReference(checksumField.type)};
 <#if indentContent>  </#if>    _res = ${helper.getReadBufferReadMethodCall(checksumField.type, "&_checksumRef")};
 <#if indentContent>  </#if>    if(_res != OK) {
@@ -299,7 +299,7 @@
 
 <#if indentContent>  </#if>  // Optional Field (${optionalField.name}) (Can be skipped, if a given expression evaluates to false)
             <#if optionalField.conditionExpression.contains("curPos")>
-<#if indentContent>  </#if>  curPos = plc4c_spi_read_get_pos(buf) - startPos;
+<#if indentContent>  </#if>  curPos = plc4c_spi_read_get_pos(io) - startPos;
             </#if>
 <#if indentContent>  </#if>  ${helper.getLanguageTypeNameForField(field)}* ${optionalField.name} = NULL;
 <#if indentContent>  </#if>  if(${helper.toParseExpression(baseType, field, optionalField.conditionExpression, baseType.parserArguments)}) {
@@ -311,7 +311,7 @@
 <#if indentContent>  </#if>    *${optionalField.name} = ${helper.getNullValueForTypeReference(optionalField.type)};
 <#if indentContent>  </#if>    _res = ${helper.getReadBufferReadMethodCall(optionalField.type, optionalField.name)};
         <#else>
-<#if indentContent>  </#if>    _res = ${helper.getCTypeName(optionalField.type.name)}_parse(buf<#if optionalField.params?has_content>, <#list optionalField.params as parserTerm>${helper.toParseExpression(baseType, optionalField, parserTerm, baseType.parserArguments)}<#sep>, </#sep></#list></#if>, &${optionalField.name});
+<#if indentContent>  </#if>    _res = ${helper.getCTypeName(optionalField.type.name)}_parse(io<#if optionalField.params?has_content>, <#list optionalField.params as parserTerm>${helper.toParseExpression(baseType, optionalField, parserTerm, baseType.parserArguments)}<#sep>, </#sep></#list></#if>, &${optionalField.name});
         </#if>
 <#if indentContent>  </#if>    if(_res != OK) {
 <#if indentContent>  </#if>      return _res;
@@ -327,7 +327,7 @@
 
 <#if indentContent>  </#if>  // Padding Field (padding)
 <#if indentContent>  </#if>  {
-<#if indentContent>  </#if>    int _timesPadding = (int) ((plc4c_spi_read_has_more(buf, ${helper.getNumBits(paddingField.type)})) && (${helper.toParseExpression(baseType, paddingField, paddingField.paddingCondition, baseType.parserArguments)}));
+<#if indentContent>  </#if>    int _timesPadding = (int) ((plc4c_spi_read_has_more(io, ${helper.getNumBits(paddingField.type)})) && (${helper.toParseExpression(baseType, paddingField, paddingField.paddingCondition, baseType.parserArguments)}));
 <#if indentContent>  </#if>    while (_timesPadding-- > 0) {
 <#if indentContent>  </#if>      // Just read the padding data and ignore it
 <#if indentContent>  </#if>      ${helper.getLanguageTypeNameForField(field)} _paddingValue = ${helper.getNullValueForTypeReference(paddingField.type)};
@@ -365,7 +365,7 @@
             <#else>
             <#-- Inizialize a local variable with the complex type (Intentionally keeping the java-style names so they can be used in expressions) -->
 <#if indentContent>  </#if>  ${helper.getLanguageTypeNameForField(field)}* ${simpleField.name};
-<#if indentContent>  </#if>  _res = ${helper.getCTypeName(simpleField.type.name)}_parse(buf<#if simpleField.params?has_content>, <#list simpleField.params as parserTerm>${helper.toParseExpression(baseType, simpleField, parserTerm, baseType.parserArguments)}<#sep>, </#sep></#list></#if>, (void*) &${simpleField.name});
+<#if indentContent>  </#if>  _res = ${helper.getCTypeName(simpleField.type.name)}_parse(io<#if simpleField.params?has_content>, <#list simpleField.params as parserTerm>${helper.toParseExpression(baseType, simpleField, parserTerm, baseType.parserArguments)}<#sep>, </#sep></#list></#if>, (void*) &${simpleField.name});
             </#if>
 <#if indentContent>  </#if>  if(_res != OK) {
 <#if indentContent>  </#if>    return _res;
@@ -402,7 +402,7 @@
   return OK;
 }
 
-plc4c_return_code ${helper.getCTypeName(type.name)}_serialize(plc4c_spi_write_buffer* buf, ${helper.getCTypeName(type.name)}* _message<#if helper.getSerializerArguments(type.parserArguments)?has_content>, <#list helper.getSerializerArguments(type.parserArguments) as parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type)} ${parserArgument.name}<#sep>, </#sep></#list></#if>) {
+plc4c_return_code ${helper.getCTypeName(type.name)}_serialize(plc4c_spi_write_buffer* io, ${helper.getCTypeName(type.name)}* _message<#if helper.getSerializerArguments(type.parserArguments)?has_content>, <#list helper.getSerializerArguments(type.parserArguments) as parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type)} ${parserArgument.name}<#sep>, </#sep></#list></#if>) {
   plc4c_return_code _res = OK;
 <#macro fieldSerializer baseType field indentContent>
     <#switch field.typeName>
@@ -419,7 +419,7 @@
             <#if helper.isSimpleTypeReference(arrayField.type)>
 <#if indentContent>    </#if>      ${helper.getWriteBufferWriteMethodCall(arrayField.type, "*_value")};
             <#else>
-<#if indentContent>    </#if>      _res = ${helper.getCTypeName(arrayField.type.name)}_serialize(buf, (void*) _value<#if helper.getSerializerTerms(field.params)?has_content>, <#list helper.getSerializerTerms(field.params) as serializerTerm>${helper.toSerializationExpression(baseType, field, serializerTerm, baseType.parserArguments)}<#sep>, </#sep></#list></#if>);
+<#if indentContent>    </#if>      _res = ${helper.getCTypeName(arrayField.type.name)}_serialize(io, (void*) _value<#if helper.getSerializerTerms(field.params)?has_content>, <#list helper.getSerializerTerms(field.params) as serializerTerm>${helper.toSerializationExpression(baseType, field, serializerTerm, baseType.parserArguments)}<#sep>, </#sep></#list></#if>);
 <#if indentContent>    </#if>      if(_res != OK) {
 <#if indentContent>    </#if>        return _res;
 <#if indentContent>    </#if>      }
@@ -434,7 +434,7 @@
 <#if indentContent>    </#if>  // Checksum Field (${checksumField.name})
 <#if indentContent>    </#if>  {
 <#if indentContent>    </#if>    // Create an array of all the bytes read in this message element so far.
-<#if indentContent>    </#if>    byte[] checksumRawData = plc4c_spi_read_get_bytes(buf, startPos, plc4c_spi_read_get_pos(buf));
+<#if indentContent>    </#if>    byte[] checksumRawData = plc4c_spi_read_get_bytes(io, startPos, plc4c_spi_read_get_pos(io));
 <#if indentContent>    </#if>    ${helper.getLanguageTypeNameForField(field)} _checksumRef = ${helper.getReadBufferReadMethodCall(checksumField.type)};
 <#if indentContent>    </#if>    ${helper.getLanguageTypeNameForField(field)} _checksum = (${helper.getLanguageTypeNameForField(field)}) (${helper.toParseExpression(baseType, checksumField, checksumField.checksumExpression, baseType.parserArguments)});
 <#if indentContent>    </#if>    if(_checksum != _checksumRef) {
@@ -488,7 +488,7 @@
             <#if helper.isSimpleTypeReference(manualField.type)>
 <#if indentContent>    </#if>  _res = ${helper.getWriteBufferWriteMethodCall(manualField.type, "(${helper.getLanguageTypeNameForTypeReference(arrayField.type)}*) plc4c_utils_list_get_value(_message->" + helper.getFieldName(baseType, arrayField))};
             <#else>
-<#if indentContent>    </#if>  _res = ${helper.getCTypeName(manualField.type.name)}_serialize(buf, (void*) &_value);
+<#if indentContent>    </#if>  _res = ${helper.getCTypeName(manualField.type.name)}_serialize(io, (void*) &_value);
             </#if>
 <#if indentContent>    </#if>  if(_res != OK) {
 <#if indentContent>    </#if>    return _res;
@@ -502,7 +502,7 @@
             <#if helper.isSimpleTypeReference(optionalField.type)>
 <#if indentContent>    </#if>    _res = ${helper.getWriteBufferWriteMethodCall(optionalField.type, "*_message->" + helper.getFieldName(baseType, optionalField))};
             <#else>
-<#if indentContent>    </#if>    _res = ${helper.getCTypeName(optionalField.type.name)}_serialize(buf, _message-><@fieldName baseType=baseType field=optionalField/>);
+<#if indentContent>    </#if>    _res = ${helper.getCTypeName(optionalField.type.name)}_serialize(io, _message-><@fieldName baseType=baseType field=optionalField/>);
             </#if>
 <#if indentContent>    </#if>    if(_res != OK) {
 <#if indentContent>    </#if>      return _res;
@@ -543,7 +543,7 @@
             <#if helper.isSimpleTypeReference(simpleField.type)>
 <#if indentContent>    </#if>  _res = ${helper.getWriteBufferWriteMethodCall(simpleField.type, "_message->" + helper.getFieldName(baseType, simpleField))};
             <#else>
-<#if indentContent>    </#if>  _res = ${helper.getCTypeName(simpleField.type.name)}_serialize(buf, _message-><@fieldName baseType=baseType field=simpleField/>);
+<#if indentContent>    </#if>  _res = ${helper.getCTypeName(simpleField.type.name)}_serialize(io, _message-><@fieldName baseType=baseType field=simpleField/>);
             </#if>
 <#if indentContent>    </#if>  if(_res != OK) {
 <#if indentContent>    </#if>    return _res;
diff --git a/build-utils/language-c/src/main/resources/templates/c/pojo-template-h.ftlh b/build-utils/language-c/src/main/resources/templates/c/pojo-template-h.ftlh
index 6333bea..fc501e1 100644
--- a/build-utils/language-c/src/main/resources/templates/c/pojo-template-h.ftlh
+++ b/build-utils/language-c/src/main/resources/templates/c/pojo-template-h.ftlh
@@ -150,12 +150,12 @@
 <#--
     Define the parse-method for elements of this tpye
 -->
-plc4c_return_code ${helper.getCTypeName(type.name)}_parse(plc4c_spi_read_buffer* buf, <#if type.parserArguments?has_content><#list type.parserArguments as parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type)}<#if !helper.isSimpleTypeReference(parserArgument.type)>*</#if> ${parserArgument.name}<#sep>, </#list>, </#if>${helper.getCTypeName(type.name)}** message);
+plc4c_return_code ${helper.getCTypeName(type.name)}_parse(plc4c_spi_read_buffer* io, <#if type.parserArguments?has_content><#list type.parserArguments as parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type)}<#if !helper.isSimpleTypeReference(parserArgument.type)>*</#if> ${parserArgument.name}<#sep>, </#list>, </#if>${helper.getCTypeName(type.name)}** message);
 
 <#--
     Define the serialize-method for elements of this tpye
 -->
-plc4c_return_code ${helper.getCTypeName(type.name)}_serialize(plc4c_spi_write_buffer* buf, ${helper.getCTypeName(type.name)}* message<#if helper.getSerializerArguments(type.parserArguments)?has_content>, <#list helper.getSerializerArguments(type.parserArguments) as parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type)} ${parserArgument.name}<#sep>, </#sep></#list></#if>);
+plc4c_return_code ${helper.getCTypeName(type.name)}_serialize(plc4c_spi_write_buffer* io, ${helper.getCTypeName(type.name)}* message<#if helper.getSerializerArguments(type.parserArguments)?has_content>, <#list helper.getSerializerArguments(type.parserArguments) as parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type)} ${parserArgument.name}<#sep>, </#sep></#list></#if>);
 
 uint16_t ${helper.getCTypeName(type.name)}_length_in_bytes(${helper.getCTypeName(type.name)}* message);
 
diff --git a/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/definitions/DefaultDataIoTypeDefinition.java b/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/definitions/DefaultDataIoTypeDefinition.java
index bbc1480..0e6e2fd 100644
--- a/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/definitions/DefaultDataIoTypeDefinition.java
+++ b/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/definitions/DefaultDataIoTypeDefinition.java
@@ -18,11 +18,9 @@
 */
 package org.apache.plc4x.plugins.codegenerator.language.mspec.model.definitions;
 
-import org.apache.plc4x.plugins.codegenerator.language.mspec.model.references.DefaultComplexTypeReference;
 import org.apache.plc4x.plugins.codegenerator.types.definitions.Argument;
 import org.apache.plc4x.plugins.codegenerator.types.definitions.DataIoTypeDefinition;
 import org.apache.plc4x.plugins.codegenerator.types.fields.SwitchField;
-import org.apache.plc4x.plugins.codegenerator.types.references.TypeReference;
 
 public class DefaultDataIoTypeDefinition extends DefaultTypeDefinition implements DataIoTypeDefinition {
 
diff --git a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/field/S7Field.java b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/field/S7Field.java
index 6cdd590..c0d15b2 100644
--- a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/field/S7Field.java
+++ b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/field/S7Field.java
@@ -55,10 +55,10 @@
         Pattern.compile("^%DB(?<blockNumber>\\d{1,5}):(?<byteOffset>\\d{1,7})(.(?<bitOffset>[0-7]))?:(?<dataType>[a-zA-Z_]+)(\\[(?<numElements>\\d+)])?");
 
     private static final Pattern DATA_BLOCK_STRING_ADDRESS_PATTERN =
-        Pattern.compile("^%DB(?<blockNumber>\\d{1,5}).DB(?<transferSizeCode>[XBWD]?)(?<byteOffset>\\d{1,7})(.(?<bitOffset>[0-7]))?:STRING\\((?<stringLength>\\d{1,3})\\)(\\[(?<numElements>\\d+)])?");
+        Pattern.compile("^%DB(?<blockNumber>\\d{1,5}).DB(?<transferSizeCode>[XBWD]?)(?<byteOffset>\\d{1,7}):STRING\\((?<stringLength>\\d{1,3})\\)(\\[(?<numElements>\\d+)])?");
 
     private static final Pattern DATA_BLOCK_STRING_SHORT_PATTERN =
-        Pattern.compile("^%DB(?<blockNumber>\\d{1,5}):(?<byteOffset>\\d{1,7})(.(?<bitOffset>[0-7]))?:STRING\\((?<stringLength>\\d{1,3})\\)(\\[(?<numElements>\\d+)])?");
+        Pattern.compile("^%DB(?<blockNumber>\\d{1,5}):(?<byteOffset>\\d{1,7}):STRING\\((?<stringLength>\\d{1,3})\\)(\\[(?<numElements>\\d+)])?");
 
     private static final Pattern PLC_PROXY_ADDRESS_PATTERN =
         Pattern.compile("[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}");
@@ -190,14 +190,34 @@
         } else if ((matcher = DATA_BLOCK_STRING_ADDRESS_PATTERN.matcher(fieldString)).matches()) {
             TransportSize dataType = TransportSize.STRING;
             int stringLength = Integer.parseInt(matcher.group(STRING_LENGTH));
+            MemoryArea memoryArea = getMemoryAreaForShortName(matcher.group(MEMORY_AREA));
+            Short transferSizeCode = getSizeCode(matcher.group(TRANSFER_SIZE_CODE));
+            int byteOffset = checkByteOffset(Integer.parseInt(matcher.group(BYTE_OFFSET)));
+            byte bitOffset = 0;
+            if (matcher.group(BIT_OFFSET) != null) {
+                bitOffset = Byte.parseByte(matcher.group(BIT_OFFSET));
+            } else if (dataType == TransportSize.BOOL) {
+                throw new PlcInvalidFieldException("Expected bit offset for BOOL parameters.");
+            }
+            int numElements = 1;
+            if (matcher.group(NUM_ELEMENTS) != null) {
+                numElements = Integer.parseInt(matcher.group(NUM_ELEMENTS));
+            }
+
+            if ((transferSizeCode != null) && (dataType.getSizeCode() != transferSizeCode)) {
+                throw new PlcInvalidFieldException("Transfer size code '" + transferSizeCode +
+                    "' doesn't match specified data type '" + dataType.name() + "'");
+            }
+
+            return new S7Field(dataType, memoryArea, (short) 0, byteOffset, bitOffset, numElements);
+        } else if ((matcher = DATA_BLOCK_STRING_ADDRESS_PATTERN.matcher(fieldString)).matches()) {
+            TransportSize dataType = TransportSize.STRING;
+            int stringLength = Integer.parseInt(matcher.group(STRING_LENGTH));
             MemoryArea memoryArea = MemoryArea.DATA_BLOCKS;
             Short transferSizeCode = getSizeCode(matcher.group(TRANSFER_SIZE_CODE));
             int blockNumber = checkDatablockNumber(Integer.parseInt(matcher.group(BLOCK_NUMBER)));
             int byteOffset = checkByteOffset(Integer.parseInt(matcher.group(BYTE_OFFSET)));
             byte bitOffset = 0;
-            if (matcher.group(BIT_OFFSET) != null) {
-                bitOffset = Byte.parseByte(matcher.group(BIT_OFFSET));
-            }
             int numElements = 1;
             if(matcher.group(NUM_ELEMENTS) != null) {
                 numElements = Integer.parseInt(matcher.group(NUM_ELEMENTS));
@@ -207,9 +227,6 @@
                 throw new PlcInvalidFieldException("Transfer size code '" + transferSizeCode +
                     "' doesn't match specified data type '" + dataType.name() + "'");
             }
-            if (bitOffset != 0) {
-                throw new PlcInvalidFieldException("A bit offset other than 0 is only supported for type BOOL");
-            }
 
             return new S7StringField(dataType, memoryArea, blockNumber,
                 byteOffset, bitOffset, numElements, stringLength);
@@ -220,16 +237,10 @@
             int blockNumber = checkDatablockNumber(Integer.parseInt(matcher.group(BLOCK_NUMBER)));
             int byteOffset = checkByteOffset(Integer.parseInt(matcher.group(BYTE_OFFSET)));
             byte bitOffset = 0;
-            if (matcher.group(BIT_OFFSET) != null) {
-                bitOffset = Byte.parseByte(matcher.group(BIT_OFFSET));
-            }
             int numElements = 1;
             if(matcher.group(NUM_ELEMENTS) != null) {
                 numElements = Integer.parseInt(matcher.group(NUM_ELEMENTS));
             }
-            if (bitOffset != 0) {
-                throw new PlcInvalidFieldException("A bit offset other than 0 is only supported for type BOOL");
-            }
 
             return new S7StringField(dataType, memoryArea, blockNumber,
                 byteOffset, bitOffset, numElements, stringLength);
@@ -254,9 +265,6 @@
                 throw new PlcInvalidFieldException("Transfer size code '" + transferSizeCode +
                     "' doesn't match specified data type '" + dataType.name() + "'");
             }
-            if ((dataType != TransportSize.BOOL) && bitOffset != 0) {
-                throw new PlcInvalidFieldException("A bit offset other than 0 is only supported for type BOOL");
-            }
 
             return new S7Field(dataType, memoryArea, blockNumber, byteOffset, bitOffset, numElements);
         } else if ((matcher = DATA_BLOCK_SHORT_PATTERN.matcher(fieldString)).matches()) {
@@ -275,10 +283,6 @@
                 numElements = Integer.parseInt(matcher.group(NUM_ELEMENTS));
             }
 
-            if ((dataType != TransportSize.BOOL) && bitOffset != 0) {
-                throw new PlcInvalidFieldException("A bit offset other than 0 is only supported for type BOOL");
-            }
-
             return new S7Field(dataType, memoryArea, blockNumber, byteOffset, bitOffset, numElements);
         } else if (PLC_PROXY_ADDRESS_PATTERN.matcher(fieldString).matches()) {
             try {
diff --git a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7ProtocolLogic.java b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7ProtocolLogic.java
index 6a58630..133cffc 100644
--- a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7ProtocolLogic.java
+++ b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7ProtocolLogic.java
@@ -306,11 +306,14 @@
     }
 
     private TPKTPacket createIdentifyRemoteMessage() {
-        S7MessageUserData identifyRemoteMessage = new S7MessageUserData(1, new S7ParameterUserData(new S7ParameterUserDataItem[]{
-            new S7ParameterUserDataItemCPUFunctions((short) 0x11, (byte) 0x4, (byte) 0x4, (short) 0x01, (short) 0x00, null, null, null)
-        }), new S7PayloadUserData(new S7PayloadUserDataItem[]{
-            new S7PayloadUserDataItemCpuFunctionReadSzlRequest(DataTransportErrorCode.OK, DataTransportSize.OCTET_STRING, new SzlId(SzlModuleTypeClass.CPU, (byte) 0x00, SzlSublist.MODULE_IDENTIFICATION), 0x0000)
-        }));
+        S7MessageUserData identifyRemoteMessage = new S7MessageUserData(1,
+            new S7ParameterUserData(new S7ParameterUserDataItem[]{
+                new S7ParameterUserDataItemCPUFunctions((short) 0x11, (byte) 0x4, (byte) 0x4, (short) 0x01, (short) 0x00, null, null, null)
+            }),
+            new S7PayloadUserData(new S7PayloadUserDataItem[]{
+                new S7PayloadUserDataItemCpuFunctionReadSzlRequest(DataTransportErrorCode.OK, DataTransportSize.OCTET_STRING, new SzlId(SzlModuleTypeClass.CPU, (byte) 0x00, SzlSublist.MODULE_IDENTIFICATION), 0x0000)
+            })
+        );
         COTPPacketData cotpPacketData = new COTPPacketData(null, identifyRemoteMessage, true, (short) 2);
         return new TPKTPacket(cotpPacketData);
     }
@@ -603,7 +606,7 @@
         }
         if(transportSize == TransportSize.STRING) {
             transportSize = TransportSize.CHAR;
-            int stringLength = (s7Field instanceof S7StringField) ? ((S7StringField) s7Field).getStringLength() : 254;
+            int stringLength = ((S7StringField) s7Field).getStringLength();
             numElements = numElements * (stringLength + 2);
         }
         return new S7AddressAny(transportSize, numElements, s7Field.getBlockNumber(),
diff --git a/protocols/modbus/src/main/resources/protocols/modbus/modbus.mspec b/protocols/modbus/src/main/resources/protocols/modbus/modbus.mspec
index a0dc2df..0abe234 100644
--- a/protocols/modbus/src/main/resources/protocols/modbus/modbus.mspec
+++ b/protocols/modbus/src/main/resources/protocols/modbus/modbus.mspec
@@ -249,7 +249,7 @@
 [type 'ModbusPDUReadFileRecordResponseItem'
     [implicit   uint 8     'dataLength'     'COUNT(data) + 1']
     [simple     uint 8     'referenceType']
-    [array      int 8    'data'             length  'dataLength - 1']
+    [array      int 8      'data'           length  'dataLength - 1']
 ]
 
 [type 'ModbusPDUWriteFileRecordRequestItem'
diff --git a/sandbox/plc4c/api/include/plc4c/connection.h b/sandbox/plc4c/api/include/plc4c/connection.h
index c1e8e47..2818add 100644
--- a/sandbox/plc4c/api/include/plc4c/connection.h
+++ b/sandbox/plc4c/api/include/plc4c/connection.h
@@ -186,12 +186,20 @@
 /**
  * Sets a plc4c_driver for a given connection
  * @param connection plc4c_connection
- * @param plc4c_driver
+ * @param plc4c_driver driver
  */
 void plc4c_connection_set_driver(plc4c_connection *connection,
                                  plc4c_driver *driver);
 
 /**
+ * Sets the configuration for a given connection.
+ *
+ * @param connection plc4c connection
+ * @param configuration configuration
+ */
+void plc4c_connection_set_configuration(plc4c_connection *connection,
+                                        void *configuration);
+/**
  * Check if an error occurred while connecting.
  *
  * @param connection the connection.
diff --git a/sandbox/plc4c/api/include/plc4c/data.h b/sandbox/plc4c/api/include/plc4c/data.h
index d35e77f..5facf13 100644
--- a/sandbox/plc4c/api/include/plc4c/data.h
+++ b/sandbox/plc4c/api/include/plc4c/data.h
@@ -40,49 +40,63 @@
  * @param b the bool value
  * @return pointer to plc4c_data
  */
-plc4c_data *plc4c_data_create_boolean_data(bool b);
+plc4c_data *plc4c_data_create_bool_data(bool b);
 
 /**
  * Creates a plc4c_data with char
  * @param c the char value
  * @return pointer to plc4c_data
  */
-plc4c_data *plc4c_data_create_char_data(char c);
+plc4c_data *plc4c_data_create_int8_t_data(int8_t c);
 
 /**
  * Creates a plc4c_data with unsigned char
  * @param uc the unsigned char value
  * @return pointer to plc4c_data
  */
-plc4c_data *plc4c_data_create_uchar_data(unsigned char uc);
+plc4c_data *plc4c_data_create_uint8_t_data(uint8_t uc);
 
 /**
  * Creates a plc4c_data with short
  * @param s the short value
  * @return pointer to plc4c_data
  */
-plc4c_data *plc4c_data_create_short_data(short s);
+plc4c_data *plc4c_data_create_int16_t_data(int16_t s);
 
 /**
  * Creates a plc4c_data with unsigned short
  * @param us the unsigned short value
  * @return pointer to plc4c_data
  */
-plc4c_data *plc4c_data_create_ushort_data(unsigned short us);
+plc4c_data *plc4c_data_create_uint16_t_data(uint16_t us);
 
 /**
  * Creates a plc4c_data with int
  * @param i the int value
  * @return pointer to plc4c_data
  */
-plc4c_data *plc4c_data_create_int_data(int i);
+plc4c_data *plc4c_data_create_int32_t_data(int32_t i);
 
 /**
  * Creates a plc4c_data with unsigned int
  * @param ui the unsigned int value
  * @return pointer to plc4c_data
  */
-plc4c_data *plc4c_data_create_uint_data(unsigned int ui);
+plc4c_data *plc4c_data_create_uint32_t_data(uint32_t ui);
+
+/**
+ * Creates a plc4c_data with int
+ * @param i the int value
+ * @return pointer to plc4c_data
+ */
+plc4c_data *plc4c_data_create_int64_t_data(int64_t i);
+
+/**
+ * Creates a plc4c_data with unsigned int
+ * @param ui the unsigned int value
+ * @return pointer to plc4c_data
+ */
+plc4c_data *plc4c_data_create_uint64_t_data(uint64_t ui);
 
 /**
  * Creates a plc4c_data with void*
@@ -99,6 +113,13 @@
 plc4c_data *plc4c_data_create_float_data(float f);
 
 /**
+ * Creates a plc4c_data with float
+ * @param f the float value
+ * @return pointer to plc4c_data
+ */
+plc4c_data *plc4c_data_create_double_data(double d);
+
+/**
  * Creates a plc4c_data with char*
  * @param size the size of the string
  * @param s the char* value
diff --git a/sandbox/plc4c/api/include/plc4c/read.h b/sandbox/plc4c/api/include/plc4c/read.h
index 556943d..ef44331 100644
--- a/sandbox/plc4c/api/include/plc4c/read.h
+++ b/sandbox/plc4c/api/include/plc4c/read.h
@@ -37,6 +37,7 @@
  * @return return code
  */
 plc4c_return_code plc4c_read_request_add_item(plc4c_read_request *read_request,
+                                              char *field_name,
                                               char *address);
 
 /**
diff --git a/sandbox/plc4c/api/include/plc4c/types.h b/sandbox/plc4c/api/include/plc4c/types.h
index 7a0fd48..fc10004 100644
--- a/sandbox/plc4c/api/include/plc4c/types.h
+++ b/sandbox/plc4c/api/include/plc4c/types.h
@@ -33,6 +33,7 @@
   OK,
   NO_MEMORY,
   INVALID_CONNECTION_STRING,
+  INVALID_ADDRESS,
   NON_MATCHING_LISTS,
   INVALID_LIST_SIZE,
   NULL_VALUE,
@@ -48,9 +49,12 @@
   NO_TRANSPORT_AVAILABLE,
   UNKNOWN_TRANSPORT,
 
+  ALREADY_CONNECTED,
+
   PARSE_ERROR,
 
   UNKNOWN_ERROR,
+  CONNECTION_ERROR,
   INTERNAL_ERROR,
   NOT_IMPLEMENTED
 } plc4c_return_code;
@@ -76,7 +80,10 @@
   PLC4C_USHORT,
   PLC4C_INT,
   PLC4C_UINT,
+  PLC4C_LINT,
+  PLC4C_ULINT,
   PLC4C_FLOAT,
+  PLC4C_DOUBLE,
   PLC4C_STRING_POINTER,
   PLC4C_CONSTANT_STRING,
   PLC4C_VOID_POINTER
diff --git a/sandbox/plc4c/drivers/modbus/CMakeLists.txt b/sandbox/plc4c/drivers/modbus/CMakeLists.txt
index aad5406..08e206b 100644
--- a/sandbox/plc4c/drivers/modbus/CMakeLists.txt
+++ b/sandbox/plc4c/drivers/modbus/CMakeLists.txt
@@ -18,14 +18,19 @@
 ]]
 
 include_directories("include" "../../api/include" "../../spi/include"
-    "${PLC4C_ROOT_DIR}/generated-sources/modbus/includes")
-
-# Add the sources
-file(GLOB sources "src/*.c")
+    "../../generated-sources/modbus/include")
 
 # Add the generated sources
-file(GLOB generatedSources "${PLC4C_ROOT_DIR}/generated-sources/modbus/src/*.c")
+file(GLOB generatedSources "../../generated-sources/modbus/src/*.c")
 
-add_library(plc4c-driver-modbus ${sources} ${generatedSources})
+add_library(plc4c-driver-modbus
+        src/driver_modbus.c
+        src/driver_modbus_encode_decode.c
+        src/driver_modbus_packets.c
+        src/driver_modbus_sm_connect.c
+        src/driver_modbus_sm_disconnect.c
+        src/driver_modbus_sm_read.c
+        src/driver_modbus_sm_write.c
+        ${generatedSources})
 
 target_link_libraries(plc4c-driver-modbus plc4c-spi ${CMAKE_DL_LIBS})
\ No newline at end of file
diff --git a/sandbox/plc4c/drivers/modbus/include/plc4c/driver_modbus.h b/sandbox/plc4c/drivers/modbus/include/plc4c/driver_modbus.h
index 5fa584c..32868c2 100644
--- a/sandbox/plc4c/drivers/modbus/include/plc4c/driver_modbus.h
+++ b/sandbox/plc4c/drivers/modbus/include/plc4c/driver_modbus.h
@@ -16,8 +16,8 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-#ifndef PLC4C_DRIVER_S7_H_
-#define PLC4C_DRIVER_S7_H_
+#ifndef PLC4C_DRIVER_MODBUS_H_
+#define PLC4C_DRIVER_MODBUS_H_
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -29,4 +29,4 @@
 #ifdef __cplusplus
 }
 #endif
-#endif  // PLC4C_DRIVER_S7_H_
\ No newline at end of file
+#endif  // PLC4C_DRIVER_MODBUS_H_
\ No newline at end of file
diff --git a/sandbox/plc4c/drivers/modbus/include/plc4c/driver_modbus_packets.h b/sandbox/plc4c/drivers/modbus/include/plc4c/driver_modbus_packets.h
new file mode 100644
index 0000000..79a8d51
--- /dev/null
+++ b/sandbox/plc4c/drivers/modbus/include/plc4c/driver_modbus_packets.h
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#ifndef PLC4C_DRIVER_MODBUS_PACKETS_H_
+#define PLC4C_DRIVER_MODBUS_PACKETS_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <plc4c/types.h>
+#include "modbus_tcp_adu.h"
+
+plc4c_return_code plc4c_driver_modbus_send_packet(
+    plc4c_connection* connection,
+    plc4c_modbus_read_write_modbus_tcp_adu* packet);
+plc4c_return_code plc4c_driver_modbus_receive_packet(
+    plc4c_connection* connection,
+    plc4c_modbus_read_write_modbus_tcp_adu** packet);
+
+plc4c_return_code plc4c_driver_modbus_create_modbus_read_request(
+    plc4c_read_request* read_request,
+    plc4c_modbus_read_write_modbus_tcp_adu** modbus_read_request_packet);
+plc4c_return_code plc4c_driver_modbus_create_modbus_write_request(
+    plc4c_write_request* write_request,
+    plc4c_modbus_read_write_modbus_tcp_adu** modbus_read_request_packet);
+
+#ifdef __cplusplus
+}
+#endif
+#endif  // PLC4C_DRIVER_MODBUS_PACKETS_H_
\ No newline at end of file
diff --git a/sandbox/plc4c/drivers/modbus/include/plc4c/driver_modbus_sm.h b/sandbox/plc4c/drivers/modbus/include/plc4c/driver_modbus_sm.h
new file mode 100644
index 0000000..faabe84
--- /dev/null
+++ b/sandbox/plc4c/drivers/modbus/include/plc4c/driver_modbus_sm.h
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#ifndef PLC4C_DRIVER_MODBUS_SM_H_
+#define PLC4C_DRIVER_MODBUS_SM_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <plc4c/types.h>
+#include <plc4c/spi/types_private.h>
+
+plc4c_return_code plc4c_driver_modbus_connect_function(
+    plc4c_connection* connection, plc4c_system_task** task);
+
+plc4c_return_code plc4c_driver_modbus_disconnect_function(
+    plc4c_connection* connection, plc4c_system_task** task);
+
+plc4c_return_code plc4c_driver_modbus_read_function(
+    plc4c_read_request_execution* read_request_execution,
+    plc4c_system_task** task);
+void plc4c_driver_modbus_free_read_response(plc4c_read_response* response);
+
+plc4c_return_code plc4c_driver_modbus_write_function(
+    plc4c_write_request_execution* write_request_execution,
+    plc4c_system_task** task);
+void plc4c_driver_modbus_free_write_response(plc4c_write_response* response);
+
+#ifdef __cplusplus
+}
+#endif
+#endif  // PLC4C_DRIVER_MODBUS_SM_H_
\ No newline at end of file
diff --git a/sandbox/plc4c/drivers/modbus/include/plc4c/driver_s7_encode_decode.h b/sandbox/plc4c/drivers/modbus/include/plc4c/driver_s7_encode_decode.h
new file mode 100644
index 0000000..0e8e5fe
--- /dev/null
+++ b/sandbox/plc4c/drivers/modbus/include/plc4c/driver_s7_encode_decode.h
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#ifndef PLC4C_DRIVER_MODBUS_ENCODE_DECODE_H_
+#define PLC4C_DRIVER_MODBUS_ENCODE_DECODE_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+
+#include <plc4c/types.h>
+#include <modbus_pdu.h>
+
+plc4c_return_code plc4c_driver_modbus_encode_address(
+    char* address, plc4c_modbus_read_write_modbus_pdu** item);
+
+#ifdef __cplusplus
+}
+#endif
+#endif  // PLC4C_DRIVER_MODBUS_ENCODE_DECODE_H_
\ No newline at end of file
diff --git a/sandbox/plc4c/drivers/modbus/src/driver_modbus.c b/sandbox/plc4c/drivers/modbus/src/driver_modbus.c
index 59e0f6e..90e2719 100644
--- a/sandbox/plc4c/drivers/modbus/src/driver_modbus.c
+++ b/sandbox/plc4c/drivers/modbus/src/driver_modbus.c
@@ -17,9 +17,7 @@
   under the License.
 */
 
-#include <plc4c/driver_modbus.h>
-#include <plc4c/spi/types_private.h>
-#include <stdlib.h>
+#include "plc4c/driver_modbus_sm.h"
 
 plc4c_driver *plc4c_driver_modbus_create() {
   plc4c_driver *driver = (plc4c_driver *)malloc(sizeof(plc4c_driver));
@@ -27,14 +25,14 @@
   driver->protocol_name = "Modbus";
   driver->default_transport_code = "tcp";
   driver->parse_address_function = NULL;
-  driver->connect_function = NULL;
-  driver->disconnect_function = NULL;
-  driver->read_function = NULL;
-  driver->write_function = NULL;
+  driver->connect_function = &plc4c_driver_modbus_connect_function;
+  driver->disconnect_function = &plc4c_driver_modbus_disconnect_function;
+  driver->read_function = &plc4c_driver_modbus_read_function;
+  driver->write_function = &plc4c_driver_modbus_write_function;
   driver->subscribe_function = NULL;
   driver->unsubscribe_function = NULL;
-  driver->free_read_response_function = NULL;
-  driver->free_write_response_function = NULL;
+  driver->free_read_response_function = &plc4c_driver_modbus_free_read_response;
+  driver->free_write_response_function = &plc4c_driver_modbus_free_write_response;
   driver->free_subscription_response_function = NULL;
   driver->free_unsubscription_response_function = NULL;
   return driver;
diff --git a/sandbox/plc4c/drivers/modbus/src/driver_modbus_encode_decode.c b/sandbox/plc4c/drivers/modbus/src/driver_modbus_encode_decode.c
new file mode 100644
index 0000000..f962ff9
--- /dev/null
+++ b/sandbox/plc4c/drivers/modbus/src/driver_modbus_encode_decode.c
@@ -0,0 +1,110 @@
+/*
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+*/
+
+#include <ctype.h>
+#include <string.h>
+
+#include "plc4c/driver_s7_encode_decode.h"
+
+plc4c_return_code plc4c_driver_modbus_encode_address(
+    char* address, plc4c_modbus_read_write_modbus_pdu** item) {
+
+  // Parser logic
+  char* cur_pos = address;
+  char* last_pos = address;
+
+  // If the first character is numeric, then we can only have a numeric address.
+  if(isdigit(*cur_pos)) {
+    int first_digit = *cur_pos - 48;
+    cur_pos++;
+    // If the first digit is followed by an 'x' or 'X', just skip that char.
+    if((*cur_pos == 'x') || (*cur_pos == 'X')) {
+      cur_pos++;
+    }
+    last_pos = cur_pos;
+    while(isdigit(*cur_pos)) {
+      cur_pos++;
+    }
+    long num_address = 0;
+    long num_items = 1;
+    // If after the numbers comes a "[" then this is the number of items.
+    if(*cur_pos == '[') {
+      *cur_pos = '/0';
+      // Interpret the rest of the address as a long.
+      num_address = atol(last_pos);
+      cur_pos++;
+      last_pos = cur_pos;
+      while(isdigit(*cur_pos)) {
+        cur_pos++;
+      }
+      if(*cur_pos != ']') {
+        return INVALID_ADDRESS;
+      }
+      *cur_pos = '\0';
+      num_items = atol(last_pos);
+    } else if(*cur_pos == '/0') {
+      num_address = atol(last_pos);
+    } else {
+      return INVALID_ADDRESS;
+    }
+
+    switch (first_digit) {
+      // coil
+      case 0: {
+        // TODO: Implement ...
+        break;
+      }
+      // discrete-input
+      case 1: {
+        // TODO: Implement ...
+        break;
+      }
+      // input-register
+      case 3: {
+        // TODO: Implement ...
+        break;
+      }
+      // holding-register
+      case 4: {
+        // TODO: Implement ...
+        break;
+      }
+      // extended-register
+      case 6: {
+        // TODO: Implement ...
+        break;
+      }
+    }
+  }
+  else {
+    if(strstr("coil:", address) == 0) {
+      // TODO: Implement ...
+    } else if(strstr("discrete-input:", address) == 0) {
+      // TODO: Implement ...
+    } else if(strstr("input-register:", address) == 0) {
+      // TODO: Implement ...
+    } else if(strstr("holding-register:", address) == 0) {
+      // TODO: Implement ...
+    } else if(strstr("extended-register:", address) == 0) {
+      // TODO: Implement ...
+    } else {
+      return INVALID_ADDRESS;
+    }
+  }
+}
diff --git a/sandbox/plc4c/drivers/modbus/src/driver_modbus_packets.c b/sandbox/plc4c/drivers/modbus/src/driver_modbus_packets.c
new file mode 100644
index 0000000..af50cbe
--- /dev/null
+++ b/sandbox/plc4c/drivers/modbus/src/driver_modbus_packets.c
@@ -0,0 +1,142 @@
+/*
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+*/
+
+#include <ctype.h>
+#include <plc4c/spi/types_private.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "modbus_tcp_adu.h"
+#include "plc4c/driver_modbus.h"
+#include "plc4c/driver_s7_encode_decode.h"
+
+/**
+ * Function used by the driver to tell the transport if there is a full
+ * packet the driver can operate on available.
+ *
+ * @param buffer_data pointer to the buffer
+ * @param buffer_length length of the buffer
+ * @return positive integer = length of the packet, 0 = not enough,
+ * try again later, negative integer = remove the given amount of bytes
+ * from the buffer.
+ */
+int16_t plc4c_driver_modbus_select_message_function(uint8_t* buffer_data,
+                                                uint16_t buffer_length) {
+  // The length information is located in bytes 5 and 6
+  if (buffer_length >= 6) {
+    uint16_t packet_length =
+        ((uint16_t) (buffer_data + 4) << 8) |
+        ((uint16_t) (buffer_data + 5));
+    packet_length += 6;
+    if (buffer_length >= packet_length) {
+      return packet_length;
+    }
+  }
+  // In all other cases, we'll just have to wait for the next time.
+  return 0;
+}
+
+plc4c_return_code plc4c_driver_modbus_send_packet(plc4c_connection* connection,
+                              plc4c_modbus_read_write_modbus_tcp_adu* packet) {
+  // Get the size required to contain the serialized form of this packet.
+  uint16_t packet_size =
+      plc4c_modbus_read_write_modbus_tcp_adu_length_in_bytes(packet);
+
+  // Serialize this message to a byte-array.
+  plc4c_spi_write_buffer* write_buffer;
+  plc4c_return_code return_code =
+      plc4c_spi_write_buffer_create(packet_size, &write_buffer);
+  if (return_code != OK) {
+    return return_code;
+  }
+  plc4c_modbus_read_write_modbus_tcp_adu_serialize(write_buffer, packet);
+
+  // Now send this to the recipient.
+  return_code = connection->transport->send_message(
+      connection->transport_configuration, write_buffer);
+  if (return_code != OK) {
+    return return_code;
+  }
+
+  return OK;
+}
+
+plc4c_return_code plc4c_driver_modbus_receive_packet(plc4c_connection* connection,
+                                 plc4c_modbus_read_write_modbus_tcp_adu** packet) {
+  // Check with the transport if there is a packet available.
+  // If it is, get a read_buffer for reading it.
+  plc4c_spi_read_buffer* read_buffer;
+  plc4c_return_code return_code = connection->transport->select_message(
+      connection->transport_configuration,
+      6, plc4c_driver_modbus_select_message_function,
+      &read_buffer);
+  // OK is only returned if a packet is available.
+  if (return_code != OK) {
+    return return_code;
+  }
+
+  // Parse the packet by consuming the read_buffer data.
+  *packet = NULL;
+  return_code = plc4c_modbus_read_write_modbus_tcp_adu_parse(read_buffer, true, packet);
+  if (return_code != OK) {
+    return return_code;
+  }
+
+  // In this case a packet was available and parsed.
+  return OK;
+}
+
+plc4c_return_code plc4c_driver_modbus_create_modbus_read_request(
+    plc4c_read_request* read_request,
+    plc4c_list** modbus_read_request_packets) {
+  // Initialize the packet list.
+  plc4c_utils_list_create(modbus_read_request_packets);
+
+  // For every item in the request, create a separate packet.
+  plc4c_list_element* item = read_request->items->tail;
+  while (item != NULL) {
+    // Get the item address from the API request.
+    char* itemAddress = item->value;
+
+    // Create a packet from the current item.
+    plc4c_modbus_read_write_modbus_pdu* packet;
+    plc4c_return_code result = plc4c_driver_modbus_encode_address(
+        itemAddress, &packet);
+    if(result != OK) {
+      return result;
+    }
+
+    // Add the packet to the list of packets.
+    plc4c_utils_list_insert_head_value(*modbus_read_request_packets, packet);
+
+    // Proceed with the next item.
+    item = item->next;
+  }
+  return OK;
+}
+
+plc4c_return_code plc4c_driver_modbus_create_modbus_write_request(
+    plc4c_write_request* write_request,
+    plc4c_modbus_read_write_modbus_tcp_adu** modbus_read_request_packet) {
+
+  // TODO: Implement this ...
+
+  return OK;
+}
+
diff --git a/sandbox/plc4c/drivers/modbus/src/driver_modbus_sm_connect.c b/sandbox/plc4c/drivers/modbus/src/driver_modbus_sm_connect.c
new file mode 100644
index 0000000..a093567
--- /dev/null
+++ b/sandbox/plc4c/drivers/modbus/src/driver_modbus_sm_connect.c
@@ -0,0 +1,51 @@
+/*
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+*/
+
+#include <plc4c/plc4c.h>
+#include <plc4c/spi/types_private.h>
+#include <string.h>
+
+plc4c_return_code plc4c_driver_modbus_connect_machine_function(
+    plc4c_system_task *task) {
+  plc4c_connection *connection = task->context;
+  if (connection == NULL) {
+    return INTERNAL_ERROR;
+  }
+  if (plc4c_connection_get_connected(connection)) {
+    return ALREADY_CONNECTED;
+  }
+  plc4c_connection_set_connected(connection, true);
+  task->completed = true;
+  return OK;
+}
+
+plc4c_return_code plc4c_driver_modbus_connect_function(
+    plc4c_connection *connection, plc4c_system_task **task) {
+
+  plc4c_system_task *new_task = malloc(sizeof(plc4c_system_task));
+  // There's nothing to do here, so no need for a state-machine.
+  new_task->state_id = -1;
+  new_task->state_machine_function =
+      &plc4c_driver_modbus_connect_machine_function;
+  new_task->completed = false;
+  new_task->context = connection;
+  new_task->connection = connection;
+  *task = new_task;
+  return OK;
+}
diff --git a/sandbox/plc4c/drivers/modbus/src/driver_modbus_sm_disconnect.c b/sandbox/plc4c/drivers/modbus/src/driver_modbus_sm_disconnect.c
new file mode 100644
index 0000000..93df6b8
--- /dev/null
+++ b/sandbox/plc4c/drivers/modbus/src/driver_modbus_sm_disconnect.c
@@ -0,0 +1,74 @@
+/*
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+*/
+
+#include <plc4c/plc4c.h>
+#include <plc4c/spi/types_private.h>
+#include <string.h>
+
+enum plc4c_driver_modbus_disconnect_states {
+  PLC4C_DRIVER_MODBUS_DISCONNECT_INIT,
+  PLC4C_DRIVER_MODBUS_DISCONNECT_WAIT_TASKS_FINISHED,
+  PLC4C_DRIVER_MODBUS_DISCONNECT_FINISHED
+};
+
+plc4c_return_code plc4c_driver_modbus_disconnect_machine_function(
+    plc4c_system_task *task) {
+  plc4c_connection *connection = task->context;
+  if (connection == NULL) {
+    return INTERNAL_ERROR;
+  }
+
+  switch (task->state_id) {
+    case PLC4C_DRIVER_MODBUS_DISCONNECT_INIT: {
+      plc4c_connection_set_disconnect(connection, true);
+      task->state_id = PLC4C_DRIVER_MODBUS_DISCONNECT_WAIT_TASKS_FINISHED;
+      break;
+    }
+    case PLC4C_DRIVER_MODBUS_DISCONNECT_WAIT_TASKS_FINISHED: {
+      // The disconnect system-task also counts.
+      if (plc4c_connection_get_running_tasks_count(connection) == 1) {
+        plc4c_connection_set_connected(connection, false);
+        task->completed = true;
+        task->state_id = PLC4C_DRIVER_MODBUS_DISCONNECT_FINISHED;
+      }
+      break;
+    }
+    case PLC4C_DRIVER_MODBUS_DISCONNECT_FINISHED: {
+      // Do nothing
+      break;
+    }
+    default: {
+      return INTERNAL_ERROR;
+    }
+  }
+  return OK;
+}
+
+plc4c_return_code plc4c_driver_modbus_disconnect_function(
+    plc4c_connection *connection, plc4c_system_task **task) {
+  plc4c_system_task *new_task = malloc(sizeof(plc4c_system_task));
+  new_task->state_id = PLC4C_DRIVER_MODBUS_DISCONNECT_INIT;
+  new_task->state_machine_function =
+      &plc4c_driver_modbus_disconnect_machine_function;
+  new_task->completed = false;
+  new_task->context = connection;
+  new_task->connection = connection;
+  *task = new_task;
+  return OK;
+}
diff --git a/sandbox/plc4c/drivers/modbus/src/driver_modbus_sm_read.c b/sandbox/plc4c/drivers/modbus/src/driver_modbus_sm_read.c
new file mode 100644
index 0000000..b855edd
--- /dev/null
+++ b/sandbox/plc4c/drivers/modbus/src/driver_modbus_sm_read.c
@@ -0,0 +1,119 @@
+/*
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+*/
+
+#include <plc4c/spi/types_private.h>
+#include <stdlib.h>
+#include <string.h>
+#include "plc4c/driver_modbus_packets.h"
+#include "modbus_tcp_adu.h"
+
+enum plc4c_driver_modbus_read_states {
+  PLC4C_DRIVER_MODBUS_READ_INIT,
+  PLC4C_DRIVER_MODBUS_READ_FINISHED
+};
+
+plc4c_return_code plc4c_driver_modbus_read_machine_function(
+    plc4c_system_task* task) {
+  plc4c_read_request_execution* read_request_execution = task->context;
+  if (read_request_execution == NULL) {
+    return INTERNAL_ERROR;
+  }
+  plc4c_read_request* read_request = read_request_execution->read_request;
+  if (read_request == NULL) {
+    return INTERNAL_ERROR;
+  }
+  plc4c_connection* connection = task->context;
+  if (connection == NULL) {
+    return INTERNAL_ERROR;
+  }
+
+  switch (task->state_id) {
+    case PLC4C_DRIVER_MODBUS_READ_INIT: {
+      plc4c_modbus_read_write_modbus_tcp_adu* modbus_read_request_packet;
+      plc4c_return_code return_code =
+          plc4c_driver_modbus_create_modbus_read_request(
+              read_request, &modbus_read_request_packet);
+      if (return_code != OK) {
+        return return_code;
+      }
+
+      // Send the packet to the remote.
+      return_code = plc4c_driver_modbus_send_packet(
+          connection, modbus_read_request_packet);
+      if (return_code != OK) {
+        return return_code;
+      }
+
+      task->state_id = PLC4C_DRIVER_MODBUS_READ_FINISHED;
+      break;
+    }
+    case PLC4C_DRIVER_MODBUS_READ_FINISHED: {
+      // Read a response packet.
+      plc4c_modbus_read_write_modbus_tcp_adu* modbus_read_response_packet;
+      plc4c_return_code return_code =
+          plc4c_driver_modbus_receive_packet(
+              connection, &modbus_read_response_packet);
+      // If we haven't read enough to process a full message, just try again
+      // next time.
+      if (return_code == UNFINISHED) {
+        return OK;
+      } else if (return_code != OK) {
+        return return_code;
+      }
+
+      // TODO: Check the response ...
+      // TODO: Decode the items in the response ...
+      // TODO: Return the results to the API ...
+
+      task->completed = true;
+      break;
+    }
+  }
+  return OK;
+}
+
+plc4c_return_code plc4c_driver_modbus_read_function(
+    plc4c_read_request_execution* read_request_execution,
+    plc4c_system_task** task) {
+  plc4c_system_task* new_task = malloc(sizeof(plc4c_system_task));
+  if(new_task == NULL) {
+    return NO_MEMORY;
+  }
+  new_task->state_id = PLC4C_DRIVER_MODBUS_READ_INIT;
+  new_task->state_machine_function = &plc4c_driver_modbus_read_machine_function;
+  new_task->completed = false;
+  new_task->context = read_request_execution;
+  new_task->connection = read_request_execution->system_task->connection;
+  *task = new_task;
+  return OK;
+}
+
+void plc4c_driver_modbus_free_read_response_item(
+    plc4c_list_element* read_item_element) {
+  plc4c_response_value_item* value_item =
+      (plc4c_response_value_item*)read_item_element->value;
+  plc4c_data_destroy(value_item->value);
+  value_item->value = NULL;
+}
+
+void plc4c_driver_modbus_free_read_response(plc4c_read_response* response) {
+  // the request will be cleaned up elsewhere
+  plc4c_utils_list_delete_elements(response->items,
+                                   &plc4c_driver_modbus_free_read_response_item);
+}
diff --git a/sandbox/plc4c/drivers/modbus/src/driver_modbus_sm_write.c b/sandbox/plc4c/drivers/modbus/src/driver_modbus_sm_write.c
new file mode 100644
index 0000000..eeb9dc4
--- /dev/null
+++ b/sandbox/plc4c/drivers/modbus/src/driver_modbus_sm_write.c
@@ -0,0 +1,121 @@
+/*
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+*/
+
+#include <plc4c/plc4c.h>
+#include <plc4c/spi/types_private.h>
+#include <stdlib.h>
+#include <string.h>
+#include "plc4c/driver_modbus_packets.h"
+#include "modbus_tcp_adu.h"
+
+enum plc4c_driver_modbus_write_states {
+  PLC4C_DRIVER_MODBUS_WRITE_INIT,
+  PLC4C_DRIVER_MODBUS_WRITE_FINISHED
+};
+
+plc4c_return_code plc4c_driver_modbus_write_machine_function(
+    plc4c_system_task* task) {
+  plc4c_write_request_execution* write_request_execution = task->context;
+  if (write_request_execution == NULL) {
+    return INTERNAL_ERROR;
+  }
+  plc4c_write_request* write_request = write_request_execution->write_request;
+  if (write_request == NULL) {
+    return INTERNAL_ERROR;
+  }
+  plc4c_connection* connection = task->context;
+  if (connection == NULL) {
+    return INTERNAL_ERROR;
+  }
+
+  switch (task->state_id) {
+    case PLC4C_DRIVER_MODBUS_WRITE_INIT: {
+      plc4c_modbus_read_write_modbus_tcp_adu* modbus_write_request_packet;
+      plc4c_return_code return_code =
+          plc4c_driver_modbus_create_modbus_write_request(
+              write_request, &modbus_write_request_packet);
+      if (return_code != OK) {
+        return return_code;
+      }
+
+      // Send the packet to the remote.
+      return_code = plc4c_driver_modbus_send_packet(
+          connection, modbus_write_request_packet);
+      if (return_code != OK) {
+        return return_code;
+      }
+
+      task->state_id = PLC4C_DRIVER_MODBUS_WRITE_FINISHED;
+      break;
+    }
+    case PLC4C_DRIVER_MODBUS_WRITE_FINISHED: {
+      // Read a response packet.
+      plc4c_modbus_read_write_modbus_tcp_adu* modbus_write_response_packet;
+      plc4c_return_code return_code =
+          plc4c_driver_modbus_receive_packet(
+              connection, &modbus_write_response_packet);
+      // If we haven't read enough to process a full message, just try again
+      // next time.
+      if (return_code == UNFINISHED) {
+        return OK;
+      } else if (return_code != OK) {
+        return return_code;
+      }
+
+      // TODO: Check the response ...
+      // TODO: Decode the return codes in the response ...
+      // TODO: Return the results to the API ...
+
+      task->completed = true;
+      break;
+    }
+  }
+  return OK;
+}
+
+plc4c_return_code plc4c_driver_modbus_write_function(
+    plc4c_write_request_execution* write_request_execution,
+    plc4c_system_task** task) {
+  plc4c_system_task* new_task = malloc(sizeof(plc4c_system_task));
+  new_task->state_id = PLC4C_DRIVER_MODBUS_WRITE_INIT;
+  new_task->state_machine_function = &plc4c_driver_modbus_write_machine_function;
+  new_task->completed = false;
+  new_task->context = write_request_execution;
+  new_task->connection = write_request_execution->system_task->connection;
+  *task = new_task;
+  return OK;
+}
+
+void plc4c_driver_modbus_free_write_response_item(
+    plc4c_list_element* write_item_element) {
+  plc4c_response_value_item* value_item =
+      (plc4c_response_value_item*)write_item_element->value;
+  // do not delete the plc4c_item
+  // we also, in THIS case don't delete the random value which isn't really
+  // a pointer
+  // free(value_item->value);
+  value_item->value = NULL;
+}
+
+void plc4c_driver_modbus_free_write_response(plc4c_write_response* response) {
+  // the request will be cleaned up elsewhere
+  plc4c_utils_list_delete_elements(response->response_items,
+                                   &plc4c_driver_modbus_free_write_response_item);
+}
+
diff --git a/sandbox/plc4c/drivers/s7/CMakeLists.txt b/sandbox/plc4c/drivers/s7/CMakeLists.txt
index 19544c9..a2271b4 100644
--- a/sandbox/plc4c/drivers/s7/CMakeLists.txt
+++ b/sandbox/plc4c/drivers/s7/CMakeLists.txt
@@ -18,13 +18,19 @@
 ]]
 
 include_directories("include" "../../api/include" "../../spi/include"
-    "${PLC4C_ROOT_DIR}/generated-sources/s7/includes")
+    "../../generated-sources/s7/include")
 
 # Add the generated sources
-file(GLOB generatedSources "${PLC4C_ROOT_DIR}/generated-sources/s7/src/*.c")
+file(GLOB generatedSources "../../generated-sources/s7/src/*.c")
 
 add_library(plc4c-driver-s7
         src/driver_s7.c
+        src/driver_s7_encode_decode.c
+        src/driver_s7_packets.c
+        src/driver_s7_sm_connect.c
+        src/driver_s7_sm_disconnect.c
+        src/driver_s7_sm_read.c
+        src/driver_s7_sm_write.c
         ${generatedSources})
 
 target_link_libraries(plc4c-driver-s7
@@ -32,6 +38,7 @@
 
 if (BUILD_PHASE STREQUAL test-compile)
     add_executable(plc4c-driver-s7-test
+            test/s7_address_parser_test.c
             test/s7_test.c
             )
     target_link_libraries(plc4c-driver-s7-test
diff --git a/sandbox/plc4c/drivers/s7/include/plc4c/driver_s7.h b/sandbox/plc4c/drivers/s7/include/plc4c/driver_s7.h
index e4c32f3..715a867 100644
--- a/sandbox/plc4c/drivers/s7/include/plc4c/driver_s7.h
+++ b/sandbox/plc4c/drivers/s7/include/plc4c/driver_s7.h
@@ -23,9 +23,68 @@
 #endif
 
 #include <plc4c/types.h>
+#include <stdint.h>
+#include <time.h>
+
+#include "../../../../generated-sources/s7/include/cotp_tpdu_size.h"
+#include "../../../../spi/include/plc4c/spi/read_buffer.h"
+
+enum plc4c_driver_s7_controller_type {
+  PLC4C_DRIVER_S7_CONTROLLER_TYPE_ANY = 0,
+  PLC4C_DRIVER_S7_CONTROLLER_TYPE_S7_300 = 1,
+  PLC4C_DRIVER_S7_CONTROLLER_TYPE_S7_400 = 2,
+  PLC4C_DRIVER_S7_CONTROLLER_TYPE_S7_1200 = 3,
+  PLC4C_DRIVER_S7_CONTROLLER_TYPE_S7_1500 = 4,
+  PLC4C_DRIVER_S7_CONTROLLER_TYPE_LOGO = 5
+};
+typedef enum plc4c_driver_s7_controller_type plc4c_driver_s7_controller_type;
+
+enum plc4c_driver_s7_device_group {
+  PLC4C_DRIVER_S7_DEVICE_GROUP_PG_OR_PC = 1,
+  PLC4C_DRIVER_S7_DEVICE_GROUP_OS = 2,
+  PLC4C_DRIVER_S7_DEVICE_GROUP_OTHERS = 3
+};
+typedef enum plc4c_driver_s7_device_group plc4c_driver_s7_device_group;
+
+struct plc4c_driver_s7_config {
+  uint8_t local_rack;
+  uint8_t local_slot;
+  uint8_t remote_rack;
+  uint8_t remote_slot;
+  uint16_t calling_tsap_id;
+  uint16_t called_tsap_id;
+  plc4c_s7_read_write_cotp_tpdu_size cotp_tpdu_size;
+  uint16_t pdu_size;
+  uint8_t max_amq_caller;
+  uint8_t max_amq_callee;
+  plc4c_driver_s7_controller_type controller_type;
+
+  uint16_t pdu_id;
+};
+typedef struct plc4c_driver_s7_config plc4c_driver_s7_config;
 
 plc4c_driver *plc4c_driver_s7_create();
 
+/*
+ *
+ *   Static functions
+ *
+ */
+
+char* plc4c_s7_read_write_parse_s7_string(plc4c_spi_read_buffer* io, int32_t stringLength, char* encoding);
+
+time_t plc4c_s7_read_write_parse_tia_time(plc4c_spi_read_buffer* io);
+
+time_t plc4c_s7_read_write_parse_s5_time(plc4c_spi_read_buffer* io);
+
+time_t plc4c_s7_read_write_parse_tia_l_time(plc4c_spi_read_buffer* io);
+
+time_t plc4c_s7_read_write_parse_tia_date(plc4c_spi_read_buffer* io);
+
+time_t plc4c_s7_read_write_parse_tia_time_of_day(plc4c_spi_read_buffer* io);
+
+time_t plc4c_s7_read_write_parse_tia_date_time(plc4c_spi_read_buffer* io);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/sandbox/plc4c/drivers/s7/include/plc4c/driver_s7_encode_decode.h b/sandbox/plc4c/drivers/s7/include/plc4c/driver_s7_encode_decode.h
new file mode 100644
index 0000000..2c79cb6
--- /dev/null
+++ b/sandbox/plc4c/drivers/s7/include/plc4c/driver_s7_encode_decode.h
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#ifndef PLC4C_DRIVER_S7_ENCODE_DECODE_H_
+#define PLC4C_DRIVER_S7_ENCODE_DECODE_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+
+#include "plc4c/driver_s7.h"
+#include "s7_var_request_parameter_item.h"
+
+uint16_t plc4c_driver_s7_encode_tsap_id(
+    plc4c_driver_s7_device_group device_group, uint8_t rack, uint8_t slot);
+
+uint16_t plc4c_driver_s7_get_nearest_matching_tpdu_size(uint16_t pdu_size);
+
+plc4c_driver_s7_controller_type decode_controller_type(char* article_number);
+
+plc4c_return_code decode_byte(const char* from_ptr, const char* to_ptr, uint8_t* value);
+
+plc4c_return_code plc4c_driver_s7_encode_address(
+    char* address, void** item);
+
+#ifdef __cplusplus
+}
+#endif
+#endif  // PLC4C_DRIVER_S7_ENCODE_DECODE_H_
\ No newline at end of file
diff --git a/sandbox/plc4c/drivers/s7/include/plc4c/driver_s7_packets.h b/sandbox/plc4c/drivers/s7/include/plc4c/driver_s7_packets.h
new file mode 100644
index 0000000..5f41110
--- /dev/null
+++ b/sandbox/plc4c/drivers/s7/include/plc4c/driver_s7_packets.h
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#ifndef PLC4C_DRIVER_S7_PACKETS_H_
+#define PLC4C_DRIVER_S7_PACKETS_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <plc4c/types.h>
+
+#include "tpkt_packet.h"
+#include "plc4c/driver_s7.h"
+
+plc4c_return_code plc4c_driver_s7_send_packet(
+    plc4c_connection* connection, plc4c_s7_read_write_tpkt_packet* packet);
+plc4c_return_code plc4c_driver_s7_receive_packet(
+    plc4c_connection* connection, plc4c_s7_read_write_tpkt_packet** packet);
+
+plc4c_return_code plc4c_driver_s7_create_cotp_connection_request(
+    plc4c_driver_s7_config* configuration,
+    plc4c_s7_read_write_tpkt_packet** cotp_connect_request_packet);
+plc4c_return_code plc4c_driver_s7_create_s7_connection_request(
+    plc4c_driver_s7_config* configuration,
+    plc4c_s7_read_write_tpkt_packet** s7_connect_request_packet);
+plc4c_return_code plc4c_driver_s7_create_s7_identify_remote_request(
+    plc4c_s7_read_write_tpkt_packet** s7_identify_remote_request_packet);
+plc4c_return_code plc4c_driver_s7_create_s7_read_request(
+    plc4c_read_request* read_request,
+    plc4c_s7_read_write_tpkt_packet** s7_read_request_packet);
+plc4c_return_code plc4c_driver_s7_create_s7_write_request(
+    plc4c_write_request* write_request,
+    plc4c_s7_read_write_tpkt_packet** s7_write_request_packet);
+
+#ifdef __cplusplus
+}
+#endif
+#endif  // PLC4C_DRIVER_S7_PACKETS_H_
\ No newline at end of file
diff --git a/sandbox/plc4c/drivers/s7/include/plc4c/driver_s7_sm.h b/sandbox/plc4c/drivers/s7/include/plc4c/driver_s7_sm.h
new file mode 100644
index 0000000..a6a9530
--- /dev/null
+++ b/sandbox/plc4c/drivers/s7/include/plc4c/driver_s7_sm.h
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#ifndef PLC4C_DRIVER_S7_SM_H_
+#define PLC4C_DRIVER_S7_SM_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <plc4c/types.h>
+#include <plc4c/spi/types_private.h>
+
+plc4c_return_code plc4c_driver_s7_connect_function(
+    plc4c_connection* connection, plc4c_system_task** task);
+
+plc4c_return_code plc4c_driver_s7_disconnect_function(
+    plc4c_connection* connection, plc4c_system_task** task);
+
+plc4c_return_code plc4c_driver_s7_read_function(
+    plc4c_read_request_execution* read_request_execution,
+    plc4c_system_task** task);
+void plc4c_driver_s7_free_read_response(plc4c_read_response* response);
+
+plc4c_return_code plc4c_driver_s7_write_function(
+    plc4c_write_request_execution* write_request_execution,
+    plc4c_system_task** task);
+void plc4c_driver_s7_free_write_response(plc4c_write_response* response);
+
+#ifdef __cplusplus
+}
+#endif
+#endif  // PLC4C_DRIVER_S7_SM_H_
\ No newline at end of file
diff --git a/sandbox/plc4c/drivers/s7/src/driver_s7.c b/sandbox/plc4c/drivers/s7/src/driver_s7.c
index 9b3431c..9f897db 100644
--- a/sandbox/plc4c/drivers/s7/src/driver_s7.c
+++ b/sandbox/plc4c/drivers/s7/src/driver_s7.c
@@ -17,25 +17,91 @@
   under the License.
 */
 
-#include <plc4c/driver_s7.h>
-#include <plc4c/spi/types_private.h>
-#include <stdlib.h>
+#include "plc4c/driver_s7.h"
+#include "plc4c/driver_s7_sm.h"
+#include "plc4c/driver_s7_encode_decode.h"
 
-plc4c_driver *plc4c_driver_s7_create() {
-  plc4c_driver *driver = (plc4c_driver *)malloc(sizeof(plc4c_driver));
+plc4c_return_code plc4c_driver_s7_configure_function(
+    plc4c_list* parameters, void** configuration) {
+  plc4c_driver_s7_config* s7_config = malloc(sizeof(plc4c_driver_s7_config));
+  if(s7_config == NULL) {
+    return NO_MEMORY;
+  }
+
+  // Initialize the parts that the user can influence.
+  s7_config->local_rack = 1;
+  s7_config->local_slot = 1;
+  s7_config->remote_rack = 0;
+  s7_config->remote_slot = 0;
+  s7_config->pdu_size = 1024;
+  s7_config->max_amq_caller = 8;
+  s7_config->max_amq_callee = 8;
+  s7_config->controller_type = PLC4C_DRIVER_S7_CONTROLLER_TYPE_ANY;
+
+  // TODO: Apply the values from the parameters.
+
+  *configuration = s7_config;
+  return OK;
+}
+
+plc4c_driver* plc4c_driver_s7_create() {
+  plc4c_driver* driver = (plc4c_driver*)malloc(sizeof(plc4c_driver));
   driver->protocol_code = "s7";
   driver->protocol_name = "Siemens S7 (Basic)";
   driver->default_transport_code = "tcp";
-  driver->parse_address_function = NULL;
-  driver->connect_function = NULL;
-  driver->disconnect_function = NULL;
-  driver->read_function = NULL;
-  driver->write_function = NULL;
+  driver->parse_address_function = &plc4c_driver_s7_encode_address;
+  driver->configure_function = &plc4c_driver_s7_configure_function;
+  driver->connect_function = &plc4c_driver_s7_connect_function;
+  driver->disconnect_function = &plc4c_driver_s7_disconnect_function;
+  driver->read_function = &plc4c_driver_s7_read_function;
+  driver->write_function = &plc4c_driver_s7_write_function;
   driver->subscribe_function = NULL;
   driver->unsubscribe_function = NULL;
-  driver->free_read_response_function = NULL;
-  driver->free_write_response_function = NULL;
+  driver->free_read_response_function = &plc4c_driver_s7_free_read_response;
+  driver->free_write_response_function = &plc4c_driver_s7_free_write_response;
   driver->free_subscription_response_function = NULL;
   driver->free_unsubscription_response_function = NULL;
   return driver;
 }
+
+/*
+ *
+ *   Static functions
+ *
+ */
+
+char* plc4c_s7_read_write_parse_s7_string(plc4c_spi_read_buffer* io, int32_t stringLength, char* encoding) {
+  // TODO: Implement ...
+  return "";
+}
+
+time_t plc4c_s7_read_write_parse_tia_time(plc4c_spi_read_buffer* io) {
+  // TODO: Implement ...
+  return 0;
+}
+
+time_t plc4c_s7_read_write_parse_s5_time(plc4c_spi_read_buffer* io) {
+  // TODO: Implement ...
+  return 0;
+}
+
+time_t plc4c_s7_read_write_parse_tia_l_time(plc4c_spi_read_buffer* io) {
+  // TODO: Implement ...
+  return 0;
+}
+
+time_t plc4c_s7_read_write_parse_tia_date(plc4c_spi_read_buffer* io) {
+  // TODO: Implement ...
+  return 0;
+}
+
+time_t plc4c_s7_read_write_parse_tia_time_of_day(plc4c_spi_read_buffer* io) {
+  // TODO: Implement ...
+  return 0;
+}
+
+time_t plc4c_s7_read_write_parse_tia_date_time(plc4c_spi_read_buffer* io) {
+  // TODO: Implement ...
+  return 0;
+}
+
diff --git a/sandbox/plc4c/drivers/s7/src/driver_s7_encode_decode.c b/sandbox/plc4c/drivers/s7/src/driver_s7_encode_decode.c
new file mode 100644
index 0000000..f11e844
--- /dev/null
+++ b/sandbox/plc4c/drivers/s7/src/driver_s7_encode_decode.c
@@ -0,0 +1,346 @@
+/*
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+*/
+
+#include <cotp_protocol_class.h>
+#include <ctype.h>
+#include <plc4c/driver_s7.h>
+#include <plc4c/spi/types_private.h>
+#include <stdlib.h>
+#include <string.h>
+#include <tpkt_packet.h>
+
+uint16_t plc4c_driver_s7_encode_tsap_id(
+    plc4c_driver_s7_device_group device_group, uint8_t rack, uint8_t slot) {
+  return (device_group << 8) |
+         ((uint16_t) ((uint16_t) rack & (uint16_t) 0x000F) << (uint16_t) 4) |
+         ((uint16_t) slot & (uint16_t) 0x000F);
+}
+
+uint16_t plc4c_driver_s7_get_nearest_matching_tpdu_size(uint16_t pdu_size) {
+  for (int i = 0; i < plc4c_s7_read_write_cotp_tpdu_size_num_values(); i++) {
+    uint16_t cur_value =
+        plc4c_s7_read_write_cotp_tpdu_size_get_size_in_bytes(
+            plc4c_s7_read_write_cotp_tpdu_size_value_for_index(i));
+    if (cur_value >= pdu_size) {
+      return plc4c_s7_read_write_cotp_tpdu_size_value_for_index(i);
+    }
+  }
+  return 0;
+}
+
+plc4c_driver_s7_controller_type decode_controller_type(char* article_number) {
+  char* prefix = "6ES7 ";
+  // If this article-number doesn't start with this prefix, we can't decode it.
+  if (strncmp(prefix, article_number, (size_t) strlen(prefix)) != 0) {
+    return PLC4C_DRIVER_S7_CONTROLLER_TYPE_ANY;
+  }
+  char model = *(article_number + 5);
+  switch (model) {
+    case '2':
+      return PLC4C_DRIVER_S7_CONTROLLER_TYPE_S7_1200;
+    case '5':
+      return PLC4C_DRIVER_S7_CONTROLLER_TYPE_S7_1500;
+    case '3':
+      return PLC4C_DRIVER_S7_CONTROLLER_TYPE_S7_300;
+    case '4':
+      return PLC4C_DRIVER_S7_CONTROLLER_TYPE_S7_400;
+    default:
+      return PLC4C_DRIVER_S7_CONTROLLER_TYPE_ANY;
+  }
+}
+
+int8_t decode_hex_char(char c) {
+  if (('0' <= c) && (c <= '9')) {
+    return c - 48;
+  }
+  if (('A' <= c) && (c <= 'D')) {
+    return c - 55;
+  }
+  return -1;
+}
+
+plc4c_return_code decode_byte(const char* from_ptr, const char* to_ptr, uint8_t* value) {
+  if (to_ptr - from_ptr != 2) {
+    return INTERNAL_ERROR;
+  }
+
+  int8_t first_char = decode_hex_char(*from_ptr);
+  int8_t second_char = decode_hex_char(*(from_ptr + 1));
+  if ((first_char == -1) || (second_char == -1)) {
+    return INTERNAL_ERROR;
+  }
+  *value = ((uint8_t) ((uint8_t) first_char << (uint8_t) 4)) | (uint8_t) second_char;
+  return OK;
+}
+
+plc4c_return_code plc4c_driver_s7_encode_address(
+    char* address, void** item) {
+
+  plc4c_s7_read_write_s7_var_request_parameter_item* s7_item =
+      malloc(sizeof(plc4c_s7_read_write_s7_var_request_parameter_item));
+  s7_item->_type =
+      plc4c_s7_read_write_s7_var_request_parameter_item_type_plc4c_s7_read_write_s7_var_request_parameter_item_address;
+
+  // Java Regexp:
+  // ADDRESS_PATTERN =
+  // ^%(?<memoryArea>.)(?<transferSizeCode>[XBWD]?)(?<byteOffset>\d{1,7})(.(?<bitOffset>[0-7]))?:(?<dataType>[a-zA-Z_]+)(\[(?<numElements>\d+)])?
+  // DATA_BLOCK_ADDRESS_PATTERN =
+  // ^%DB(?<blockNumber>\d{1,5}).DB(?<transferSizeCode>[XBWD]?)(?<byteOffset>\d{1,7})(.(?<bitOffset>[0-7]))?:(?<dataType>[a-zA-Z_]+)(\[(?<numElements>\d+)])?
+  // DATA_BLOCK_SHORT_PATTERN =
+  // ^%DB(?<blockNumber>\d{1,5}).(?<byteOffset>\d{1,7})(.(?<bitOffset>[0-7]))?:(?<dataType>[a-zA-Z_]+)(\[(?<numElements>\d+)])?
+  // DATA_BLOCK_STRING_ADDRESS_PATTERN =
+  // ^%DB(?<blockNumber>\d{1,5}).DB(?<transferSizeCode>[XBWD]?)(?<byteOffset>\d{1,7}):STRING\((?<stringLength>\d{1,3})\)(\[(?<numElements>\d+)])?
+  // DATA_BLOCK_STRING_SHORT_PATTERN =
+  // ^%DB(?<blockNumber>\d{1,5}):(?<byteOffset>\d{1,7}):STRING\((?<stringLength>\d{1,3})\)(\[(?<numElements>\d+)])?
+  // PLC_PROXY_ADDRESS_PATTERN =
+  // [0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}
+
+  // Parser logic
+  char* cur_pos = address;
+  char* last_pos = address;
+  // - Does it start with "%"?
+  if (*cur_pos == '%') {
+    cur_pos++;
+
+    char* memory_area = NULL;
+    char* block_number = NULL;
+    char* transfer_size_code = NULL;
+    char* byte_offset = NULL;
+    char* bit_offset = NULL;
+    char* data_type = NULL;
+    char* string_length = NULL;
+    char* num_elements = NULL;
+
+    ////////////////////////////////////////////////////////////////////////////
+    // First extract the different parts of the address
+    ////////////////////////////////////////////////////////////////////////////
+
+    if (!isalpha(*cur_pos)) {
+      return INVALID_ADDRESS;
+    }
+
+    last_pos = cur_pos;
+    while (isalpha(*cur_pos)) {
+      cur_pos++;
+    }
+    uint16_t len = cur_pos - last_pos;
+    memory_area = malloc(sizeof(char) * (len + 1));
+    strncpy(memory_area, last_pos, len);
+    //*(memory_area + len + 1) = '/0';
+
+    // If it's a DB-block, get the block_number
+    if (strcmp(memory_area, "DB") == 0) {
+      last_pos = cur_pos;
+      while (isdigit(*cur_pos)) {
+        cur_pos++;
+      }
+      len = cur_pos - last_pos;
+      block_number = malloc(sizeof(char) * (len + 1));
+      strncpy(block_number, last_pos, len);
+
+      // Skip the "."
+      cur_pos++;
+    }
+
+    // If the next is not a digit it might be DB, DB{transferSizeCode}
+    // or {transferSizeCode}
+    if (!isdigit(*cur_pos)) {
+      last_pos = cur_pos;
+      while (!isdigit(*cur_pos)) {
+        cur_pos++;
+      }
+      len = cur_pos - last_pos;
+      // If it's at least 2 digits long, it's DB{transferSizeCode} or
+      // "DB". So we get rid of the "DB" prefix, as this has no value for us.
+      if (len >= 2) {
+        last_pos += 2;
+      }
+      // If it's 1 or 3 long it contains a "transferSizeCode", which is just
+      // one char long.
+      if ((len == 1) || (len == 3)) {
+        transfer_size_code = malloc(sizeof(char) * 2);
+        *transfer_size_code = *last_pos;
+        *(transfer_size_code + 1) = '\0';
+      }
+    }
+
+    // Next comes the byte_offset
+    last_pos = cur_pos;
+    while (isdigit(*cur_pos)) {
+      cur_pos++;
+    }
+    len = cur_pos - last_pos;
+    byte_offset = malloc(sizeof(char) * (len + 1));
+    strncpy(byte_offset, last_pos, len);
+
+    // Parse the bit_offset
+    if (*cur_pos == '.') {
+      cur_pos++;
+      // Next comes the byte_offset
+      last_pos = cur_pos;
+      while (isdigit(*cur_pos)) {
+        cur_pos++;
+      }
+      len = cur_pos - last_pos;
+      bit_offset = malloc(sizeof(char) * (len + 1));
+      strncpy(bit_offset, last_pos, len);
+    }
+
+    // Skip the ":" char.
+    cur_pos++;
+
+    // Next comes the data_type
+    last_pos = cur_pos;
+    while (isalpha(*cur_pos)) {
+      cur_pos++;
+    }
+    len = cur_pos - last_pos;
+    data_type = malloc(sizeof(char) * (len + 1));
+    strncpy(data_type, last_pos, len);
+
+    if ((*cur_pos == '(') && (strcmp(data_type, "STRING") == 0)) {
+      // Next comes the string_length
+      last_pos = cur_pos;
+      while (isalpha(*cur_pos)) {
+        cur_pos++;
+      }
+      len = cur_pos - last_pos;
+      string_length = malloc(sizeof(char) * (len + 1));
+      strncpy(string_length, last_pos, len);
+
+      // Skip the ")"
+      cur_pos++;
+    }
+
+    if (*cur_pos == '[') {
+      // Next comes the num_elements
+      cur_pos++;
+      last_pos = cur_pos;
+      while (isdigit(*cur_pos)) {
+        cur_pos++;
+      }
+      len = cur_pos - last_pos;
+      num_elements = malloc(sizeof(char) * (len + 1));
+      strncpy(num_elements, last_pos, len);
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    // Now parse the contents.
+    ////////////////////////////////////////////////////////////////////////////
+
+    plc4c_s7_read_write_s7_address* any_address = malloc(sizeof(plc4c_s7_read_write_s7_address));
+    if(any_address == NULL) {
+      return NO_MEMORY;
+    }
+    any_address->_type = plc4c_s7_read_write_s7_address_type_plc4c_s7_read_write_s7_address_any;
+
+    for(int i = 0; i < plc4c_s7_read_write_memory_area_num_values(); i++) {
+      plc4c_s7_read_write_memory_area ma = plc4c_s7_read_write_memory_area_value_for_index(i);
+      if(strcmp(plc4c_s7_read_write_memory_area_get_short_name(ma), memory_area) == 0) {
+        any_address->s7_address_any_area = ma;
+        break;
+      }
+    }
+
+    if (block_number != NULL) {
+      any_address->s7_address_any_db_number = strtol(block_number, 0, 10);
+    } else {
+      any_address->s7_address_any_db_number = 0;
+    }
+
+    any_address->s7_address_any_byte_address = strtol(byte_offset, 0, 10);
+
+    if (bit_offset != NULL) {
+      any_address->s7_address_any_bit_address = strtol(bit_offset, 0, 10);
+    } else {
+      any_address->s7_address_any_bit_address = 0;
+    }
+
+    any_address->s7_address_any_transport_size =
+        plc4c_s7_read_write_transport_size_value_of(data_type);
+
+    if (num_elements != NULL) {
+      any_address->s7_address_any_number_of_elements =
+          strtol(num_elements, 0, 10);
+    } else {
+      any_address->s7_address_any_number_of_elements = 1;
+    }
+
+    if (any_address->s7_address_any_transport_size ==
+         plc4c_s7_read_write_transport_size_STRING) {
+      if (string_length != NULL) {
+        any_address->s7_address_any_number_of_elements =
+            strtol(string_length, 0, 10) *
+                any_address->s7_address_any_number_of_elements;
+      } else if (any_address->s7_address_any_transport_size ==
+                 plc4c_s7_read_write_transport_size_STRING) {
+        any_address->s7_address_any_number_of_elements =
+            254 * any_address->s7_address_any_number_of_elements;
+      }
+    }
+
+    // Check the optional transport size code.
+    if(transfer_size_code != NULL) {
+      if(plc4c_s7_read_write_transport_size_get_size_code(any_address->s7_address_any_transport_size) != *transfer_size_code) {
+        return INVALID_ADDRESS;
+      }
+    }
+
+    s7_item->s7_var_request_parameter_item_address_address = any_address;
+  }
+  // - Else -> PLC_PROXY_ADDRESS_PATTERN
+  else {
+    //   - parse the sequence of 2 digit Hex numbers into an array of 10 bytes
+    uint8_t* raw_data = malloc(sizeof(uint8_t) * 10);
+    if (raw_data == NULL) {
+      return NO_MEMORY;
+    }
+    cur_pos += 2;
+    for (int i = 0; i < 10; i++) {
+      plc4c_return_code return_code =
+          decode_byte(last_pos, cur_pos, raw_data + i);
+      if (return_code != OK) {
+        return return_code;
+      }
+      if (i < 9) {
+        if (*cur_pos != '-') {
+          return INVALID_ADDRESS;
+        }
+        // Move to the next segment.
+        last_pos += 3;
+        cur_pos += 3;
+      }
+    }
+    //   - create a plc4c_spi_read_buffer from the 10 byte array
+    plc4c_spi_read_buffer* read_buffer;
+    plc4c_return_code return_code =
+        plc4c_spi_read_buffer_create(raw_data, 10, &read_buffer);
+    if (return_code != OK) {
+      return return_code;
+    }
+    //   - plc4c_s7_read_write_s7_var_request_parameter_item_parse function to
+    //   parse the byte array
+    //   - directly add the resulting struct to the request
+    plc4c_s7_read_write_s7_address_parse(
+        read_buffer, &s7_item->s7_var_request_parameter_item_address_address);
+  }
+
+  *item = s7_item;
+  return OK;
+}
diff --git a/sandbox/plc4c/drivers/s7/src/driver_s7_packets.c b/sandbox/plc4c/drivers/s7/src/driver_s7_packets.c
new file mode 100644
index 0000000..d9e639e
--- /dev/null
+++ b/sandbox/plc4c/drivers/s7/src/driver_s7_packets.c
@@ -0,0 +1,524 @@
+/*
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permiSchreib' missions and limitations
+  under the License.
+*/
+
+#include <cotp_protocol_class.h>
+#include <ctype.h>
+#include <plc4c/driver_s7.h>
+#include <plc4c/spi/types_private.h>
+#include <stdlib.h>
+#include <string.h>
+#include <tpkt_packet.h>
+
+#include "plc4c/driver_s7_encode_decode.h"
+
+/**
+ * Function used by the driver to tell the transport if there is a full
+ * packet the driver can operate on available.
+ *
+ * @param buffer_data pointer to the buffer
+ * @param buffer_length length of the buffer
+ * @return positive integer = length of the packet, 0 = not enough,
+ * try again later, negative integer = remove the given amount of bytes
+ * from the buffer.
+ */
+int16_t plc4c_driver_s7_select_message_function(uint8_t* buffer_data,
+                                                uint16_t buffer_length) {
+  // If the packet doesn't start with 0x03, it's a corrupt package.
+  if (buffer_length >= 1) {
+    // The buffer seems to be corrupt, try to find a sequence of 0x03 0x00
+    // and return the negative number of bytes needed to find that or the
+    // number of bytes in the buffer so it will simply clean the buffer
+    // completely.
+    if (*buffer_data != 0x03) {
+      for (int i = 1; i < (buffer_length - 1); i++) {
+        buffer_data++;
+        if ((*buffer_data == 0x03) && (*(buffer_data + 1) == 0x00)) {
+          // We've found a potential new packet start.
+          return -(i - 1);
+        }
+      }
+      // We didn't find a new start, delete the entire content except the last
+      // byte (as this could be the start of the next frame and we couldn't
+      // confirm this.
+      return -(buffer_length - 1);
+    }
+  }
+  // The length information is located in bytes 3 and 4
+  if (buffer_length >= 4) {
+    uint16_t packet_length =
+        ((uint16_t) *(buffer_data + 2) << 8) |
+        ((uint16_t) *(buffer_data + 3));
+    if (buffer_length >= packet_length) {
+      return packet_length;
+    }
+    // 8192 is the maximum pdu size, so if the value is larger, the packet is
+    // probably corrupt.
+    if (packet_length > 8192) {
+      for (int i = 1; i < (buffer_length - 1); i++) {
+        buffer_data++;
+        if ((*buffer_data == 0x03) && (*(buffer_data + 1) == 0x00)) {
+          // We've found a potential new packet start.
+          return -(i - 1);
+        }
+      }
+      return -(buffer_length - 1);
+    }
+    return packet_length;
+  }
+  // In all other cases, we'll just have to wait for the next time.
+  return 0;
+}
+
+plc4c_return_code plc4c_driver_s7_send_packet(plc4c_connection* connection,
+                              plc4c_s7_read_write_tpkt_packet* packet) {
+  // Get the size required to contain the serialized form of this packet.
+  uint16_t packet_size =
+      plc4c_s7_read_write_tpkt_packet_length_in_bytes(packet);
+
+  // Serialize this message to a byte-array.
+  plc4c_spi_write_buffer* write_buffer;
+  plc4c_return_code return_code =
+      plc4c_spi_write_buffer_create(packet_size, &write_buffer);
+  if (return_code != OK) {
+    return return_code;
+  }
+  return_code = plc4c_s7_read_write_tpkt_packet_serialize(write_buffer, packet);
+  if(return_code != OK) {
+    return return_code;
+  }
+
+  // Now send this to the recipient.
+  return_code = connection->transport->send_message(connection->transport_configuration, write_buffer);
+  if (return_code != OK) {
+    return return_code;
+  }
+
+  return OK;
+}
+
+plc4c_return_code plc4c_driver_s7_receive_packet(plc4c_connection* connection,
+                                 plc4c_s7_read_write_tpkt_packet** packet) {
+  // Check with the transport if there is a packet available.
+  // If it is, get a read_buffer for reading it.
+  plc4c_spi_read_buffer* read_buffer;
+  plc4c_return_code return_code = connection->transport->select_message(
+      connection->transport_configuration,
+      4, plc4c_driver_s7_select_message_function,
+      &read_buffer);
+  // OK is only returned if a packet is available.
+  if (return_code != OK) {
+    return return_code;
+  }
+
+  // Parse the packet by consuming the read_buffer data.
+  *packet = NULL;
+  return_code = plc4c_s7_read_write_tpkt_packet_parse(read_buffer, packet);
+  if (return_code != OK) {
+    return return_code;
+  }
+
+  // In this case a packet was available and parsed.
+  return OK;
+}
+
+/**
+ * Create a COTP connection request packet.
+ *
+ * @param configuration configuration of the current connection.
+ * @param plc4c_s7_read_write_tpkt_packet COTP connection-request (return)
+ * @return OK, if the packet was correctly prepared, otherwise not-OK.
+ */
+plc4c_return_code plc4c_driver_s7_create_cotp_connection_request(
+    plc4c_driver_s7_config* configuration,
+    plc4c_s7_read_write_tpkt_packet** cotp_connect_request_packet) {
+  *cotp_connect_request_packet =
+      malloc(sizeof(plc4c_s7_read_write_tpkt_packet));
+  if (*cotp_connect_request_packet == NULL) {
+    return NO_MEMORY;
+  }
+  (*cotp_connect_request_packet)->payload =
+      malloc(sizeof(plc4c_s7_read_write_cotp_packet));
+  if ((*cotp_connect_request_packet)->payload == NULL) {
+    return NO_MEMORY;
+  }
+  (*cotp_connect_request_packet)->payload->_type =
+      plc4c_s7_read_write_cotp_packet_type_plc4c_s7_read_write_cotp_packet_connection_request;
+  (*cotp_connect_request_packet)
+      ->payload->cotp_packet_connection_request_destination_reference = 0x0000;
+  (*cotp_connect_request_packet)
+      ->payload->cotp_packet_connection_request_source_reference = 0x000F;
+  (*cotp_connect_request_packet)
+      ->payload->cotp_packet_connection_request_protocol_class =
+      plc4c_s7_read_write_cotp_protocol_class_CLASS_0;
+
+  // Add the COTP parameters: Called TSAP, Calling TSAP and TPDU Size.
+  plc4c_utils_list_create(
+      &((*cotp_connect_request_packet)->payload->parameters));
+  plc4c_s7_read_write_cotp_parameter* called_tsap_parameter =
+      malloc(sizeof(plc4c_s7_read_write_cotp_parameter));
+  if (called_tsap_parameter == NULL) {
+    return NO_MEMORY;
+  }
+  called_tsap_parameter->_type =
+      plc4c_s7_read_write_cotp_parameter_type_plc4c_s7_read_write_cotp_parameter_called_tsap;
+  called_tsap_parameter->cotp_parameter_called_tsap_tsap_id =
+      configuration->called_tsap_id;
+
+  plc4c_utils_list_insert_head_value(
+      (*cotp_connect_request_packet)->payload->parameters,
+      called_tsap_parameter);
+  plc4c_s7_read_write_cotp_parameter* calling_tsap_parameter =
+      malloc(sizeof(plc4c_s7_read_write_cotp_parameter));
+  if (calling_tsap_parameter == NULL) {
+    return NO_MEMORY;
+  }
+  calling_tsap_parameter->_type =
+      plc4c_s7_read_write_cotp_parameter_type_plc4c_s7_read_write_cotp_parameter_calling_tsap;
+  calling_tsap_parameter->cotp_parameter_calling_tsap_tsap_id =
+      configuration->calling_tsap_id;
+
+  plc4c_utils_list_insert_head_value(
+      (*cotp_connect_request_packet)->payload->parameters,
+      calling_tsap_parameter);
+  plc4c_s7_read_write_cotp_parameter* tpdu_size_parameter =
+      malloc(sizeof(plc4c_s7_read_write_cotp_parameter));
+  if (tpdu_size_parameter == NULL) {
+    return NO_MEMORY;
+  }
+  tpdu_size_parameter->_type =
+      plc4c_s7_read_write_cotp_parameter_type_plc4c_s7_read_write_cotp_parameter_tpdu_size;
+  tpdu_size_parameter->cotp_parameter_tpdu_size_tpdu_size =
+      configuration->cotp_tpdu_size;
+
+  plc4c_utils_list_insert_head_value(
+      (*cotp_connect_request_packet)->payload->parameters, tpdu_size_parameter);
+
+  // For a COTP connection request, there is no payload.
+  (*cotp_connect_request_packet)->payload->payload = NULL;
+
+  return OK;
+}
+
+/**
+ * Create a S7 connection request packet.
+ *
+ * @param configuration configuration of the current connection.
+ * @param plc4c_s7_read_write_tpkt_packet S7 connection-request (return)
+ * @return OK, if the packet was correctly prepared, otherwise not-OK.
+ */
+plc4c_return_code plc4c_driver_s7_create_s7_connection_request(
+    plc4c_driver_s7_config* configuration,
+    plc4c_s7_read_write_tpkt_packet** s7_connect_request_packet) {
+  *s7_connect_request_packet = malloc(sizeof(plc4c_s7_read_write_tpkt_packet));
+  if (*s7_connect_request_packet == NULL) {
+    return NO_MEMORY;
+  }
+  (*s7_connect_request_packet)->payload =
+      malloc(sizeof(plc4c_s7_read_write_cotp_packet));
+  if ((*s7_connect_request_packet)->payload == NULL) {
+    return NO_MEMORY;
+  }
+  (*s7_connect_request_packet)->payload->_type =
+      plc4c_s7_read_write_cotp_packet_type_plc4c_s7_read_write_cotp_packet_data;
+  (*s7_connect_request_packet)->payload->parameters = NULL;
+  (*s7_connect_request_packet)->payload->cotp_packet_data_eot = true;
+  (*s7_connect_request_packet)->payload->cotp_packet_data_tpdu_ref = 1;
+
+  (*s7_connect_request_packet)->payload->payload =
+      malloc(sizeof(plc4c_s7_read_write_s7_message));
+  if ((*s7_connect_request_packet)->payload->payload == NULL) {
+    return NO_MEMORY;
+  }
+  (*s7_connect_request_packet)->payload->payload->_type =
+      plc4c_s7_read_write_s7_message_type_plc4c_s7_read_write_s7_message_request;
+
+  (*s7_connect_request_packet)->payload->payload->parameter =
+      malloc(sizeof(plc4c_s7_read_write_s7_parameter));
+  if ((*s7_connect_request_packet)->payload->payload->parameter == NULL) {
+    return NO_MEMORY;
+  }
+  (*s7_connect_request_packet)->payload->payload->parameter->_type =
+      plc4c_s7_read_write_s7_parameter_type_plc4c_s7_read_write_s7_parameter_setup_communication;
+  (*s7_connect_request_packet)
+      ->payload->payload->parameter
+      ->s7_parameter_setup_communication_max_amq_callee =
+      configuration->max_amq_callee;
+  (*s7_connect_request_packet)
+      ->payload->payload->parameter
+      ->s7_parameter_setup_communication_max_amq_caller =
+      configuration->max_amq_caller;
+  (*s7_connect_request_packet)
+      ->payload->payload->parameter
+      ->s7_parameter_setup_communication_pdu_length = configuration->pdu_size;
+
+  (*s7_connect_request_packet)->payload->payload->payload = NULL;
+/*      malloc(sizeof(plc4c_s7_read_write_s7_payload));
+  if ((*s7_connect_request_packet)->payload->payload->payload == NULL) {
+    return NO_MEMORY;
+  }
+  (*s7_connect_request_packet)->payload->payload->payload->_type =
+      plc4c_s7_read_write_s7_payload_type_plc4c_s7_read_write_s7_payload_user_data;*/
+  return OK;
+}
+
+/**
+ * Create a S7 identify remote request packet
+ *
+ * @param configuration configuration of the current connection.
+ * @param plc4c_s7_read_write_tpkt_packet S7 identify remote request (return)
+ * @return OK, if the packet was correctly prepared, otherwise not-OK.
+ */
+plc4c_return_code plc4c_driver_s7_create_s7_identify_remote_request(
+    plc4c_s7_read_write_tpkt_packet** s7_identify_remote_request_packet) {
+  *s7_identify_remote_request_packet =
+      malloc(sizeof(plc4c_s7_read_write_tpkt_packet));
+  if (*s7_identify_remote_request_packet == NULL) {
+    return NO_MEMORY;
+  }
+  (*s7_identify_remote_request_packet)->payload =
+      malloc(sizeof(plc4c_s7_read_write_cotp_packet));
+  if ((*s7_identify_remote_request_packet)->payload == NULL) {
+    return NO_MEMORY;
+  }
+  (*s7_identify_remote_request_packet)->payload->_type =
+      plc4c_s7_read_write_cotp_packet_type_plc4c_s7_read_write_cotp_packet_data;
+  (*s7_identify_remote_request_packet)->payload->parameters = NULL;
+  (*s7_identify_remote_request_packet)->payload->cotp_packet_data_eot = true;
+  (*s7_identify_remote_request_packet)->payload->cotp_packet_data_tpdu_ref = 2;
+
+  (*s7_identify_remote_request_packet)->payload->payload =
+      malloc(sizeof(plc4c_s7_read_write_s7_message));
+  if ((*s7_identify_remote_request_packet)->payload->payload == NULL) {
+    return NO_MEMORY;
+  }
+  (*s7_identify_remote_request_packet)->payload->payload->_type =
+      plc4c_s7_read_write_s7_message_type_plc4c_s7_read_write_s7_message_user_data;
+
+  // Create a Parameter
+  (*s7_identify_remote_request_packet)->payload->payload->parameter =
+      malloc(sizeof(plc4c_s7_read_write_s7_parameter));
+  if ((*s7_identify_remote_request_packet)->payload->payload->parameter == NULL) {
+    return NO_MEMORY;
+  }
+  (*s7_identify_remote_request_packet)->payload->payload->parameter->_type =
+      plc4c_s7_read_write_s7_parameter_type_plc4c_s7_read_write_s7_parameter_user_data;
+  plc4c_utils_list_create(
+      &((*s7_identify_remote_request_packet)
+            ->payload->payload->parameter->s7_parameter_user_data_items));
+  // Create the Parameter Item
+  plc4c_s7_read_write_s7_parameter_user_data_item* parameter_item =
+      malloc(sizeof(plc4c_s7_read_write_s7_parameter_user_data_item));
+  parameter_item->_type =
+      plc4c_s7_read_write_s7_parameter_user_data_item_type_plc4c_s7_read_write_s7_parameter_user_data_item_cpu_functions;
+  parameter_item->s7_parameter_user_data_item_cpu_functions_method = 0x11;
+  parameter_item->s7_parameter_user_data_item_cpu_functions_cpu_function_type =
+      0x4;
+  parameter_item->s7_parameter_user_data_item_cpu_functions_cpu_function_group =
+      0x4;
+  parameter_item->s7_parameter_user_data_item_cpu_functions_cpu_subfunction =
+      0x01;
+  parameter_item->s7_parameter_user_data_item_cpu_functions_sequence_number =
+      0x00;
+  parameter_item
+      ->s7_parameter_user_data_item_cpu_functions_data_unit_reference_number =
+      NULL;
+  parameter_item->s7_parameter_user_data_item_cpu_functions_last_data_unit =
+      NULL;
+  parameter_item->s7_parameter_user_data_item_cpu_functions_error_code = NULL;
+  plc4c_utils_list_insert_head_value(
+      (*s7_identify_remote_request_packet)
+          ->payload->payload->parameter->s7_parameter_user_data_items,
+      parameter_item);
+
+  // Create the Payload
+  (*s7_identify_remote_request_packet)->payload->payload->payload = malloc(sizeof(plc4c_s7_read_write_s7_payload));
+  if ((*s7_identify_remote_request_packet)->payload->payload->parameter == NULL) {
+    return NO_MEMORY;
+  }
+  (*s7_identify_remote_request_packet)->payload->payload->payload->_type =
+      plc4c_s7_read_write_s7_payload_type_plc4c_s7_read_write_s7_payload_user_data;
+  plc4c_utils_list_create(
+      &((*s7_identify_remote_request_packet)
+            ->payload->payload->payload->s7_payload_user_data_items));
+  // Create the Payload Item
+  plc4c_s7_read_write_s7_payload_user_data_item* payload_item =
+      malloc(sizeof(plc4c_s7_read_write_s7_payload_user_data_item));
+  payload_item->_type =
+      plc4c_s7_read_write_s7_payload_user_data_item_type_plc4c_s7_read_write_s7_payload_user_data_item_cpu_function_read_szl_request;
+  payload_item->return_code = plc4c_s7_read_write_data_transport_error_code_OK;
+  payload_item->transport_size =
+      plc4c_s7_read_write_data_transport_size_OCTET_STRING;
+  payload_item->szl_index = 0x0000;
+  payload_item->szl_id = malloc(sizeof(plc4c_s7_read_write_szl_id));
+  if (payload_item->szl_id == NULL) {
+    return NO_MEMORY;
+  }
+  payload_item->szl_id->type_class =
+      plc4c_s7_read_write_szl_module_type_class_CPU;
+  payload_item->szl_id->sublist_extract = 0x00;
+  payload_item->szl_id->sublist_list =
+      plc4c_s7_read_write_szl_sublist_MODULE_IDENTIFICATION;
+  plc4c_utils_list_insert_head_value(
+      (*s7_identify_remote_request_packet)
+          ->payload->payload->payload->s7_payload_user_data_items,
+      payload_item);
+
+  return OK;
+}
+
+/**
+ * Create a S7 read request packet
+ *
+ * @param configuration configuration of the current connection.
+ * @param plc4c_s7_read_write_tpkt_packet S7 read request (return)
+ * @return OK, if the packet was correctly prepared, otherwise not-OK.
+ */
+plc4c_return_code plc4c_driver_s7_create_s7_read_request(
+    plc4c_read_request* read_request,
+    plc4c_s7_read_write_tpkt_packet** s7_read_request_packet) {
+  plc4c_driver_s7_config* configuration =
+      read_request->connection->configuration;
+
+  *s7_read_request_packet = malloc(sizeof(s7_read_request_packet));
+  if (*s7_read_request_packet == NULL) {
+    return NO_MEMORY;
+  }
+
+  (*s7_read_request_packet)->payload =
+      malloc(sizeof(plc4c_s7_read_write_cotp_packet));
+  if((*s7_read_request_packet)->payload == NULL) {
+    return NO_MEMORY;
+  }
+  (*s7_read_request_packet)->payload->_type =
+      plc4c_s7_read_write_cotp_packet_type_plc4c_s7_read_write_cotp_packet_data;
+  (*s7_read_request_packet)->payload->cotp_packet_data_tpdu_ref =
+      configuration->pdu_id++;
+  (*s7_read_request_packet)->payload->cotp_packet_data_eot = true;
+  (*s7_read_request_packet)->payload->parameters = NULL;
+  (*s7_read_request_packet)->payload->payload =
+      malloc(sizeof(plc4c_s7_read_write_s7_message));
+  if((*s7_read_request_packet)->payload->payload == NULL) {
+    return NO_MEMORY;
+  }
+  (*s7_read_request_packet)->payload->payload->_type =
+      plc4c_s7_read_write_s7_message_type_plc4c_s7_read_write_s7_message_request;
+  (*s7_read_request_packet)->payload->payload->parameter =
+      malloc(sizeof(plc4c_s7_read_write_s7_parameter));
+  if((*s7_read_request_packet)->payload->payload->parameter == NULL) {
+    return NO_MEMORY;
+  }
+  (*s7_read_request_packet)->payload->payload->parameter->_type =
+      plc4c_s7_read_write_s7_parameter_type_plc4c_s7_read_write_s7_parameter_read_var_request;
+  plc4c_utils_list_create(
+      &(*s7_read_request_packet)
+           ->payload->payload->parameter->s7_parameter_read_var_request_items);
+
+  plc4c_list_element* cur_item = read_request->items->tail;
+  while (cur_item != NULL) {
+    plc4c_item* item = cur_item->value;
+    // Get the item address from the API request.
+    plc4c_s7_read_write_s7_var_request_parameter_item* parsed_item_address = item->address;
+
+    // Add the new item to the request.
+    plc4c_utils_list_insert_head_value(
+        (*s7_read_request_packet)
+            ->payload->payload->parameter->s7_parameter_read_var_request_items,
+        parsed_item_address);
+
+    cur_item = cur_item->next;
+  }
+
+  (*s7_read_request_packet)->payload->payload->payload = NULL;
+  return OK;
+}
+
+/**
+ * Create a S7 write request packet
+ *
+ * @param configuration configuration of the current connection.
+ * @param plc4c_s7_read_write_tpkt_packet S7 write request (return)
+ * @return OK, if the packet was correctly prepared, otherwise not-OK.
+ */
+plc4c_return_code plc4c_driver_s7_create_s7_write_request(
+    plc4c_write_request* write_request,
+    plc4c_s7_read_write_tpkt_packet** s7_write_request_packet) {
+  plc4c_driver_s7_config* configuration =
+      write_request->connection->configuration;
+
+  *s7_write_request_packet = malloc(sizeof(s7_write_request_packet));
+  if (*s7_write_request_packet == NULL) {
+    return NO_MEMORY;
+  }
+
+  (*s7_write_request_packet)->payload =
+      malloc(sizeof(plc4c_s7_read_write_cotp_packet));
+  (*s7_write_request_packet)->payload->_type =
+      plc4c_s7_read_write_cotp_packet_type_plc4c_s7_read_write_cotp_packet_data;
+  (*s7_write_request_packet)->payload->cotp_packet_data_tpdu_ref =
+      configuration->pdu_id++;
+  (*s7_write_request_packet)->payload->cotp_packet_data_eot = true;
+  (*s7_write_request_packet)->payload->payload =
+      malloc(sizeof(plc4c_s7_read_write_s7_message));
+  (*s7_write_request_packet)->payload->payload->_type =
+      plc4c_s7_read_write_s7_message_type_plc4c_s7_read_write_s7_message_request;
+  (*s7_write_request_packet)->payload->payload->parameter =
+      malloc(sizeof(plc4c_s7_read_write_s7_parameter));
+  (*s7_write_request_packet)->payload->payload->parameter->_type =
+      plc4c_s7_read_write_s7_parameter_type_plc4c_s7_read_write_s7_parameter_write_var_request;
+  plc4c_utils_list_create(
+      &(*s7_write_request_packet)
+          ->payload->payload->parameter->s7_parameter_read_var_request_items);
+
+  plc4c_list_element* item = write_request->items->tail;
+  while (item != NULL) {
+    // Get the item address from the API request.
+    char* itemAddress = item->value;
+
+    // Create the item ...
+    plc4c_s7_read_write_s7_var_request_parameter_item* request_item;
+    plc4c_return_code return_code =
+        plc4c_driver_s7_encode_address(itemAddress, &request_item);
+    if (return_code != OK) {
+      return return_code;
+    }
+
+    // Add the new item to the request.
+    plc4c_utils_list_insert_head_value(
+        (*s7_write_request_packet)
+            ->payload->payload->parameter->s7_parameter_read_var_request_items,
+        request_item);
+
+    item = item->next;
+  }
+
+  (*s7_write_request_packet)->payload->payload->payload =
+      malloc(sizeof(plc4c_s7_read_write_s7_payload));
+  if((*s7_write_request_packet)->payload->payload->payload == NULL) {
+    return NO_MEMORY;
+  }
+  (*s7_write_request_packet)->payload->payload->payload->_type =
+      plc4c_s7_read_write_s7_payload_type_plc4c_s7_read_write_s7_payload_write_var_request;
+  plc4c_utils_list_create(
+      &(*s7_write_request_packet)->payload->payload->payload->s7_payload_write_var_request_items);
+
+  // TODO: Implement the value encoding ...
+  // TODO: Add all the encoded item values ...
+
+  return OK;
+}
diff --git a/sandbox/plc4c/drivers/s7/src/driver_s7_sm_connect.c b/sandbox/plc4c/drivers/s7/src/driver_s7_sm_connect.c
new file mode 100644
index 0000000..f2aae94
--- /dev/null
+++ b/sandbox/plc4c/drivers/s7/src/driver_s7_sm_connect.c
@@ -0,0 +1,348 @@
+/*
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+*/
+
+#include <ctype.h>
+#include <plc4c/plc4c.h>
+#include <plc4c/spi/types_private.h>
+#include <stdlib.h>
+#include <string.h>
+#include "plc4c/driver_s7.h"
+#include "plc4c/driver_s7_encode_decode.h"
+#include "plc4c/driver_s7_packets.h"
+#include "cotp_protocol_class.h"
+#include "tpkt_packet.h"
+
+enum plc4c_driver_s7_connect_states {
+  PLC4C_DRIVER_S7_CONNECT_INIT,
+  PLC4C_DRIVER_S7_CONNECT_TRANSPORT_CONNECT,
+  PLC4C_DRIVER_S7_CONNECT_SEND_COTP_CONNECT_REQUEST,
+  PLC4C_DRIVER_S7_CONNECT_RECEIVE_COTP_CONNECT_RESPONSE,
+  PLC4C_DRIVER_S7_CONNECT_SEND_S7_CONNECT_REQUEST,
+  PLC4C_DRIVER_S7_CONNECT_RECEIVE_S7_CONNECT_RESPONSE,
+  PLC4C_DRIVER_S7_CONNECT_SEND_S7_IDENTIFICATION_REQUEST,
+  PLC4C_DRIVER_S7_CONNECT_RECEIVE_S7_IDENTIFICATION_RESPONSE,
+  PLC4C_DRIVER_S7_CONNECT_FINISHED
+};
+
+/**
+ * State machine function for establishing a connection to a remote S7 device.
+ * @param task the current system task
+ * @return return code of the current state machine step execution
+ */
+plc4c_return_code plc4c_driver_s7_connect_machine_function(
+    plc4c_system_task* task) {
+  plc4c_connection* connection = task->context;
+  if (connection == NULL) {
+    return INTERNAL_ERROR;
+  }
+  // If we were already connected, return an error
+  if (plc4c_connection_get_connected(connection)) {
+    return ALREADY_CONNECTED;
+  }
+  plc4c_driver_s7_config* configuration = connection->configuration;
+
+  // Initialize the pdu id (The first messages are hard-coded)
+  configuration->pdu_id = 4;
+
+  switch (task->state_id) {
+    // Initialize some internal data-structures.
+    case PLC4C_DRIVER_S7_CONNECT_INIT: {
+      // Calculate some internal settings from the values provided in the
+      // configuration.
+      configuration->calling_tsap_id = plc4c_driver_s7_encode_tsap_id(
+          PLC4C_DRIVER_S7_DEVICE_GROUP_OTHERS, configuration->local_rack,
+          configuration->local_slot);
+      configuration->called_tsap_id = plc4c_driver_s7_encode_tsap_id(
+          PLC4C_DRIVER_S7_DEVICE_GROUP_PG_OR_PC, configuration->remote_rack,
+          configuration->remote_slot);
+      configuration->cotp_tpdu_size =
+          plc4c_driver_s7_get_nearest_matching_tpdu_size(
+              configuration->pdu_size);
+      configuration->pdu_size = configuration->cotp_tpdu_size - 16;
+
+      task->state_id = PLC4C_DRIVER_S7_CONNECT_TRANSPORT_CONNECT;
+      break;
+    }
+    case PLC4C_DRIVER_S7_CONNECT_TRANSPORT_CONNECT: {
+      plc4c_return_code return_code = connection->transport->open(connection->transport_configuration);
+      if(return_code != OK) {
+        return return_code;
+      }
+
+      task->state_id = PLC4C_DRIVER_S7_CONNECT_SEND_COTP_CONNECT_REQUEST;
+      break;
+    }
+    // Send a COTP connection request.
+    case PLC4C_DRIVER_S7_CONNECT_SEND_COTP_CONNECT_REQUEST: {
+      // Get a COTP connection response for the settings in the config.
+      plc4c_s7_read_write_tpkt_packet* cotp_connect_request_packet;
+      plc4c_return_code return_code =
+          plc4c_driver_s7_create_cotp_connection_request(
+              configuration, &cotp_connect_request_packet);
+      if (return_code != OK) {
+        return return_code;
+      }
+
+      // Send the packet to the remote.
+      return_code = plc4c_driver_s7_send_packet(connection, cotp_connect_request_packet);
+      if (return_code != OK) {
+        return return_code;
+      }
+
+      task->state_id = PLC4C_DRIVER_S7_CONNECT_RECEIVE_COTP_CONNECT_RESPONSE;
+      break;
+    }
+    // Receive a COTP connection response.
+    case PLC4C_DRIVER_S7_CONNECT_RECEIVE_COTP_CONNECT_RESPONSE: {
+      // Read a response packet.
+      plc4c_s7_read_write_tpkt_packet* cotp_connect_response_packet;
+      plc4c_return_code return_code =
+          plc4c_driver_s7_receive_packet(connection, &cotp_connect_response_packet);
+      // If we haven't read enough to process a full message, just try again
+      // next time.
+      if (return_code == UNFINISHED) {
+        return OK;
+      } else if (return_code != OK) {
+        return return_code;
+      }
+
+      // Check if the packet has the right type
+      if (cotp_connect_response_packet->payload->_type !=
+          plc4c_s7_read_write_cotp_packet_type_plc4c_s7_read_write_cotp_packet_connection_response) {
+        return INTERNAL_ERROR;
+      }
+
+      // Extract the information for: called-tsap-id, calling-tsap-id and
+      // tpdu-size.
+      plc4c_list_element* parameter_element =
+          cotp_connect_response_packet->payload->parameters->tail;
+      while (parameter_element != NULL) {
+        plc4c_s7_read_write_cotp_parameter* parameter =
+            parameter_element->value;
+        switch (parameter->_type) {
+          case plc4c_s7_read_write_cotp_parameter_type_plc4c_s7_read_write_cotp_parameter_tpdu_size: {
+            configuration->cotp_tpdu_size =
+                parameter->cotp_parameter_tpdu_size_tpdu_size;
+            break;
+          }
+          case plc4c_s7_read_write_cotp_parameter_type_plc4c_s7_read_write_cotp_parameter_calling_tsap: {
+            configuration->calling_tsap_id =
+                parameter->cotp_parameter_calling_tsap_tsap_id;
+            break;
+          }
+          case plc4c_s7_read_write_cotp_parameter_type_plc4c_s7_read_write_cotp_parameter_called_tsap: {
+            configuration->called_tsap_id =
+                parameter->cotp_parameter_called_tsap_tsap_id;
+            break;
+          }
+          default: {
+            break;
+          }
+        }
+        parameter_element = parameter_element->next;
+      }
+
+      // If we got the expected response, continue with the next higher level
+      // of connection.
+      task->state_id = PLC4C_DRIVER_S7_CONNECT_SEND_S7_CONNECT_REQUEST;
+      break;
+    }
+    // Send a S7 connection request.
+    case PLC4C_DRIVER_S7_CONNECT_SEND_S7_CONNECT_REQUEST: {
+      plc4c_s7_read_write_tpkt_packet* s7_connect_request_packet;
+      plc4c_return_code return_code =
+          plc4c_driver_s7_create_s7_connection_request(
+              configuration, &s7_connect_request_packet);
+      if (return_code != OK) {
+        return return_code;
+      }
+
+      // Send the packet to the remote.
+      return_code = plc4c_driver_s7_send_packet(connection, s7_connect_request_packet);
+      if (return_code != OK) {
+        return return_code;
+      }
+
+      task->state_id = PLC4C_DRIVER_S7_CONNECT_RECEIVE_S7_CONNECT_RESPONSE;
+      break;
+    }
+    // Receive a S7 connection response.
+    case PLC4C_DRIVER_S7_CONNECT_RECEIVE_S7_CONNECT_RESPONSE: {
+      // Read a response packet.
+      plc4c_s7_read_write_tpkt_packet* s7_connect_response_packet;
+      plc4c_return_code return_code =
+          plc4c_driver_s7_receive_packet(connection, &s7_connect_response_packet);
+      // If we haven't read enough to process a full message, just try again
+      // next time.
+      if (return_code == UNFINISHED) {
+        return OK;
+      } else if (return_code != OK) {
+        return return_code;
+      }
+
+      // Check if the packet has the right type
+      if (s7_connect_response_packet->payload->_type !=
+          plc4c_s7_read_write_cotp_packet_type_plc4c_s7_read_write_cotp_packet_data) {
+        return INTERNAL_ERROR;
+      }
+      if (s7_connect_response_packet->payload->payload->_type !=
+          plc4c_s7_read_write_s7_message_type_plc4c_s7_read_write_s7_message_response_data) {
+        return INTERNAL_ERROR;
+      }
+      if (s7_connect_response_packet->payload->payload->parameter->_type !=
+          plc4c_s7_read_write_s7_parameter_type_plc4c_s7_read_write_s7_parameter_setup_communication) {
+        return INTERNAL_ERROR;
+      }
+
+      // Extract and save the information for:
+      // max-amq-caller, max-amq-callee, pdu-size.
+      configuration->pdu_size =
+          s7_connect_response_packet->payload->payload->parameter
+              ->s7_parameter_setup_communication_pdu_length;
+      configuration->max_amq_caller =
+          s7_connect_response_packet->payload->payload->parameter
+              ->s7_parameter_setup_communication_max_amq_caller;
+      configuration->max_amq_callee =
+          s7_connect_response_packet->payload->payload->parameter
+              ->s7_parameter_setup_communication_max_amq_callee;
+
+      // If no controller is explicitly selected, detect it.
+      if (configuration->controller_type ==
+          PLC4C_DRIVER_S7_CONTROLLER_TYPE_ANY) {
+        task->state_id = PLC4C_DRIVER_S7_CONNECT_SEND_S7_IDENTIFICATION_REQUEST;
+      }
+      // If a controller is explicitly selected, we're done connecting.
+      else {
+        task->state_id = PLC4C_DRIVER_S7_CONNECT_FINISHED;
+      }
+      break;
+    }
+    // Send a S7 identification request.
+    case PLC4C_DRIVER_S7_CONNECT_SEND_S7_IDENTIFICATION_REQUEST: {
+      plc4c_s7_read_write_tpkt_packet* s7_identify_remote_request_packet;
+      plc4c_return_code return_code =
+          plc4c_driver_s7_create_s7_identify_remote_request(
+              &s7_identify_remote_request_packet);
+      if (return_code != OK) {
+        return return_code;
+      }
+
+      // Send the packet to the remote.
+      return_code = plc4c_driver_s7_send_packet(
+          connection, s7_identify_remote_request_packet);
+      if (return_code != OK) {
+        return return_code;
+      }
+
+      task->state_id =
+          PLC4C_DRIVER_S7_CONNECT_RECEIVE_S7_IDENTIFICATION_RESPONSE;
+      break;
+    }
+    // Receive a S7 identification response.
+    case PLC4C_DRIVER_S7_CONNECT_RECEIVE_S7_IDENTIFICATION_RESPONSE: {
+      // Read a response packet.
+      plc4c_s7_read_write_tpkt_packet* s7_identify_remote_response_packet;
+      plc4c_return_code return_code =
+          plc4c_driver_s7_receive_packet(connection, &s7_identify_remote_response_packet);
+      // If we haven't read enough to process a full message, just try again
+      // next time.
+      if (return_code == UNFINISHED) {
+        return OK;
+      } else if (return_code != OK) {
+        return return_code;
+      }
+
+      // Check if the packet has the right type
+      if (s7_identify_remote_response_packet->payload->_type !=
+          plc4c_s7_read_write_cotp_packet_type_plc4c_s7_read_write_cotp_packet_data) {
+        return INTERNAL_ERROR;
+      }
+      if (s7_identify_remote_response_packet->payload->payload->_type !=
+          plc4c_s7_read_write_s7_message_type_plc4c_s7_read_write_s7_message_user_data) {
+        return INTERNAL_ERROR;
+      }
+      if (s7_identify_remote_response_packet->payload->payload->payload
+              ->_type !=
+          plc4c_s7_read_write_s7_payload_type_plc4c_s7_read_write_s7_payload_user_data) {
+        return INTERNAL_ERROR;
+      }
+
+      plc4c_list_element* cur_item =
+          s7_identify_remote_response_packet->payload->payload->payload
+              ->s7_payload_user_data_items->tail;
+      while (cur_item != NULL) {
+        plc4c_s7_read_write_s7_payload_user_data_item* item = cur_item->value;
+        if (item->_type ==
+            plc4c_s7_read_write_s7_payload_user_data_item_type_plc4c_s7_read_write_s7_payload_user_data_item_cpu_function_read_szl_response) {
+          plc4c_list_element* szl_item =
+              item->s7_payload_user_data_item_cpu_function_read_szl_response_items
+                  ->tail;
+          while (szl_item != NULL) {
+            plc4c_s7_read_write_szl_data_tree_item* data_tree_item =
+                szl_item->value;
+            if (data_tree_item->item_index == 0x0001) {
+              char* article_number = list_to_string(data_tree_item->mlfb);
+              if (article_number != NULL) {
+                configuration->controller_type =
+                    decode_controller_type(article_number);
+                free(article_number);
+                break;
+              } else {
+                configuration->controller_type =
+                    PLC4C_DRIVER_S7_CONTROLLER_TYPE_ANY;
+              }
+            }
+            szl_item = szl_item->next;
+          }
+        }
+
+        cur_item = cur_item->next;
+      }
+
+      task->state_id = PLC4C_DRIVER_S7_CONNECT_FINISHED;
+      break;
+    }
+    // Clean up some internal data-structures.
+    case PLC4C_DRIVER_S7_CONNECT_FINISHED: {
+      plc4c_connection_set_connected(connection, true);
+      task->completed = true;
+      break;
+    }
+    // If an unexpected state id was received, this is not really something
+    // we can recover from.
+    default: {
+      task->completed = true;
+      return INTERNAL_ERROR;
+    }
+  }
+  return OK;
+}
+
+plc4c_return_code plc4c_driver_s7_connect_function(plc4c_connection* connection,
+                                                   plc4c_system_task** task) {
+  plc4c_system_task* new_task = malloc(sizeof(plc4c_system_task));
+  // There's nothing to do here, so no need for a state-machine.
+  new_task->state_id = PLC4C_DRIVER_S7_CONNECT_INIT;
+  new_task->state_machine_function = &plc4c_driver_s7_connect_machine_function;
+  new_task->completed = false;
+  new_task->context = connection;
+  new_task->connection = connection;
+  *task = new_task;
+  return OK;
+}
diff --git a/sandbox/plc4c/drivers/s7/src/driver_s7_sm_disconnect.c b/sandbox/plc4c/drivers/s7/src/driver_s7_sm_disconnect.c
new file mode 100644
index 0000000..3ee831a
--- /dev/null
+++ b/sandbox/plc4c/drivers/s7/src/driver_s7_sm_disconnect.c
@@ -0,0 +1,81 @@
+/*
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+*/
+
+#include <ctype.h>
+#include <plc4c/plc4c.h>
+#include <plc4c/spi/types_private.h>
+#include <stdlib.h>
+#include <string.h>
+#include "plc4c/driver_s7.h"
+#include "plc4c/driver_s7_encode_decode.h"
+#include "plc4c/driver_s7_packets.h"
+#include "cotp_protocol_class.h"
+#include "tpkt_packet.h"
+
+enum plc4c_driver_s7_disconnect_states {
+  PLC4C_DRIVER_S7_DISCONNECT_INIT,
+  PLC4C_DRIVER_S7_DISCONNECT_WAIT_TASKS_FINISHED,
+  PLC4C_DRIVER_S7_DISCONNECT_FINISHED
+};
+
+plc4c_return_code plc4c_driver_s7_disconnect_machine_function(
+    plc4c_system_task* task) {
+  plc4c_connection* connection = task->context;
+  if (connection == NULL) {
+    return INTERNAL_ERROR;
+  }
+
+  switch (task->state_id) {
+    case PLC4C_DRIVER_S7_DISCONNECT_INIT: {
+      plc4c_connection_set_disconnect(connection, true);
+      task->state_id = PLC4C_DRIVER_S7_DISCONNECT_WAIT_TASKS_FINISHED;
+      break;
+    }
+    case PLC4C_DRIVER_S7_DISCONNECT_WAIT_TASKS_FINISHED: {
+      // The disconnect system-task also counts.
+      if (plc4c_connection_get_running_tasks_count(connection) == 1) {
+        plc4c_connection_set_connected(connection, false);
+        task->completed = true;
+        task->state_id = PLC4C_DRIVER_S7_DISCONNECT_FINISHED;
+      }
+      break;
+    }
+    case PLC4C_DRIVER_S7_DISCONNECT_FINISHED: {
+      // Do nothing
+      break;
+    }
+    default: {
+      return INTERNAL_ERROR;
+    }
+  }
+  return OK;
+}
+
+plc4c_return_code plc4c_driver_s7_disconnect_function(
+    plc4c_connection* connection, plc4c_system_task** task) {
+  plc4c_system_task* new_task = malloc(sizeof(plc4c_system_task));
+  new_task->state_id = PLC4C_DRIVER_S7_DISCONNECT_INIT;
+  new_task->state_machine_function =
+      &plc4c_driver_s7_disconnect_machine_function;
+  new_task->completed = false;
+  new_task->context = connection;
+  new_task->connection = connection;
+  *task = new_task;
+  return OK;
+}
diff --git a/sandbox/plc4c/drivers/s7/src/driver_s7_sm_read.c b/sandbox/plc4c/drivers/s7/src/driver_s7_sm_read.c
new file mode 100644
index 0000000..64e9499
--- /dev/null
+++ b/sandbox/plc4c/drivers/s7/src/driver_s7_sm_read.c
@@ -0,0 +1,207 @@
+/*
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+*/
+
+#include <ctype.h>
+#include <plc4c/spi/types_private.h>
+#include <stdlib.h>
+#include <string.h>
+#include "plc4c/driver_s7.h"
+#include "plc4c/driver_s7_encode_decode.h"
+#include "plc4c/driver_s7_packets.h"
+#include "cotp_protocol_class.h"
+#include "tpkt_packet.h"
+#include "data_item.h"
+
+enum plc4c_driver_s7_read_states {
+  PLC4C_DRIVER_S7_READ_INIT,
+  PLC4C_DRIVER_S7_READ_FINISHED
+};
+
+plc4c_return_code plc4c_driver_s7_read_list_to_byte_array(plc4c_list* list, uint8_t** array) {
+  size_t array_size = plc4c_utils_list_size(list);
+  uint8_t* byte_array = malloc(sizeof(uint8_t) * array_size);
+  if(byte_array == NULL) {
+    return NO_MEMORY;
+  }
+  uint8_t* cur_byte = byte_array;
+  plc4c_list_element* cur_element = list->tail;
+  for(int i = 0; i < array_size; i++) {
+    *cur_byte = (uint8_t) (cur_element->value);
+    cur_byte++;
+    cur_element = cur_element->next;
+  }
+  *array = byte_array;
+  return OK;
+}
+
+plc4c_return_code plc4c_driver_s7_read_machine_function(
+    plc4c_system_task* task) {
+  plc4c_read_request_execution* read_request_execution = task->context;
+  if (read_request_execution == NULL) {
+    return INTERNAL_ERROR;
+  }
+  plc4c_read_request* read_request = read_request_execution->read_request;
+  if (read_request == NULL) {
+    return INTERNAL_ERROR;
+  }
+  plc4c_connection* connection = task->connection;
+  if (connection == NULL) {
+    return INTERNAL_ERROR;
+  }
+
+  switch (task->state_id) {
+    case PLC4C_DRIVER_S7_READ_INIT: {
+      plc4c_s7_read_write_tpkt_packet* s7_read_request_packet;
+      plc4c_return_code return_code =
+          plc4c_driver_s7_create_s7_read_request(
+              read_request, &s7_read_request_packet);
+      if (return_code != OK) {
+        return return_code;
+      }
+
+      // Send the packet to the remote.
+      return_code = plc4c_driver_s7_send_packet(connection, s7_read_request_packet);
+      if (return_code != OK) {
+        return return_code;
+      }
+
+      task->state_id = PLC4C_DRIVER_S7_READ_FINISHED;
+      break;
+    }
+    case PLC4C_DRIVER_S7_READ_FINISHED: {
+      // Read a response packet.
+      plc4c_s7_read_write_tpkt_packet* s7_read_response_packet;
+      plc4c_return_code return_code =
+          plc4c_driver_s7_receive_packet(connection, &s7_read_response_packet);
+      // If we haven't read enough to process a full message, just try again
+      // next time.
+      if (return_code == UNFINISHED) {
+        return OK;
+      } else if (return_code != OK) {
+        return return_code;
+      }
+
+      // Check the response.
+      plc4c_s7_read_write_s7_parameter* parameter = s7_read_response_packet->payload->payload->parameter;
+      if(parameter->_type != plc4c_s7_read_write_s7_parameter_type_plc4c_s7_read_write_s7_parameter_read_var_response) {
+        return INTERNAL_ERROR;
+      }
+      // Check if the number of items matches that of the request
+      // (Otherwise we won't know how to interpret the items)
+      if(parameter->s7_parameter_read_var_response_num_items != plc4c_utils_list_size(read_request->items)) {
+        return INTERNAL_ERROR;
+      }
+
+      plc4c_read_response* read_response = malloc(sizeof(plc4c_read_response));
+      if(read_response == NULL) {
+        return NO_MEMORY;
+      }
+      read_response->read_request = read_request;
+      read_request_execution->read_response = read_response;
+      plc4c_utils_list_create(&(read_response->items));
+
+      // Iterate over the request items and use the types to decode the
+      // response items.
+      plc4c_s7_read_write_s7_payload* payload = s7_read_response_packet->payload->payload->payload;
+      plc4c_list_element* cur_request_item_element = plc4c_utils_list_tail(read_request->items);
+      plc4c_list_element* cur_response_item_element = plc4c_utils_list_tail(payload->s7_payload_read_var_response_items);
+      while((cur_request_item_element != NULL) && (cur_response_item_element != NULL)) {
+        plc4c_item* cur_request_item = cur_request_item_element->value;
+
+        // Get the protocol id for the current item from the corresponding
+        // request item. Also get the number of elements, if it's an array.
+        plc4c_s7_read_write_s7_var_request_parameter_item* s7_address = cur_request_item->address;
+        plc4c_s7_read_write_transport_size transport_size = s7_address->s7_var_request_parameter_item_address_address->s7_address_any_transport_size;
+        uint8_t data_protocol_id = plc4c_s7_read_write_transport_size_get_data_protocol_id(transport_size);
+        uint16_t num_elements = s7_address->s7_var_request_parameter_item_address_address->s7_address_any_number_of_elements;
+        int32_t string_length = 0;
+
+        // Convert the linked list with uint8_t elements into an array of uint8_t.
+        plc4c_s7_read_write_s7_var_payload_data_item* cur_response_item = cur_response_item_element->value;
+        uint8_t* byte_array = NULL;
+        plc4c_return_code result = plc4c_driver_s7_read_list_to_byte_array(cur_response_item->data, &byte_array);
+        if(result != OK) {
+          return result;
+        }
+
+        // Create a new read-buffer for reading data from the uint8_t array.
+        plc4c_spi_read_buffer* read_buffer;
+        result = plc4c_spi_read_buffer_create(byte_array, plc4c_utils_list_size(cur_response_item->data), &read_buffer);
+        if(result != OK) {
+          return result;
+        }
+
+        // Parse the data item.
+        plc4c_data* data_item;
+        plc4c_s7_read_write_data_item_parse(read_buffer, data_protocol_id, string_length, &data_item);
+
+        // Create a new response value-item
+        plc4c_response_value_item* response_value_item = malloc(sizeof(plc4c_response_value_item));
+        if(response_value_item == NULL) {
+          return NO_MEMORY;
+        }
+        response_value_item->item = cur_request_item;
+        response_value_item->response_code = PLC4C_RESPONSE_CODE_OK;
+        response_value_item->value = data_item;
+
+        // Add the value-item to the list.
+        plc4c_utils_list_insert_head_value(read_response->items, response_value_item);
+
+        cur_request_item_element = cur_request_item_element->next;
+        cur_response_item_element = cur_response_item_element->next;
+      }
+
+      // TODO: Return the results to the API ...
+
+      task->completed = true;
+      break;
+    }
+  }
+  return OK;
+}
+
+plc4c_return_code plc4c_driver_s7_read_function(
+    plc4c_read_request_execution* read_request_execution,
+    plc4c_system_task** task) {
+  plc4c_system_task* new_task = malloc(sizeof(plc4c_system_task));
+  if(new_task == NULL) {
+    return NO_MEMORY;
+  }
+  new_task->state_id = PLC4C_DRIVER_S7_READ_INIT;
+  new_task->state_machine_function = &plc4c_driver_s7_read_machine_function;
+  new_task->completed = false;
+  new_task->context = read_request_execution;
+  new_task->connection = read_request_execution->read_request->connection;
+  *task = new_task;
+  return OK;
+}
+
+void plc4c_driver_s7_free_read_response_item(
+    plc4c_list_element* read_item_element) {
+  plc4c_response_value_item* value_item =
+      (plc4c_response_value_item*)read_item_element->value;
+  plc4c_data_destroy(value_item->value);
+  value_item->value = NULL;
+}
+
+void plc4c_driver_s7_free_read_response(plc4c_read_response* response) {
+  // the request will be cleaned up elsewhere
+  plc4c_utils_list_delete_elements(response->items,
+                                   &plc4c_driver_s7_free_read_response_item);
+}
diff --git a/sandbox/plc4c/drivers/s7/src/driver_s7_sm_write.c b/sandbox/plc4c/drivers/s7/src/driver_s7_sm_write.c
new file mode 100644
index 0000000..1f232cf
--- /dev/null
+++ b/sandbox/plc4c/drivers/s7/src/driver_s7_sm_write.c
@@ -0,0 +1,122 @@
+/*
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+*/
+
+#include <ctype.h>
+#include <plc4c/plc4c.h>
+#include <plc4c/spi/types_private.h>
+#include <stdlib.h>
+#include <string.h>
+#include "plc4c/driver_s7.h"
+#include "plc4c/driver_s7_encode_decode.h"
+#include "plc4c/driver_s7_packets.h"
+#include "cotp_protocol_class.h"
+#include "tpkt_packet.h"
+
+enum plc4c_driver_s7_write_states {
+  PLC4C_DRIVER_S7_WRITE_INIT,
+  PLC4C_DRIVER_S7_WRITE_FINISHED
+};
+
+plc4c_return_code plc4c_driver_s7_write_machine_function(
+    plc4c_system_task* task) {
+  plc4c_write_request_execution* write_request_execution = task->context;
+  if (write_request_execution == NULL) {
+    return INTERNAL_ERROR;
+  }
+  plc4c_write_request* write_request = write_request_execution->write_request;
+  if (write_request == NULL) {
+    return INTERNAL_ERROR;
+  }
+  plc4c_connection* connection = task->context;
+  if (connection == NULL) {
+    return INTERNAL_ERROR;
+  }
+
+  switch (task->state_id) {
+    case PLC4C_DRIVER_S7_WRITE_INIT: {
+      plc4c_s7_read_write_tpkt_packet* s7_write_request_packet;
+      plc4c_return_code return_code =
+          plc4c_driver_s7_create_s7_write_request(
+              write_request, &s7_write_request_packet);
+      if (return_code != OK) {
+        return return_code;
+      }
+
+      // Send the packet to the remote.
+      return_code = plc4c_driver_s7_send_packet(connection, s7_write_request_packet);
+      if (return_code != OK) {
+        return return_code;
+      }
+
+      task->state_id = PLC4C_DRIVER_S7_WRITE_FINISHED;
+      break;
+    }
+    case PLC4C_DRIVER_S7_WRITE_FINISHED: {
+      // Read a response packet.
+      plc4c_s7_read_write_tpkt_packet* s7_write_response_packet;
+      plc4c_return_code return_code =
+          plc4c_driver_s7_receive_packet(connection, &s7_write_response_packet);
+      // If we haven't read enough to process a full message, just try again
+      // next time.
+      if (return_code == UNFINISHED) {
+        return OK;
+      } else if (return_code != OK) {
+        return return_code;
+      }
+
+      // TODO: Check the response ...
+      // TODO: Decode the return codes in the response ...
+      // TODO: Return the results to the API ...
+
+      task->completed = true;
+      break;
+    }
+  }
+  return OK;
+}
+
+plc4c_return_code plc4c_driver_s7_write_function(
+    plc4c_write_request_execution* write_request_execution,
+    plc4c_system_task** task) {
+  plc4c_system_task* new_task = malloc(sizeof(plc4c_system_task));
+  new_task->state_id = PLC4C_DRIVER_S7_WRITE_INIT;
+  new_task->state_machine_function = &plc4c_driver_s7_write_machine_function;
+  new_task->completed = false;
+  new_task->context = write_request_execution;
+  new_task->connection = write_request_execution->write_request->connection;
+  *task = new_task;
+  return OK;
+}
+
+void plc4c_driver_s7_free_write_response_item(
+    plc4c_list_element* write_item_element) {
+  plc4c_response_value_item* value_item =
+      (plc4c_response_value_item*)write_item_element->value;
+  // do not delete the plc4c_item
+  // we also, in THIS case don't delete the random value which isn't really
+  // a pointer
+  // free(value_item->value);
+  value_item->value = NULL;
+}
+
+void plc4c_driver_s7_free_write_response(plc4c_write_response* response) {
+  // the request will be cleaned up elsewhere
+  plc4c_utils_list_delete_elements(response->response_items,
+                                   &plc4c_driver_s7_free_write_response_item);
+}
diff --git a/sandbox/plc4c/drivers/s7/test/s7_address_parser_test.c b/sandbox/plc4c/drivers/s7/test/s7_address_parser_test.c
new file mode 100644
index 0000000..283e1d7
--- /dev/null
+++ b/sandbox/plc4c/drivers/s7/test/s7_address_parser_test.c
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#include <memory_area.h>
+#include <s7_var_request_parameter_item.h>
+#include <transport_size.h>
+#include <unity.h>
+
+#include "plc4c/spi/read_buffer.h"
+
+plc4c_return_code plc4c_driver_s7_encode_address(char* address, plc4c_s7_read_write_s7_var_request_parameter_item** item);
+
+void internal_parse_addresses_test(
+    char* address, plc4c_return_code return_code,
+    plc4c_s7_read_write_transport_size transport_size,
+    plc4c_s7_read_write_memory_area memory_area, uint16_t db_number,
+    uint16_t byte_address, uint8_t bit_address, uint16_t number_of_elements) {
+
+  // Call the parser ...
+  plc4c_s7_read_write_s7_var_request_parameter_item* item;
+  plc4c_return_code act_return_code =
+      plc4c_driver_s7_encode_address(address, &item);
+
+  // Check the result ...
+  if(act_return_code != OK) {
+    TEST_ASSERT_EQUAL_INT(return_code, act_return_code);
+  } else {
+    TEST_ASSERT_EQUAL_INT(item->_type, plc4c_s7_read_write_s7_var_request_parameter_item_type_plc4c_s7_read_write_s7_var_request_parameter_item_address);
+    TEST_ASSERT_EQUAL_INT(return_code, act_return_code);
+    TEST_ASSERT_EQUAL_INT(transport_size, item->s7_var_request_parameter_item_address_address->s7_address_any_transport_size);
+    TEST_ASSERT_EQUAL_INT(memory_area, item->s7_var_request_parameter_item_address_address->s7_address_any_area);
+    TEST_ASSERT_EQUAL_INT(db_number, item->s7_var_request_parameter_item_address_address->s7_address_any_db_number);
+    TEST_ASSERT_EQUAL_INT(byte_address, item->s7_var_request_parameter_item_address_address->s7_address_any_byte_address);
+    TEST_ASSERT_EQUAL_INT(bit_address, item->s7_var_request_parameter_item_address_address->s7_address_any_bit_address);
+    TEST_ASSERT_EQUAL_INT(number_of_elements, item->s7_var_request_parameter_item_address_address->s7_address_any_number_of_elements);
+  }
+}
+
+void parse_addresses_test() {
+  internal_parse_addresses_test(
+      "%I23.2:BOOL",OK,
+      plc4c_s7_read_write_transport_size_BOOL,
+      plc4c_s7_read_write_memory_area_INPUTS,
+      0, 23, 2, 1);
+  internal_parse_addresses_test(
+      "%I23.2:BOOL[3]",OK,
+      plc4c_s7_read_write_transport_size_BOOL,
+      plc4c_s7_read_write_memory_area_INPUTS,
+      0, 23, 2, 3);
+  internal_parse_addresses_test(
+      "%Q23.2:BOOL[1]",OK,
+      plc4c_s7_read_write_transport_size_BOOL,
+      plc4c_s7_read_write_memory_area_OUTPUTS,
+      0, 23, 2, 1);
+  internal_parse_addresses_test(
+      "%I23.0:BYTE",OK,
+      plc4c_s7_read_write_transport_size_BYTE,
+      plc4c_s7_read_write_memory_area_INPUTS,
+      0, 23, 0, 1);
+  internal_parse_addresses_test(
+      "%I23:BYTE",OK,
+      plc4c_s7_read_write_transport_size_BYTE,
+      plc4c_s7_read_write_memory_area_INPUTS,
+      0, 23, 0, 1);
+  internal_parse_addresses_test(
+      "%DB23.DBX3.4:BOOL",OK,
+      plc4c_s7_read_write_transport_size_BOOL,
+      plc4c_s7_read_write_memory_area_DATA_BLOCKS,
+      23, 3, 4, 1);
+  internal_parse_addresses_test(
+      "%DB23.DBX3.4:BOOL[4]",OK,
+      plc4c_s7_read_write_transport_size_BOOL,
+      plc4c_s7_read_write_memory_area_DATA_BLOCKS,
+      23, 3, 4, 4);
+  internal_parse_addresses_test(
+      "%DB23.DBW3.0:INT",OK,
+      plc4c_s7_read_write_transport_size_INT,
+      plc4c_s7_read_write_memory_area_DATA_BLOCKS,
+      23, 3, 0, 1);
+  internal_parse_addresses_test(
+      "%DB23.DBW3:INT",OK,
+      plc4c_s7_read_write_transport_size_INT,
+      plc4c_s7_read_write_memory_area_DATA_BLOCKS,
+      23, 3, 0, 1);
+  // TODO: add more tests ...
+  internal_parse_addresses_test(
+      "10-01-00-01-00-2D-84-00-00-08",OK,
+      plc4c_s7_read_write_transport_size_BOOL,
+      plc4c_s7_read_write_memory_area_DATA_BLOCKS,
+      45, 1, 0, 1);
+}
+
+void s7_address_parser_test() {
+  parse_addresses_test();
+}
\ No newline at end of file
diff --git a/sandbox/plc4c/drivers/s7/test/s7_test.c b/sandbox/plc4c/drivers/s7/test/s7_test.c
index db92b4a..4128863 100644
--- a/sandbox/plc4c/drivers/s7/test/s7_test.c
+++ b/sandbox/plc4c/drivers/s7/test/s7_test.c
@@ -21,6 +21,8 @@
 #include "plc4c/spi/read_buffer.h"
 #include "tpkt_packet.h"
 
+void s7_address_parser_test();
+
 void internal_assert_arrays_equal(uint8_t* expected_array,
                                   plc4c_spi_write_buffer* write_buffer,
                                   uint8_t num_bytes) {
@@ -37,7 +39,7 @@
   }
 }
 
-void internal_parse_serialize_test(const uint8_t* payload,
+void internal_parse_serialize_test(uint8_t* payload,
                                    uint8_t payload_size) {
   // Create a new read_buffer instance
   plc4c_spi_read_buffer* read_buffer;
@@ -230,5 +232,8 @@
   RUN_TEST(parse_s7_write_request);
   RUN_TEST(parse_s7_write_response);
 
+  // Run the address parser tests ...
+  RUN_TEST(s7_address_parser_test);
+
   return UNITY_END();
 }
\ No newline at end of file
diff --git a/sandbox/plc4c/drivers/simulated/include/plc4c/driver_simulated.h b/sandbox/plc4c/drivers/simulated/include/plc4c/driver_simulated.h
index cc77d59..32c0df4 100644
--- a/sandbox/plc4c/drivers/simulated/include/plc4c/driver_simulated.h
+++ b/sandbox/plc4c/drivers/simulated/include/plc4c/driver_simulated.h
@@ -16,8 +16,8 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-#ifndef PLC4C_DRIVER_S7_H_
-#define PLC4C_DRIVER_S7_H_
+#ifndef PLC4C_DRIVER_SIMULATED_H_
+#define PLC4C_DRIVER_SIMULATED_H_
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -29,4 +29,4 @@
 #ifdef __cplusplus
 }
 #endif
-#endif  // PLC4C_DRIVER_S7_H_
\ No newline at end of file
+#endif  // PLC4C_DRIVER_SIMULATED_H_
\ No newline at end of file
diff --git a/sandbox/plc4c/drivers/simulated/src/driver_simulated.c b/sandbox/plc4c/drivers/simulated/src/driver_simulated.c
index 48c3ade..8346ae9 100644
--- a/sandbox/plc4c/drivers/simulated/src/driver_simulated.c
+++ b/sandbox/plc4c/drivers/simulated/src/driver_simulated.c
@@ -63,7 +63,7 @@
     return INTERNAL_ERROR;
   }
   if (plc4c_connection_get_connected(connection)) {
-    return INTERNAL_ERROR;
+    return ALREADY_CONNECTED;
   }
   plc4c_connection_set_connected(connection, true);
   task->completed = true;
@@ -133,7 +133,7 @@
          * we can also set a custom printf method
          * right , now just create a new random value
          */
-        value_item->value = plc4c_data_create_uint_data(rand());
+        value_item->value = plc4c_data_create_uint32_t_data(rand());
 
         // Add the value to the response.
         plc4c_utils_list_insert_tail_value(read_response->items, value_item);
@@ -369,7 +369,8 @@
   return OK;
 }
 
-void free_read_response_item(plc4c_list_element *read_item_element) {
+void plc4c_driver_simulated_free_read_response_item(
+    plc4c_list_element *read_item_element) {
   plc4c_response_value_item *value_item =
       (plc4c_response_value_item *)read_item_element->value;
   plc4c_data_destroy(value_item->value);
@@ -378,10 +379,12 @@
 
 void plc4c_driver_simulated_free_read_response(plc4c_read_response *response) {
   // the request will be cleaned up elsewhere
-  plc4c_utils_list_delete_elements(response->items, &free_read_response_item);
+  plc4c_utils_list_delete_elements(response->items,
+                                   &plc4c_driver_simulated_free_read_response_item);
 }
 
-void free_write_response_item(plc4c_list_element *write_item_element) {
+void plc4c_driver_simulated_free_write_response_item(
+    plc4c_list_element *write_item_element) {
   plc4c_response_value_item *value_item =
       (plc4c_response_value_item *)write_item_element->value;
   // do not delete the plc4c_item
@@ -395,7 +398,7 @@
     plc4c_write_response *response) {
   // the request will be cleaned up elsewhere
   plc4c_utils_list_delete_elements(response->response_items,
-                                   &free_write_response_item);
+                                   &plc4c_driver_simulated_free_write_response_item);
 }
 
 plc4c_driver *plc4c_driver_simulated_create() {
diff --git a/sandbox/plc4c/examples/hello-world/CMakeLists.txt b/sandbox/plc4c/examples/hello-world/CMakeLists.txt
index 2190e0b..3e59217 100644
--- a/sandbox/plc4c/examples/hello-world/CMakeLists.txt
+++ b/sandbox/plc4c/examples/hello-world/CMakeLists.txt
@@ -17,14 +17,21 @@
   under the License.
 ]]
 
-include_directories("../../api/include" "../../drivers/simulated/include" "../../transports/dummy/include")
+include_directories("../../api/include"
+        "../../drivers/simulated/include" "../../drivers/s7/include" "../../drivers/modbus/include"
+        "../../transports/dummy/include" "../../transports/tcp/include" "../../transports/serial/include")
 
 add_executable(plc4c-examples-hello-world
         src/hello_world.c
         )
 
 target_link_libraries(plc4c-examples-hello-world
-        plc4c-spi plc4c-driver-simulated
+        plc4c-spi
+        plc4c-driver-simulated
+        plc4c-driver-s7
+        plc4c-driver-modbus
         plc4c-transport-dummy
+        plc4c-transport-tcp
+        plc4c-transport-serial
         m
 )
\ No newline at end of file
diff --git a/sandbox/plc4c/examples/hello-world/src/hello_world.c b/sandbox/plc4c/examples/hello-world/src/hello_world.c
index d233bdd..f809b26 100644
--- a/sandbox/plc4c/examples/hello-world/src/hello_world.c
+++ b/sandbox/plc4c/examples/hello-world/src/hello_world.c
@@ -17,11 +17,16 @@
  * under the License.
  */
 #include <plc4c/driver_simulated.h>
+#include <plc4c/driver_s7.h>
+#include <plc4c/driver_modbus.h>
 #include <plc4c/plc4c.h>
 #include <plc4c/transport_dummy.h>
+#include <plc4c/transport_tcp.h>
+#include <plc4c/transport_serial.h>
 #include <plc4c/utils/list.h>
 #include <stdio.h>
 #include <string.h>
+#include <unistd.h>
 
 #include "../../../spi/include/plc4c/spi/types_private.h"
 
@@ -91,7 +96,21 @@
   plc4c_driver *simulated_driver = plc4c_driver_simulated_create();
   result = plc4c_system_add_driver(system, simulated_driver);
   if (result != OK) {
-    printf("FAILED\n");
+    printf("FAILED adding simulated driver\n");
+    return -1;
+  }
+  printf("Registering driver for the 's7' protocol ... ");
+  plc4c_driver *s7_driver = plc4c_driver_s7_create();
+  result = plc4c_system_add_driver(system, s7_driver);
+  if (result != OK) {
+    printf("FAILED adding s7 driver\n");
+    return -1;
+  }
+  printf("Registering driver for the 'modbus' protocol ... ");
+  plc4c_driver *modbus_driver = plc4c_driver_modbus_create();
+  result = plc4c_system_add_driver(system, modbus_driver);
+  if (result != OK) {
+    printf("FAILED adding modbus driver\n");
     return -1;
   }
   printf("SUCCESS\n");
@@ -100,7 +119,19 @@
   plc4c_transport *dummy_transport = plc4c_transport_dummy_create();
   result = plc4c_system_add_transport(system, dummy_transport);
   if (result != OK) {
-    printf("FAILED\n");
+    printf("FAILED adding dummy transport\n");
+    return -1;
+  }
+  plc4c_transport *tcp_transport = plc4c_transport_tcp_create();
+  result = plc4c_system_add_transport(system, tcp_transport);
+  if (result != OK) {
+    printf("FAILED adding tcp transport\n");
+    return -1;
+  }
+  plc4c_transport *serial_transport = plc4c_transport_serial_create();
+  result = plc4c_system_add_transport(system, serial_transport);
+  if (result != OK) {
+    printf("FAILED adding serial transport\n");
     return -1;
   }
   printf("SUCCESS\n");
@@ -122,8 +153,8 @@
 
   // Establish connections to remote devices
   // you may or may not care about the connection handle
-  printf("Connecting to 'simulated://foo' ... ");
-  result = plc4c_system_connect(system, "simulated://foo", &connection);
+  printf("Connecting to 's7:tcp://192.168.23.30' ... ");
+  result = plc4c_system_connect(system, "s7:tcp://192.168.23.30", &connection);
   if (result != OK) {
     printf("FAILED\n");
     return -1;
@@ -165,9 +196,9 @@
         }
         printf("SUCCESS\n");
 
-        printf("Adding an item for 'RANDOM/foo:INTEGER' ... ");
+        printf("Adding an item for '%I0.0:BOOL' ... ");
         result =
-            plc4c_read_request_add_item(read_request, "RANDOM/foo:INTEGER");
+            plc4c_read_request_add_item(read_request, "hurz", "%I0.0:BOOL");
         if (result != OK) {
           printf("FAILED\n");
           return -1;
@@ -211,7 +242,7 @@
 
         // Iterate over all returned items.
         plc4c_list_element *cur_element =
-            plc4c_utils_list_head(read_response->items);
+            plc4c_utils_list_tail(read_response->items);
         while (cur_element != NULL) {
           plc4c_response_value_item *value_item = cur_element->value;
 
@@ -228,8 +259,18 @@
         plc4c_read_request_execution_destroy(read_request_execution);
         plc4c_read_request_destroy(read_request);
 
+        // TODO: Comment out after implementing the write functionality.
+        // Disconnect.
+        printf("Disconnecting ... ");
+        result = plc4c_connection_disconnect(connection);
+        if (result != OK) {
+          printf("FAILED");
+          return -1;
+        }
+        state = DISCONNECTING;
+
         // Create a new write-request.
-        printf("Preparing a write-request ... ");
+/*        printf("Preparing a write-request ... ");
         char value[] = "bar";
         result =
             plc4c_connection_create_write_request(connection, &write_request);
@@ -258,7 +299,7 @@
           return -1;
         } else {
           state = WRITE_REQUEST_SENT;
-        }
+        }*/
         break;
       }
         // Wait until the write-request execution is finished.
diff --git a/sandbox/plc4c/generated-sources/modbus/include/data_item.h b/sandbox/plc4c/generated-sources/modbus/include/data_item.h
new file mode 100644
index 0000000..4a7353a
--- /dev/null
+++ b/sandbox/plc4c/generated-sources/modbus/include/data_item.h
@@ -0,0 +1,43 @@
+/*
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+*/
+#ifndef PLC4C_MODBUS_READ_WRITE_DATA_ITEM_H_
+#define PLC4C_MODBUS_READ_WRITE_DATA_ITEM_H_
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <plc4c/spi/read_buffer.h>
+#include <plc4c/spi/write_buffer.h>
+#include <plc4c/utils/list.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer* buf, uint8_t dataType, uint8_t numberOfValues, plc4c_data** data_item);
+
+plc4c_return_code plc4c_modbus_read_write_data_item_serialize(plc4c_spi_write_buffer* buf, plc4c_data** data_item);
+
+uint16_t plc4c_modbus_read_write_data_item_length_in_bytes(plc4c_data* data_item);
+
+uint16_t plc4c_modbus_read_write_data_item_length_in_bits(plc4c_data* data_item);
+
+#ifdef __cplusplus
+}
+#endif
+#endif  // PLC4C_MODBUS_READ_WRITE_DATA_ITEM_H_
diff --git a/sandbox/plc4c/generated-sources/modbus/includes/modbus_constants.h b/sandbox/plc4c/generated-sources/modbus/include/modbus_constants.h
similarity index 91%
rename from sandbox/plc4c/generated-sources/modbus/includes/modbus_constants.h
rename to sandbox/plc4c/generated-sources/modbus/include/modbus_constants.h
index 5504e8f..60c1a43 100644
--- a/sandbox/plc4c/generated-sources/modbus/includes/modbus_constants.h
+++ b/sandbox/plc4c/generated-sources/modbus/include/modbus_constants.h
@@ -42,9 +42,9 @@
 // Create an empty NULL-struct
 plc4c_modbus_read_write_modbus_constants plc4c_modbus_read_write_modbus_constants_null();
 
-plc4c_return_code plc4c_modbus_read_write_modbus_constants_parse(plc4c_spi_read_buffer* buf, plc4c_modbus_read_write_modbus_constants** message);
+plc4c_return_code plc4c_modbus_read_write_modbus_constants_parse(plc4c_spi_read_buffer* io, plc4c_modbus_read_write_modbus_constants** message);
 
-plc4c_return_code plc4c_modbus_read_write_modbus_constants_serialize(plc4c_spi_write_buffer* buf, plc4c_modbus_read_write_modbus_constants* message);
+plc4c_return_code plc4c_modbus_read_write_modbus_constants_serialize(plc4c_spi_write_buffer* io, plc4c_modbus_read_write_modbus_constants* message);
 
 uint16_t plc4c_modbus_read_write_modbus_constants_length_in_bytes(plc4c_modbus_read_write_modbus_constants* message);
 
diff --git a/sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu.h b/sandbox/plc4c/generated-sources/modbus/include/modbus_pdu.h
similarity index 98%
rename from sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu.h
rename to sandbox/plc4c/generated-sources/modbus/include/modbus_pdu.h
index 2011d29..08adfa5 100644
--- a/sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu.h
+++ b/sandbox/plc4c/generated-sources/modbus/include/modbus_pdu.h
@@ -227,9 +227,9 @@
 // Create an empty NULL-struct
 plc4c_modbus_read_write_modbus_pdu plc4c_modbus_read_write_modbus_pdu_null();
 
-plc4c_return_code plc4c_modbus_read_write_modbus_pdu_parse(plc4c_spi_read_buffer* buf, bool response, plc4c_modbus_read_write_modbus_pdu** message);
+plc4c_return_code plc4c_modbus_read_write_modbus_pdu_parse(plc4c_spi_read_buffer* io, bool response, plc4c_modbus_read_write_modbus_pdu** message);
 
-plc4c_return_code plc4c_modbus_read_write_modbus_pdu_serialize(plc4c_spi_write_buffer* buf, plc4c_modbus_read_write_modbus_pdu* message);
+plc4c_return_code plc4c_modbus_read_write_modbus_pdu_serialize(plc4c_spi_write_buffer* io, plc4c_modbus_read_write_modbus_pdu* message);
 
 uint16_t plc4c_modbus_read_write_modbus_pdu_length_in_bytes(plc4c_modbus_read_write_modbus_pdu* message);
 
diff --git a/sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu_read_file_record_request_item.h b/sandbox/plc4c/generated-sources/modbus/include/modbus_pdu_read_file_record_request_item.h
similarity index 89%
rename from sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu_read_file_record_request_item.h
rename to sandbox/plc4c/generated-sources/modbus/include/modbus_pdu_read_file_record_request_item.h
index 8e2d438..3b3ad03 100644
--- a/sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu_read_file_record_request_item.h
+++ b/sandbox/plc4c/generated-sources/modbus/include/modbus_pdu_read_file_record_request_item.h
@@ -42,9 +42,9 @@
 // Create an empty NULL-struct
 plc4c_modbus_read_write_modbus_pdu_read_file_record_request_item plc4c_modbus_read_write_modbus_pdu_read_file_record_request_item_null();
 
-plc4c_return_code plc4c_modbus_read_write_modbus_pdu_read_file_record_request_item_parse(plc4c_spi_read_buffer* buf, plc4c_modbus_read_write_modbus_pdu_read_file_record_request_item** message);
+plc4c_return_code plc4c_modbus_read_write_modbus_pdu_read_file_record_request_item_parse(plc4c_spi_read_buffer* io, plc4c_modbus_read_write_modbus_pdu_read_file_record_request_item** message);
 
-plc4c_return_code plc4c_modbus_read_write_modbus_pdu_read_file_record_request_item_serialize(plc4c_spi_write_buffer* buf, plc4c_modbus_read_write_modbus_pdu_read_file_record_request_item* message);
+plc4c_return_code plc4c_modbus_read_write_modbus_pdu_read_file_record_request_item_serialize(plc4c_spi_write_buffer* io, plc4c_modbus_read_write_modbus_pdu_read_file_record_request_item* message);
 
 uint16_t plc4c_modbus_read_write_modbus_pdu_read_file_record_request_item_length_in_bytes(plc4c_modbus_read_write_modbus_pdu_read_file_record_request_item* message);
 
diff --git a/sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu_read_file_record_response_item.h b/sandbox/plc4c/generated-sources/modbus/include/modbus_pdu_read_file_record_response_item.h
similarity index 88%
rename from sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu_read_file_record_response_item.h
rename to sandbox/plc4c/generated-sources/modbus/include/modbus_pdu_read_file_record_response_item.h
index 4071a22..5fc5233 100644
--- a/sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu_read_file_record_response_item.h
+++ b/sandbox/plc4c/generated-sources/modbus/include/modbus_pdu_read_file_record_response_item.h
@@ -40,9 +40,9 @@
 // Create an empty NULL-struct
 plc4c_modbus_read_write_modbus_pdu_read_file_record_response_item plc4c_modbus_read_write_modbus_pdu_read_file_record_response_item_null();
 
-plc4c_return_code plc4c_modbus_read_write_modbus_pdu_read_file_record_response_item_parse(plc4c_spi_read_buffer* buf, plc4c_modbus_read_write_modbus_pdu_read_file_record_response_item** message);
+plc4c_return_code plc4c_modbus_read_write_modbus_pdu_read_file_record_response_item_parse(plc4c_spi_read_buffer* io, plc4c_modbus_read_write_modbus_pdu_read_file_record_response_item** message);
 
-plc4c_return_code plc4c_modbus_read_write_modbus_pdu_read_file_record_response_item_serialize(plc4c_spi_write_buffer* buf, plc4c_modbus_read_write_modbus_pdu_read_file_record_response_item* message);
+plc4c_return_code plc4c_modbus_read_write_modbus_pdu_read_file_record_response_item_serialize(plc4c_spi_write_buffer* io, plc4c_modbus_read_write_modbus_pdu_read_file_record_response_item* message);
 
 uint16_t plc4c_modbus_read_write_modbus_pdu_read_file_record_response_item_length_in_bytes(plc4c_modbus_read_write_modbus_pdu_read_file_record_response_item* message);
 
diff --git a/sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu_write_file_record_request_item.h b/sandbox/plc4c/generated-sources/modbus/include/modbus_pdu_write_file_record_request_item.h
similarity index 89%
rename from sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu_write_file_record_request_item.h
rename to sandbox/plc4c/generated-sources/modbus/include/modbus_pdu_write_file_record_request_item.h
index a781f77..b32f2b3 100644
--- a/sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu_write_file_record_request_item.h
+++ b/sandbox/plc4c/generated-sources/modbus/include/modbus_pdu_write_file_record_request_item.h
@@ -42,9 +42,9 @@
 // Create an empty NULL-struct
 plc4c_modbus_read_write_modbus_pdu_write_file_record_request_item plc4c_modbus_read_write_modbus_pdu_write_file_record_request_item_null();
 
-plc4c_return_code plc4c_modbus_read_write_modbus_pdu_write_file_record_request_item_parse(plc4c_spi_read_buffer* buf, plc4c_modbus_read_write_modbus_pdu_write_file_record_request_item** message);
+plc4c_return_code plc4c_modbus_read_write_modbus_pdu_write_file_record_request_item_parse(plc4c_spi_read_buffer* io, plc4c_modbus_read_write_modbus_pdu_write_file_record_request_item** message);
 
-plc4c_return_code plc4c_modbus_read_write_modbus_pdu_write_file_record_request_item_serialize(plc4c_spi_write_buffer* buf, plc4c_modbus_read_write_modbus_pdu_write_file_record_request_item* message);
+plc4c_return_code plc4c_modbus_read_write_modbus_pdu_write_file_record_request_item_serialize(plc4c_spi_write_buffer* io, plc4c_modbus_read_write_modbus_pdu_write_file_record_request_item* message);
 
 uint16_t plc4c_modbus_read_write_modbus_pdu_write_file_record_request_item_length_in_bytes(plc4c_modbus_read_write_modbus_pdu_write_file_record_request_item* message);
 
diff --git a/sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu_write_file_record_response_item.h b/sandbox/plc4c/generated-sources/modbus/include/modbus_pdu_write_file_record_response_item.h
similarity index 89%
rename from sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu_write_file_record_response_item.h
rename to sandbox/plc4c/generated-sources/modbus/include/modbus_pdu_write_file_record_response_item.h
index acb7ad6..81d20e6 100644
--- a/sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu_write_file_record_response_item.h
+++ b/sandbox/plc4c/generated-sources/modbus/include/modbus_pdu_write_file_record_response_item.h
@@ -42,9 +42,9 @@
 // Create an empty NULL-struct
 plc4c_modbus_read_write_modbus_pdu_write_file_record_response_item plc4c_modbus_read_write_modbus_pdu_write_file_record_response_item_null();
 
-plc4c_return_code plc4c_modbus_read_write_modbus_pdu_write_file_record_response_item_parse(plc4c_spi_read_buffer* buf, plc4c_modbus_read_write_modbus_pdu_write_file_record_response_item** message);
+plc4c_return_code plc4c_modbus_read_write_modbus_pdu_write_file_record_response_item_parse(plc4c_spi_read_buffer* io, plc4c_modbus_read_write_modbus_pdu_write_file_record_response_item** message);
 
-plc4c_return_code plc4c_modbus_read_write_modbus_pdu_write_file_record_response_item_serialize(plc4c_spi_write_buffer* buf, plc4c_modbus_read_write_modbus_pdu_write_file_record_response_item* message);
+plc4c_return_code plc4c_modbus_read_write_modbus_pdu_write_file_record_response_item_serialize(plc4c_spi_write_buffer* io, plc4c_modbus_read_write_modbus_pdu_write_file_record_response_item* message);
 
 uint16_t plc4c_modbus_read_write_modbus_pdu_write_file_record_response_item_length_in_bytes(plc4c_modbus_read_write_modbus_pdu_write_file_record_response_item* message);
 
diff --git a/sandbox/plc4c/generated-sources/modbus/includes/modbus_serial_adu.h b/sandbox/plc4c/generated-sources/modbus/include/modbus_serial_adu.h
similarity index 91%
rename from sandbox/plc4c/generated-sources/modbus/includes/modbus_serial_adu.h
rename to sandbox/plc4c/generated-sources/modbus/include/modbus_serial_adu.h
index f0360db..9a280c0 100644
--- a/sandbox/plc4c/generated-sources/modbus/includes/modbus_serial_adu.h
+++ b/sandbox/plc4c/generated-sources/modbus/include/modbus_serial_adu.h
@@ -43,9 +43,9 @@
 // Create an empty NULL-struct
 plc4c_modbus_read_write_modbus_serial_adu plc4c_modbus_read_write_modbus_serial_adu_null();
 
-plc4c_return_code plc4c_modbus_read_write_modbus_serial_adu_parse(plc4c_spi_read_buffer* buf, bool response, plc4c_modbus_read_write_modbus_serial_adu** message);
+plc4c_return_code plc4c_modbus_read_write_modbus_serial_adu_parse(plc4c_spi_read_buffer* io, bool response, plc4c_modbus_read_write_modbus_serial_adu** message);
 
-plc4c_return_code plc4c_modbus_read_write_modbus_serial_adu_serialize(plc4c_spi_write_buffer* buf, plc4c_modbus_read_write_modbus_serial_adu* message);
+plc4c_return_code plc4c_modbus_read_write_modbus_serial_adu_serialize(plc4c_spi_write_buffer* io, plc4c_modbus_read_write_modbus_serial_adu* message);
 
 uint16_t plc4c_modbus_read_write_modbus_serial_adu_length_in_bytes(plc4c_modbus_read_write_modbus_serial_adu* message);
 
diff --git a/sandbox/plc4c/generated-sources/modbus/includes/modbus_tcp_adu.h b/sandbox/plc4c/generated-sources/modbus/include/modbus_tcp_adu.h
similarity index 91%
rename from sandbox/plc4c/generated-sources/modbus/includes/modbus_tcp_adu.h
rename to sandbox/plc4c/generated-sources/modbus/include/modbus_tcp_adu.h
index dfa1783..ca9ef93 100644
--- a/sandbox/plc4c/generated-sources/modbus/includes/modbus_tcp_adu.h
+++ b/sandbox/plc4c/generated-sources/modbus/include/modbus_tcp_adu.h
@@ -46,9 +46,9 @@
 // Create an empty NULL-struct
 plc4c_modbus_read_write_modbus_tcp_adu plc4c_modbus_read_write_modbus_tcp_adu_null();
 
-plc4c_return_code plc4c_modbus_read_write_modbus_tcp_adu_parse(plc4c_spi_read_buffer* buf, bool response, plc4c_modbus_read_write_modbus_tcp_adu** message);
+plc4c_return_code plc4c_modbus_read_write_modbus_tcp_adu_parse(plc4c_spi_read_buffer* io, bool response, plc4c_modbus_read_write_modbus_tcp_adu** message);
 
-plc4c_return_code plc4c_modbus_read_write_modbus_tcp_adu_serialize(plc4c_spi_write_buffer* buf, plc4c_modbus_read_write_modbus_tcp_adu* message);
+plc4c_return_code plc4c_modbus_read_write_modbus_tcp_adu_serialize(plc4c_spi_write_buffer* io, plc4c_modbus_read_write_modbus_tcp_adu* message);
 
 uint16_t plc4c_modbus_read_write_modbus_tcp_adu_length_in_bytes(plc4c_modbus_read_write_modbus_tcp_adu* message);
 
diff --git a/sandbox/plc4c/generated-sources/modbus/src/data_item.c b/sandbox/plc4c/generated-sources/modbus/src/data_item.c
new file mode 100644
index 0000000..a825905
--- /dev/null
+++ b/sandbox/plc4c/generated-sources/modbus/src/data_item.c
@@ -0,0 +1,96 @@
+/*
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+*/
+
+#include <stdio.h>
+#include <time.h>
+#include <plc4c/data.h>
+#include <plc4c/spi/evaluation_helper.h>
+#include <plc4c/driver_modbus.h>
+#include "data_item.h"
+
+// Parse function.
+plc4c_return_code plc4c_modbus_read_write_data_item_parse(plc4c_spi_read_buffer* io, uint8_t dataType, uint8_t numberOfValues, plc4c_data** data_item) {
+    uint16_t startPos = plc4c_spi_read_get_pos(io);
+    uint16_t curPos;
+    plc4c_return_code _res = OK;
+
+        if((dataType == 1) && (numberOfValues == 1)) { /* Boolean */
+
+                // Reserved Field (Compartmentalized so the "reserved" variable can't leak)
+                {
+                    unsigned int _reserved = 0;
+                    _res = plc4c_spi_read_unsigned_byte(io, 7, (uint8_t*) &_reserved);
+                    if(_res != OK) {
+                        return _res;
+                    }
+                    if(_reserved != 0x00) {
+                      printf("Expected constant value '%d' but got '%d' for reserved field.", 0x00, _reserved);
+                    }
+                }
+
+                // Simple Field (value)
+                bool value = false;
+                _res = plc4c_spi_read_bit(io, (bool*) &value);
+                if(_res != OK) {
+                    return _res;
+                }
+
+                *data_item = plc4c_data_create_bool_data(value);
+
+        } else 
+        if(dataType == 1) { /* List */
+
+                    // Array field (value)
+        } else 
+        if((dataType == 2) && (numberOfValues == 1)) { /* Integer */
+
+                // Simple Field (value)
+                int16_t value = 0;
+                _res = plc4c_spi_read_signed_short(io, 16, (int16_t*) &value);
+                if(_res != OK) {
+                    return _res;
+                }
+
+                *data_item = plc4c_data_create_int16_t_data(value);
+
+        } else 
+        if(dataType == 2) { /* List */
+
+                    // Array field (value)
+        }
+
+  return OK;
+}
+
+plc4c_return_code plc4c_modbus_read_write_data_item_serialize(plc4c_spi_write_buffer* io, plc4c_data** data_item) {
+  plc4c_return_code _res = OK;
+
+  return OK;
+}
+
+uint16_t plc4c_modbus_read_write_data_item_length_in_bytes(plc4c_data* data_item) {
+  return plc4c_modbus_read_write_data_item_length_in_bits(data_item) / 8;
+}
+
+uint16_t plc4c_modbus_read_write_data_item_length_in_bits(plc4c_data* data_item) {
+  uint16_t lengthInBits = 0;
+
+  return lengthInBits;
+}
+
diff --git a/sandbox/plc4c/generated-sources/modbus/src/modbus_constants.c b/sandbox/plc4c/generated-sources/modbus/src/modbus_constants.c
index d4abb8b..826e276 100644
--- a/sandbox/plc4c/generated-sources/modbus/src/modbus_constants.c
+++ b/sandbox/plc4c/generated-sources/modbus/src/modbus_constants.c
@@ -29,8 +29,8 @@
 }
 
 // Parse function.
-plc4c_return_code plc4c_modbus_read_write_modbus_constants_parse(plc4c_spi_read_buffer* buf, plc4c_modbus_read_write_modbus_constants** _message) {
-  uint16_t startPos = plc4c_spi_read_get_pos(buf);
+plc4c_return_code plc4c_modbus_read_write_modbus_constants_parse(plc4c_spi_read_buffer* io, plc4c_modbus_read_write_modbus_constants** _message) {
+  uint16_t startPos = plc4c_spi_read_get_pos(io);
   uint16_t curPos;
   plc4c_return_code _res = OK;
 
@@ -42,7 +42,7 @@
 
   // Const Field (modbusTcpDefaultPort)
   uint16_t modbusTcpDefaultPort = 0;
-  _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &modbusTcpDefaultPort);
+  _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &modbusTcpDefaultPort);
   if(_res != OK) {
     return _res;
   }
@@ -54,11 +54,11 @@
   return OK;
 }
 
-plc4c_return_code plc4c_modbus_read_write_modbus_constants_serialize(plc4c_spi_write_buffer* buf, plc4c_modbus_read_write_modbus_constants* _message) {
+plc4c_return_code plc4c_modbus_read_write_modbus_constants_serialize(plc4c_spi_write_buffer* io, plc4c_modbus_read_write_modbus_constants* _message) {
   plc4c_return_code _res = OK;
 
   // Const Field (modbusTcpDefaultPort)
-  plc4c_spi_write_unsigned_short(buf, 16, PLC4C_MODBUS_READ_WRITE_MODBUS_CONSTANTS_MODBUS_TCP_DEFAULT_PORT());
+  plc4c_spi_write_unsigned_short(io, 16, PLC4C_MODBUS_READ_WRITE_MODBUS_CONSTANTS_MODBUS_TCP_DEFAULT_PORT());
 
   return OK;
 }
diff --git a/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu.c b/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu.c
index d1a22eb..b29b90d 100644
--- a/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu.c
+++ b/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu.c
@@ -113,8 +113,8 @@
 
 
 // Parse function.
-plc4c_return_code plc4c_modbus_read_write_modbus_pdu_parse(plc4c_spi_read_buffer* buf, bool response, plc4c_modbus_read_write_modbus_pdu** _message) {
-  uint16_t startPos = plc4c_spi_read_get_pos(buf);
+plc4c_return_code plc4c_modbus_read_write_modbus_pdu_parse(plc4c_spi_read_buffer* io, bool response, plc4c_modbus_read_write_modbus_pdu** _message) {
+  uint16_t startPos = plc4c_spi_read_get_pos(io);
   uint16_t curPos;
   plc4c_return_code _res = OK;
 
@@ -126,14 +126,14 @@
 
   // Discriminator Field (error) (Used as input to a switch field)
   bool error = false;
-  _res = plc4c_spi_read_bit(buf, (bool*) &error);
+  _res = plc4c_spi_read_bit(io, (bool*) &error);
   if(_res != OK) {
     return _res;
   }
 
   // Discriminator Field (function) (Used as input to a switch field)
   unsigned int function = 0;
-  _res = plc4c_spi_read_unsigned_byte(buf, 7, (uint8_t*) &function);
+  _res = plc4c_spi_read_unsigned_byte(io, 7, (uint8_t*) &function);
   if(_res != OK) {
     return _res;
   }
@@ -144,7 +144,7 @@
                     
     // Simple Field (exceptionCode)
     uint8_t exceptionCode = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &exceptionCode);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &exceptionCode);
     if(_res != OK) {
       return _res;
     }
@@ -156,7 +156,7 @@
                     
     // Simple Field (startingAddress)
     uint16_t startingAddress = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &startingAddress);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &startingAddress);
     if(_res != OK) {
       return _res;
     }
@@ -166,7 +166,7 @@
                     
     // Simple Field (quantity)
     uint16_t quantity = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &quantity);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &quantity);
     if(_res != OK) {
       return _res;
     }
@@ -178,7 +178,7 @@
                     
     // Implicit Field (byteCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
     uint8_t byteCount = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &byteCount);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &byteCount);
     if(_res != OK) {
       return _res;
     }
@@ -196,9 +196,8 @@
       uint8_t itemCount = byteCount;
       for(int curItem = 0; curItem < itemCount; curItem++) {
         
-                  
         int8_t* _value = malloc(sizeof(int8_t));
-        _res = plc4c_spi_read_signed_byte(buf, 8, (int8_t*) _value);
+        _res = plc4c_spi_read_signed_byte(io, 8, (int8_t*) _value);
         if(_res != OK) {
           return _res;
         }
@@ -213,7 +212,7 @@
                     
     // Simple Field (startingAddress)
     uint16_t startingAddress = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &startingAddress);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &startingAddress);
     if(_res != OK) {
       return _res;
     }
@@ -223,7 +222,7 @@
                     
     // Simple Field (quantity)
     uint16_t quantity = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &quantity);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &quantity);
     if(_res != OK) {
       return _res;
     }
@@ -235,7 +234,7 @@
                     
     // Implicit Field (byteCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
     uint8_t byteCount = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &byteCount);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &byteCount);
     if(_res != OK) {
       return _res;
     }
@@ -253,9 +252,8 @@
       uint8_t itemCount = byteCount;
       for(int curItem = 0; curItem < itemCount; curItem++) {
         
-                  
         int8_t* _value = malloc(sizeof(int8_t));
-        _res = plc4c_spi_read_signed_byte(buf, 8, (int8_t*) _value);
+        _res = plc4c_spi_read_signed_byte(io, 8, (int8_t*) _value);
         if(_res != OK) {
           return _res;
         }
@@ -270,7 +268,7 @@
                     
     // Simple Field (address)
     uint16_t address = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &address);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &address);
     if(_res != OK) {
       return _res;
     }
@@ -280,7 +278,7 @@
                     
     // Simple Field (value)
     uint16_t value = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &value);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &value);
     if(_res != OK) {
       return _res;
     }
@@ -292,7 +290,7 @@
                     
     // Simple Field (address)
     uint16_t address = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &address);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &address);
     if(_res != OK) {
       return _res;
     }
@@ -302,7 +300,7 @@
                     
     // Simple Field (value)
     uint16_t value = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &value);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &value);
     if(_res != OK) {
       return _res;
     }
@@ -314,7 +312,7 @@
                     
     // Simple Field (startingAddress)
     uint16_t startingAddress = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &startingAddress);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &startingAddress);
     if(_res != OK) {
       return _res;
     }
@@ -324,7 +322,7 @@
                     
     // Simple Field (quantity)
     uint16_t quantity = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &quantity);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &quantity);
     if(_res != OK) {
       return _res;
     }
@@ -334,7 +332,7 @@
                     
     // Implicit Field (byteCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
     uint8_t byteCount = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &byteCount);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &byteCount);
     if(_res != OK) {
       return _res;
     }
@@ -352,9 +350,8 @@
       uint8_t itemCount = byteCount;
       for(int curItem = 0; curItem < itemCount; curItem++) {
         
-                  
         int8_t* _value = malloc(sizeof(int8_t));
-        _res = plc4c_spi_read_signed_byte(buf, 8, (int8_t*) _value);
+        _res = plc4c_spi_read_signed_byte(io, 8, (int8_t*) _value);
         if(_res != OK) {
           return _res;
         }
@@ -369,7 +366,7 @@
                     
     // Simple Field (startingAddress)
     uint16_t startingAddress = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &startingAddress);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &startingAddress);
     if(_res != OK) {
       return _res;
     }
@@ -379,7 +376,7 @@
                     
     // Simple Field (quantity)
     uint16_t quantity = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &quantity);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &quantity);
     if(_res != OK) {
       return _res;
     }
@@ -391,7 +388,7 @@
                     
     // Simple Field (startingAddress)
     uint16_t startingAddress = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &startingAddress);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &startingAddress);
     if(_res != OK) {
       return _res;
     }
@@ -401,7 +398,7 @@
                     
     // Simple Field (quantity)
     uint16_t quantity = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &quantity);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &quantity);
     if(_res != OK) {
       return _res;
     }
@@ -413,7 +410,7 @@
                     
     // Implicit Field (byteCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
     uint8_t byteCount = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &byteCount);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &byteCount);
     if(_res != OK) {
       return _res;
     }
@@ -431,9 +428,8 @@
       uint8_t itemCount = byteCount;
       for(int curItem = 0; curItem < itemCount; curItem++) {
         
-                  
         int8_t* _value = malloc(sizeof(int8_t));
-        _res = plc4c_spi_read_signed_byte(buf, 8, (int8_t*) _value);
+        _res = plc4c_spi_read_signed_byte(io, 8, (int8_t*) _value);
         if(_res != OK) {
           return _res;
         }
@@ -448,7 +444,7 @@
                     
     // Simple Field (startingAddress)
     uint16_t startingAddress = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &startingAddress);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &startingAddress);
     if(_res != OK) {
       return _res;
     }
@@ -458,7 +454,7 @@
                     
     // Simple Field (quantity)
     uint16_t quantity = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &quantity);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &quantity);
     if(_res != OK) {
       return _res;
     }
@@ -470,7 +466,7 @@
                     
     // Implicit Field (byteCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
     uint8_t byteCount = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &byteCount);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &byteCount);
     if(_res != OK) {
       return _res;
     }
@@ -488,9 +484,8 @@
       uint8_t itemCount = byteCount;
       for(int curItem = 0; curItem < itemCount; curItem++) {
         
-                  
         int8_t* _value = malloc(sizeof(int8_t));
-        _res = plc4c_spi_read_signed_byte(buf, 8, (int8_t*) _value);
+        _res = plc4c_spi_read_signed_byte(io, 8, (int8_t*) _value);
         if(_res != OK) {
           return _res;
         }
@@ -505,7 +500,7 @@
                     
     // Simple Field (address)
     uint16_t address = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &address);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &address);
     if(_res != OK) {
       return _res;
     }
@@ -515,7 +510,7 @@
                     
     // Simple Field (value)
     uint16_t value = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &value);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &value);
     if(_res != OK) {
       return _res;
     }
@@ -527,7 +522,7 @@
                     
     // Simple Field (address)
     uint16_t address = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &address);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &address);
     if(_res != OK) {
       return _res;
     }
@@ -537,7 +532,7 @@
                     
     // Simple Field (value)
     uint16_t value = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &value);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &value);
     if(_res != OK) {
       return _res;
     }
@@ -549,7 +544,7 @@
                     
     // Simple Field (startingAddress)
     uint16_t startingAddress = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &startingAddress);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &startingAddress);
     if(_res != OK) {
       return _res;
     }
@@ -559,7 +554,7 @@
                     
     // Simple Field (quantity)
     uint16_t quantity = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &quantity);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &quantity);
     if(_res != OK) {
       return _res;
     }
@@ -569,7 +564,7 @@
                     
     // Implicit Field (byteCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
     uint8_t byteCount = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &byteCount);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &byteCount);
     if(_res != OK) {
       return _res;
     }
@@ -587,9 +582,8 @@
       uint8_t itemCount = byteCount;
       for(int curItem = 0; curItem < itemCount; curItem++) {
         
-                  
         int8_t* _value = malloc(sizeof(int8_t));
-        _res = plc4c_spi_read_signed_byte(buf, 8, (int8_t*) _value);
+        _res = plc4c_spi_read_signed_byte(io, 8, (int8_t*) _value);
         if(_res != OK) {
           return _res;
         }
@@ -604,7 +598,7 @@
                     
     // Simple Field (startingAddress)
     uint16_t startingAddress = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &startingAddress);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &startingAddress);
     if(_res != OK) {
       return _res;
     }
@@ -614,7 +608,7 @@
                     
     // Simple Field (quantity)
     uint16_t quantity = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &quantity);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &quantity);
     if(_res != OK) {
       return _res;
     }
@@ -626,7 +620,7 @@
                     
     // Simple Field (readStartingAddress)
     uint16_t readStartingAddress = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &readStartingAddress);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &readStartingAddress);
     if(_res != OK) {
       return _res;
     }
@@ -636,7 +630,7 @@
                     
     // Simple Field (readQuantity)
     uint16_t readQuantity = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &readQuantity);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &readQuantity);
     if(_res != OK) {
       return _res;
     }
@@ -646,7 +640,7 @@
                     
     // Simple Field (writeStartingAddress)
     uint16_t writeStartingAddress = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &writeStartingAddress);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &writeStartingAddress);
     if(_res != OK) {
       return _res;
     }
@@ -656,7 +650,7 @@
                     
     // Simple Field (writeQuantity)
     uint16_t writeQuantity = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &writeQuantity);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &writeQuantity);
     if(_res != OK) {
       return _res;
     }
@@ -666,7 +660,7 @@
                     
     // Implicit Field (byteCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
     uint8_t byteCount = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &byteCount);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &byteCount);
     if(_res != OK) {
       return _res;
     }
@@ -684,9 +678,8 @@
       uint8_t itemCount = byteCount;
       for(int curItem = 0; curItem < itemCount; curItem++) {
         
-                  
         int8_t* _value = malloc(sizeof(int8_t));
-        _res = plc4c_spi_read_signed_byte(buf, 8, (int8_t*) _value);
+        _res = plc4c_spi_read_signed_byte(io, 8, (int8_t*) _value);
         if(_res != OK) {
           return _res;
         }
@@ -701,7 +694,7 @@
                     
     // Implicit Field (byteCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
     uint8_t byteCount = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &byteCount);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &byteCount);
     if(_res != OK) {
       return _res;
     }
@@ -719,9 +712,8 @@
       uint8_t itemCount = byteCount;
       for(int curItem = 0; curItem < itemCount; curItem++) {
         
-                  
         int8_t* _value = malloc(sizeof(int8_t));
-        _res = plc4c_spi_read_signed_byte(buf, 8, (int8_t*) _value);
+        _res = plc4c_spi_read_signed_byte(io, 8, (int8_t*) _value);
         if(_res != OK) {
           return _res;
         }
@@ -736,7 +728,7 @@
                     
     // Simple Field (referenceAddress)
     uint16_t referenceAddress = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &referenceAddress);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &referenceAddress);
     if(_res != OK) {
       return _res;
     }
@@ -746,7 +738,7 @@
                     
     // Simple Field (andMask)
     uint16_t andMask = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &andMask);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &andMask);
     if(_res != OK) {
       return _res;
     }
@@ -756,7 +748,7 @@
                     
     // Simple Field (orMask)
     uint16_t orMask = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &orMask);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &orMask);
     if(_res != OK) {
       return _res;
     }
@@ -768,7 +760,7 @@
                     
     // Simple Field (referenceAddress)
     uint16_t referenceAddress = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &referenceAddress);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &referenceAddress);
     if(_res != OK) {
       return _res;
     }
@@ -778,7 +770,7 @@
                     
     // Simple Field (andMask)
     uint16_t andMask = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &andMask);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &andMask);
     if(_res != OK) {
       return _res;
     }
@@ -788,7 +780,7 @@
                     
     // Simple Field (orMask)
     uint16_t orMask = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &orMask);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &orMask);
     if(_res != OK) {
       return _res;
     }
@@ -800,7 +792,7 @@
                     
     // Simple Field (fifoPointerAddress)
     uint16_t fifoPointerAddress = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &fifoPointerAddress);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &fifoPointerAddress);
     if(_res != OK) {
       return _res;
     }
@@ -812,7 +804,7 @@
                     
     // Implicit Field (byteCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
     uint16_t byteCount = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &byteCount);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &byteCount);
     if(_res != OK) {
       return _res;
     }
@@ -821,7 +813,7 @@
                     
     // Implicit Field (fifoCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
     uint16_t fifoCount = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &fifoCount);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &fifoCount);
     if(_res != OK) {
       return _res;
     }
@@ -839,9 +831,8 @@
       uint8_t itemCount = fifoCount;
       for(int curItem = 0; curItem < itemCount; curItem++) {
         
-                  
         uint16_t* _value = malloc(sizeof(uint16_t));
-        _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) _value);
+        _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) _value);
         if(_res != OK) {
           return _res;
         }
@@ -856,7 +847,7 @@
                     
     // Implicit Field (byteCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
     uint8_t byteCount = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &byteCount);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &byteCount);
     if(_res != OK) {
       return _res;
     }
@@ -872,10 +863,10 @@
     {
       // Length array
       uint8_t _itemsLength = byteCount;
-      uint8_t itemsEndPos = plc4c_spi_read_get_pos(buf) + _itemsLength;
-      while(plc4c_spi_read_get_pos(buf) < itemsEndPos) {
-        plc4c_list* _value = NULL;
-        _res = plc4c_modbus_read_write_modbus_pdu_read_file_record_request_item_parse(buf, (void*) &_value);
+      uint8_t itemsEndPos = plc4c_spi_read_get_pos(io) + _itemsLength;
+      while(plc4c_spi_read_get_pos(io) < itemsEndPos) {
+        plc4c_modbus_read_write_modbus_pdu_read_file_record_request_item* _value = NULL;
+        _res = plc4c_modbus_read_write_modbus_pdu_read_file_record_request_item_parse(io, (void*) &_value);
         if(_res != OK) {
           return _res;
         }
@@ -890,7 +881,7 @@
                     
     // Implicit Field (byteCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
     uint8_t byteCount = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &byteCount);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &byteCount);
     if(_res != OK) {
       return _res;
     }
@@ -906,10 +897,10 @@
     {
       // Length array
       uint8_t _itemsLength = byteCount;
-      uint8_t itemsEndPos = plc4c_spi_read_get_pos(buf) + _itemsLength;
-      while(plc4c_spi_read_get_pos(buf) < itemsEndPos) {
-        plc4c_list* _value = NULL;
-        _res = plc4c_modbus_read_write_modbus_pdu_read_file_record_response_item_parse(buf, (void*) &_value);
+      uint8_t itemsEndPos = plc4c_spi_read_get_pos(io) + _itemsLength;
+      while(plc4c_spi_read_get_pos(io) < itemsEndPos) {
+        plc4c_modbus_read_write_modbus_pdu_read_file_record_response_item* _value = NULL;
+        _res = plc4c_modbus_read_write_modbus_pdu_read_file_record_response_item_parse(io, (void*) &_value);
         if(_res != OK) {
           return _res;
         }
@@ -924,7 +915,7 @@
                     
     // Implicit Field (byteCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
     uint8_t byteCount = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &byteCount);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &byteCount);
     if(_res != OK) {
       return _res;
     }
@@ -940,10 +931,10 @@
     {
       // Length array
       uint8_t _itemsLength = byteCount;
-      uint8_t itemsEndPos = plc4c_spi_read_get_pos(buf) + _itemsLength;
-      while(plc4c_spi_read_get_pos(buf) < itemsEndPos) {
-        plc4c_list* _value = NULL;
-        _res = plc4c_modbus_read_write_modbus_pdu_write_file_record_request_item_parse(buf, (void*) &_value);
+      uint8_t itemsEndPos = plc4c_spi_read_get_pos(io) + _itemsLength;
+      while(plc4c_spi_read_get_pos(io) < itemsEndPos) {
+        plc4c_modbus_read_write_modbus_pdu_write_file_record_request_item* _value = NULL;
+        _res = plc4c_modbus_read_write_modbus_pdu_write_file_record_request_item_parse(io, (void*) &_value);
         if(_res != OK) {
           return _res;
         }
@@ -958,7 +949,7 @@
                     
     // Implicit Field (byteCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
     uint8_t byteCount = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &byteCount);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &byteCount);
     if(_res != OK) {
       return _res;
     }
@@ -974,10 +965,10 @@
     {
       // Length array
       uint8_t _itemsLength = byteCount;
-      uint8_t itemsEndPos = plc4c_spi_read_get_pos(buf) + _itemsLength;
-      while(plc4c_spi_read_get_pos(buf) < itemsEndPos) {
-        plc4c_list* _value = NULL;
-        _res = plc4c_modbus_read_write_modbus_pdu_write_file_record_response_item_parse(buf, (void*) &_value);
+      uint8_t itemsEndPos = plc4c_spi_read_get_pos(io) + _itemsLength;
+      while(plc4c_spi_read_get_pos(io) < itemsEndPos) {
+        plc4c_modbus_read_write_modbus_pdu_write_file_record_response_item* _value = NULL;
+        _res = plc4c_modbus_read_write_modbus_pdu_write_file_record_response_item_parse(io, (void*) &_value);
         if(_res != OK) {
           return _res;
         }
@@ -995,7 +986,7 @@
                     
     // Simple Field (value)
     uint8_t value = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &value);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &value);
     if(_res != OK) {
       return _res;
     }
@@ -1007,7 +998,7 @@
                     
     // Simple Field (status)
     uint16_t status = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &status);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &status);
     if(_res != OK) {
       return _res;
     }
@@ -1017,7 +1008,7 @@
                     
     // Simple Field (eventCount)
     uint16_t eventCount = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &eventCount);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &eventCount);
     if(_res != OK) {
       return _res;
     }
@@ -1032,7 +1023,7 @@
                     
     // Implicit Field (byteCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
     uint8_t byteCount = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &byteCount);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &byteCount);
     if(_res != OK) {
       return _res;
     }
@@ -1041,7 +1032,7 @@
                     
     // Simple Field (status)
     uint16_t status = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &status);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &status);
     if(_res != OK) {
       return _res;
     }
@@ -1051,7 +1042,7 @@
                     
     // Simple Field (eventCount)
     uint16_t eventCount = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &eventCount);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &eventCount);
     if(_res != OK) {
       return _res;
     }
@@ -1061,7 +1052,7 @@
                     
     // Simple Field (messageCount)
     uint16_t messageCount = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &messageCount);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &messageCount);
     if(_res != OK) {
       return _res;
     }
@@ -1080,9 +1071,8 @@
       uint8_t itemCount = (byteCount) - (6);
       for(int curItem = 0; curItem < itemCount; curItem++) {
         
-                  
         int8_t* _value = malloc(sizeof(int8_t));
-        _res = plc4c_spi_read_signed_byte(buf, 8, (int8_t*) _value);
+        _res = plc4c_spi_read_signed_byte(io, 8, (int8_t*) _value);
         if(_res != OK) {
           return _res;
         }
@@ -1100,7 +1090,7 @@
                     
     // Implicit Field (byteCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
     uint8_t byteCount = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &byteCount);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &byteCount);
     if(_res != OK) {
       return _res;
     }
@@ -1118,9 +1108,8 @@
       uint8_t itemCount = byteCount;
       for(int curItem = 0; curItem < itemCount; curItem++) {
         
-                  
         int8_t* _value = malloc(sizeof(int8_t));
-        _res = plc4c_spi_read_signed_byte(buf, 8, (int8_t*) _value);
+        _res = plc4c_spi_read_signed_byte(io, 8, (int8_t*) _value);
         if(_res != OK) {
           return _res;
         }
@@ -1140,21 +1129,21 @@
   return OK;
 }
 
-plc4c_return_code plc4c_modbus_read_write_modbus_pdu_serialize(plc4c_spi_write_buffer* buf, plc4c_modbus_read_write_modbus_pdu* _message) {
+plc4c_return_code plc4c_modbus_read_write_modbus_pdu_serialize(plc4c_spi_write_buffer* io, plc4c_modbus_read_write_modbus_pdu* _message) {
   plc4c_return_code _res = OK;
 
   // Discriminator Field (error)
-  plc4c_spi_write_bit(buf, plc4c_modbus_read_write_modbus_pdu_get_discriminator(_message->_type).error);
+  plc4c_spi_write_bit(io, plc4c_modbus_read_write_modbus_pdu_get_discriminator(_message->_type).error);
 
   // Discriminator Field (function)
-  plc4c_spi_write_unsigned_byte(buf, 7, plc4c_modbus_read_write_modbus_pdu_get_discriminator(_message->_type).function);
+  plc4c_spi_write_unsigned_byte(io, 7, plc4c_modbus_read_write_modbus_pdu_get_discriminator(_message->_type).function);
 
   // Switch Field (Depending of the current type, serialize the sub-type elements)
   switch(_message->_type) {
     case plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_error: {
 
       // Simple Field (exceptionCode)
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, _message->modbus_pdu_error_exception_code);
+      _res = plc4c_spi_write_unsigned_byte(io, 8, _message->modbus_pdu_error_exception_code);
       if(_res != OK) {
         return _res;
       }
@@ -1164,13 +1153,13 @@
     case plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_read_discrete_inputs_request: {
 
       // Simple Field (startingAddress)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_read_discrete_inputs_request_starting_address);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_read_discrete_inputs_request_starting_address);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (quantity)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_read_discrete_inputs_request_quantity);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_read_discrete_inputs_request_quantity);
       if(_res != OK) {
         return _res;
       }
@@ -1180,7 +1169,7 @@
     case plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_read_discrete_inputs_response: {
 
       // Implicit Field (byteCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, plc4c_spi_evaluation_helper_count(_message->modbus_pdu_read_discrete_inputs_response_value));
+      _res = plc4c_spi_write_unsigned_byte(io, 8, plc4c_spi_evaluation_helper_count(_message->modbus_pdu_read_discrete_inputs_response_value));
       if(_res != OK) {
         return _res;
       }
@@ -1191,7 +1180,7 @@
         for(int curItem = 0; curItem < itemCount; curItem++) {
 
           int8_t* _value = (int8_t*) plc4c_utils_list_get_value(_message->modbus_pdu_read_discrete_inputs_response_value, curItem);
-          plc4c_spi_write_signed_byte(buf, 8, *_value);
+          plc4c_spi_write_signed_byte(io, 8, *_value);
         }
       }
 
@@ -1200,13 +1189,13 @@
     case plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_read_coils_request: {
 
       // Simple Field (startingAddress)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_read_coils_request_starting_address);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_read_coils_request_starting_address);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (quantity)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_read_coils_request_quantity);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_read_coils_request_quantity);
       if(_res != OK) {
         return _res;
       }
@@ -1216,7 +1205,7 @@
     case plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_read_coils_response: {
 
       // Implicit Field (byteCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, plc4c_spi_evaluation_helper_count(_message->modbus_pdu_read_coils_response_value));
+      _res = plc4c_spi_write_unsigned_byte(io, 8, plc4c_spi_evaluation_helper_count(_message->modbus_pdu_read_coils_response_value));
       if(_res != OK) {
         return _res;
       }
@@ -1227,7 +1216,7 @@
         for(int curItem = 0; curItem < itemCount; curItem++) {
 
           int8_t* _value = (int8_t*) plc4c_utils_list_get_value(_message->modbus_pdu_read_coils_response_value, curItem);
-          plc4c_spi_write_signed_byte(buf, 8, *_value);
+          plc4c_spi_write_signed_byte(io, 8, *_value);
         }
       }
 
@@ -1236,13 +1225,13 @@
     case plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_write_single_coil_request: {
 
       // Simple Field (address)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_write_single_coil_request_address);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_write_single_coil_request_address);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (value)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_write_single_coil_request_value);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_write_single_coil_request_value);
       if(_res != OK) {
         return _res;
       }
@@ -1252,13 +1241,13 @@
     case plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_write_single_coil_response: {
 
       // Simple Field (address)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_write_single_coil_response_address);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_write_single_coil_response_address);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (value)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_write_single_coil_response_value);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_write_single_coil_response_value);
       if(_res != OK) {
         return _res;
       }
@@ -1268,19 +1257,19 @@
     case plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_write_multiple_coils_request: {
 
       // Simple Field (startingAddress)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_write_multiple_coils_request_starting_address);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_write_multiple_coils_request_starting_address);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (quantity)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_write_multiple_coils_request_quantity);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_write_multiple_coils_request_quantity);
       if(_res != OK) {
         return _res;
       }
 
       // Implicit Field (byteCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, plc4c_spi_evaluation_helper_count(_message->modbus_pdu_write_multiple_coils_request_value));
+      _res = plc4c_spi_write_unsigned_byte(io, 8, plc4c_spi_evaluation_helper_count(_message->modbus_pdu_write_multiple_coils_request_value));
       if(_res != OK) {
         return _res;
       }
@@ -1291,7 +1280,7 @@
         for(int curItem = 0; curItem < itemCount; curItem++) {
 
           int8_t* _value = (int8_t*) plc4c_utils_list_get_value(_message->modbus_pdu_write_multiple_coils_request_value, curItem);
-          plc4c_spi_write_signed_byte(buf, 8, *_value);
+          plc4c_spi_write_signed_byte(io, 8, *_value);
         }
       }
 
@@ -1300,13 +1289,13 @@
     case plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_write_multiple_coils_response: {
 
       // Simple Field (startingAddress)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_write_multiple_coils_response_starting_address);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_write_multiple_coils_response_starting_address);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (quantity)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_write_multiple_coils_response_quantity);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_write_multiple_coils_response_quantity);
       if(_res != OK) {
         return _res;
       }
@@ -1316,13 +1305,13 @@
     case plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_read_input_registers_request: {
 
       // Simple Field (startingAddress)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_read_input_registers_request_starting_address);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_read_input_registers_request_starting_address);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (quantity)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_read_input_registers_request_quantity);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_read_input_registers_request_quantity);
       if(_res != OK) {
         return _res;
       }
@@ -1332,7 +1321,7 @@
     case plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_read_input_registers_response: {
 
       // Implicit Field (byteCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, plc4c_spi_evaluation_helper_count(_message->modbus_pdu_read_input_registers_response_value));
+      _res = plc4c_spi_write_unsigned_byte(io, 8, plc4c_spi_evaluation_helper_count(_message->modbus_pdu_read_input_registers_response_value));
       if(_res != OK) {
         return _res;
       }
@@ -1343,7 +1332,7 @@
         for(int curItem = 0; curItem < itemCount; curItem++) {
 
           int8_t* _value = (int8_t*) plc4c_utils_list_get_value(_message->modbus_pdu_read_input_registers_response_value, curItem);
-          plc4c_spi_write_signed_byte(buf, 8, *_value);
+          plc4c_spi_write_signed_byte(io, 8, *_value);
         }
       }
 
@@ -1352,13 +1341,13 @@
     case plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_read_holding_registers_request: {
 
       // Simple Field (startingAddress)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_read_holding_registers_request_starting_address);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_read_holding_registers_request_starting_address);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (quantity)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_read_holding_registers_request_quantity);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_read_holding_registers_request_quantity);
       if(_res != OK) {
         return _res;
       }
@@ -1368,7 +1357,7 @@
     case plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_read_holding_registers_response: {
 
       // Implicit Field (byteCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, plc4c_spi_evaluation_helper_count(_message->modbus_pdu_read_holding_registers_response_value));
+      _res = plc4c_spi_write_unsigned_byte(io, 8, plc4c_spi_evaluation_helper_count(_message->modbus_pdu_read_holding_registers_response_value));
       if(_res != OK) {
         return _res;
       }
@@ -1379,7 +1368,7 @@
         for(int curItem = 0; curItem < itemCount; curItem++) {
 
           int8_t* _value = (int8_t*) plc4c_utils_list_get_value(_message->modbus_pdu_read_holding_registers_response_value, curItem);
-          plc4c_spi_write_signed_byte(buf, 8, *_value);
+          plc4c_spi_write_signed_byte(io, 8, *_value);
         }
       }
 
@@ -1388,13 +1377,13 @@
     case plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_write_single_register_request: {
 
       // Simple Field (address)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_write_single_register_request_address);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_write_single_register_request_address);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (value)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_write_single_register_request_value);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_write_single_register_request_value);
       if(_res != OK) {
         return _res;
       }
@@ -1404,13 +1393,13 @@
     case plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_write_single_register_response: {
 
       // Simple Field (address)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_write_single_register_response_address);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_write_single_register_response_address);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (value)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_write_single_register_response_value);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_write_single_register_response_value);
       if(_res != OK) {
         return _res;
       }
@@ -1420,19 +1409,19 @@
     case plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_write_multiple_holding_registers_request: {
 
       // Simple Field (startingAddress)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_write_multiple_holding_registers_request_starting_address);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_write_multiple_holding_registers_request_starting_address);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (quantity)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_write_multiple_holding_registers_request_quantity);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_write_multiple_holding_registers_request_quantity);
       if(_res != OK) {
         return _res;
       }
 
       // Implicit Field (byteCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, plc4c_spi_evaluation_helper_count(_message->modbus_pdu_write_multiple_holding_registers_request_value));
+      _res = plc4c_spi_write_unsigned_byte(io, 8, plc4c_spi_evaluation_helper_count(_message->modbus_pdu_write_multiple_holding_registers_request_value));
       if(_res != OK) {
         return _res;
       }
@@ -1443,7 +1432,7 @@
         for(int curItem = 0; curItem < itemCount; curItem++) {
 
           int8_t* _value = (int8_t*) plc4c_utils_list_get_value(_message->modbus_pdu_write_multiple_holding_registers_request_value, curItem);
-          plc4c_spi_write_signed_byte(buf, 8, *_value);
+          plc4c_spi_write_signed_byte(io, 8, *_value);
         }
       }
 
@@ -1452,13 +1441,13 @@
     case plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_write_multiple_holding_registers_response: {
 
       // Simple Field (startingAddress)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_write_multiple_holding_registers_response_starting_address);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_write_multiple_holding_registers_response_starting_address);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (quantity)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_write_multiple_holding_registers_response_quantity);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_write_multiple_holding_registers_response_quantity);
       if(_res != OK) {
         return _res;
       }
@@ -1468,31 +1457,31 @@
     case plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_read_write_multiple_holding_registers_request: {
 
       // Simple Field (readStartingAddress)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_read_write_multiple_holding_registers_request_read_starting_address);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_read_write_multiple_holding_registers_request_read_starting_address);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (readQuantity)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_read_write_multiple_holding_registers_request_read_quantity);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_read_write_multiple_holding_registers_request_read_quantity);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (writeStartingAddress)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_read_write_multiple_holding_registers_request_write_starting_address);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_read_write_multiple_holding_registers_request_write_starting_address);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (writeQuantity)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_read_write_multiple_holding_registers_request_write_quantity);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_read_write_multiple_holding_registers_request_write_quantity);
       if(_res != OK) {
         return _res;
       }
 
       // Implicit Field (byteCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, plc4c_spi_evaluation_helper_count(_message->modbus_pdu_read_write_multiple_holding_registers_request_value));
+      _res = plc4c_spi_write_unsigned_byte(io, 8, plc4c_spi_evaluation_helper_count(_message->modbus_pdu_read_write_multiple_holding_registers_request_value));
       if(_res != OK) {
         return _res;
       }
@@ -1503,7 +1492,7 @@
         for(int curItem = 0; curItem < itemCount; curItem++) {
 
           int8_t* _value = (int8_t*) plc4c_utils_list_get_value(_message->modbus_pdu_read_write_multiple_holding_registers_request_value, curItem);
-          plc4c_spi_write_signed_byte(buf, 8, *_value);
+          plc4c_spi_write_signed_byte(io, 8, *_value);
         }
       }
 
@@ -1512,7 +1501,7 @@
     case plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_read_write_multiple_holding_registers_response: {
 
       // Implicit Field (byteCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, plc4c_spi_evaluation_helper_count(_message->modbus_pdu_read_write_multiple_holding_registers_response_value));
+      _res = plc4c_spi_write_unsigned_byte(io, 8, plc4c_spi_evaluation_helper_count(_message->modbus_pdu_read_write_multiple_holding_registers_response_value));
       if(_res != OK) {
         return _res;
       }
@@ -1523,7 +1512,7 @@
         for(int curItem = 0; curItem < itemCount; curItem++) {
 
           int8_t* _value = (int8_t*) plc4c_utils_list_get_value(_message->modbus_pdu_read_write_multiple_holding_registers_response_value, curItem);
-          plc4c_spi_write_signed_byte(buf, 8, *_value);
+          plc4c_spi_write_signed_byte(io, 8, *_value);
         }
       }
 
@@ -1532,19 +1521,19 @@
     case plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_mask_write_holding_register_request: {
 
       // Simple Field (referenceAddress)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_mask_write_holding_register_request_reference_address);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_mask_write_holding_register_request_reference_address);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (andMask)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_mask_write_holding_register_request_and_mask);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_mask_write_holding_register_request_and_mask);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (orMask)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_mask_write_holding_register_request_or_mask);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_mask_write_holding_register_request_or_mask);
       if(_res != OK) {
         return _res;
       }
@@ -1554,19 +1543,19 @@
     case plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_mask_write_holding_register_response: {
 
       // Simple Field (referenceAddress)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_mask_write_holding_register_response_reference_address);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_mask_write_holding_register_response_reference_address);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (andMask)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_mask_write_holding_register_response_and_mask);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_mask_write_holding_register_response_and_mask);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (orMask)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_mask_write_holding_register_response_or_mask);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_mask_write_holding_register_response_or_mask);
       if(_res != OK) {
         return _res;
       }
@@ -1576,7 +1565,7 @@
     case plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_read_fifo_queue_request: {
 
       // Simple Field (fifoPointerAddress)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_read_fifo_queue_request_fifo_pointer_address);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_read_fifo_queue_request_fifo_pointer_address);
       if(_res != OK) {
         return _res;
       }
@@ -1586,13 +1575,13 @@
     case plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_read_fifo_queue_response: {
 
       // Implicit Field (byteCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, (((plc4c_spi_evaluation_helper_count(_message->modbus_pdu_read_fifo_queue_response_fifo_value)) * (2))) + (2));
+      _res = plc4c_spi_write_unsigned_short(io, 16, (((plc4c_spi_evaluation_helper_count(_message->modbus_pdu_read_fifo_queue_response_fifo_value)) * (2))) + (2));
       if(_res != OK) {
         return _res;
       }
 
       // Implicit Field (fifoCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, (((plc4c_spi_evaluation_helper_count(_message->modbus_pdu_read_fifo_queue_response_fifo_value)) * (2))) / (2));
+      _res = plc4c_spi_write_unsigned_short(io, 16, (((plc4c_spi_evaluation_helper_count(_message->modbus_pdu_read_fifo_queue_response_fifo_value)) * (2))) / (2));
       if(_res != OK) {
         return _res;
       }
@@ -1603,7 +1592,7 @@
         for(int curItem = 0; curItem < itemCount; curItem++) {
 
           uint16_t* _value = (uint16_t*) plc4c_utils_list_get_value(_message->modbus_pdu_read_fifo_queue_response_fifo_value, curItem);
-          plc4c_spi_write_unsigned_short(buf, 16, *_value);
+          plc4c_spi_write_unsigned_short(io, 16, *_value);
         }
       }
 
@@ -1612,7 +1601,7 @@
     case plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_read_file_record_request: {
 
       // Implicit Field (byteCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, plc4c_spi_evaluation_helper_array_size_in_bytes(_message->modbus_pdu_read_file_record_request_items));
+      _res = plc4c_spi_write_unsigned_byte(io, 8, plc4c_spi_evaluation_helper_array_size_in_bytes(_message->modbus_pdu_read_file_record_request_items));
       if(_res != OK) {
         return _res;
       }
@@ -1623,7 +1612,7 @@
         for(int curItem = 0; curItem < itemCount; curItem++) {
           bool lastItem = curItem == (itemCount - 1);
           plc4c_modbus_read_write_modbus_pdu_read_file_record_request_item* _value = (plc4c_modbus_read_write_modbus_pdu_read_file_record_request_item*) plc4c_utils_list_get_value(_message->modbus_pdu_read_file_record_request_items, curItem);
-          _res = plc4c_modbus_read_write_modbus_pdu_read_file_record_request_item_serialize(buf, (void*) _value);
+          _res = plc4c_modbus_read_write_modbus_pdu_read_file_record_request_item_serialize(io, (void*) _value);
           if(_res != OK) {
             return _res;
           }
@@ -1635,7 +1624,7 @@
     case plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_read_file_record_response: {
 
       // Implicit Field (byteCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, plc4c_spi_evaluation_helper_array_size_in_bytes(_message->modbus_pdu_read_file_record_response_items));
+      _res = plc4c_spi_write_unsigned_byte(io, 8, plc4c_spi_evaluation_helper_array_size_in_bytes(_message->modbus_pdu_read_file_record_response_items));
       if(_res != OK) {
         return _res;
       }
@@ -1646,7 +1635,7 @@
         for(int curItem = 0; curItem < itemCount; curItem++) {
           bool lastItem = curItem == (itemCount - 1);
           plc4c_modbus_read_write_modbus_pdu_read_file_record_response_item* _value = (plc4c_modbus_read_write_modbus_pdu_read_file_record_response_item*) plc4c_utils_list_get_value(_message->modbus_pdu_read_file_record_response_items, curItem);
-          _res = plc4c_modbus_read_write_modbus_pdu_read_file_record_response_item_serialize(buf, (void*) _value);
+          _res = plc4c_modbus_read_write_modbus_pdu_read_file_record_response_item_serialize(io, (void*) _value);
           if(_res != OK) {
             return _res;
           }
@@ -1658,7 +1647,7 @@
     case plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_write_file_record_request: {
 
       // Implicit Field (byteCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, plc4c_spi_evaluation_helper_array_size_in_bytes(_message->modbus_pdu_write_file_record_request_items));
+      _res = plc4c_spi_write_unsigned_byte(io, 8, plc4c_spi_evaluation_helper_array_size_in_bytes(_message->modbus_pdu_write_file_record_request_items));
       if(_res != OK) {
         return _res;
       }
@@ -1669,7 +1658,7 @@
         for(int curItem = 0; curItem < itemCount; curItem++) {
           bool lastItem = curItem == (itemCount - 1);
           plc4c_modbus_read_write_modbus_pdu_write_file_record_request_item* _value = (plc4c_modbus_read_write_modbus_pdu_write_file_record_request_item*) plc4c_utils_list_get_value(_message->modbus_pdu_write_file_record_request_items, curItem);
-          _res = plc4c_modbus_read_write_modbus_pdu_write_file_record_request_item_serialize(buf, (void*) _value);
+          _res = plc4c_modbus_read_write_modbus_pdu_write_file_record_request_item_serialize(io, (void*) _value);
           if(_res != OK) {
             return _res;
           }
@@ -1681,7 +1670,7 @@
     case plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_write_file_record_response: {
 
       // Implicit Field (byteCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, plc4c_spi_evaluation_helper_array_size_in_bytes(_message->modbus_pdu_write_file_record_response_items));
+      _res = plc4c_spi_write_unsigned_byte(io, 8, plc4c_spi_evaluation_helper_array_size_in_bytes(_message->modbus_pdu_write_file_record_response_items));
       if(_res != OK) {
         return _res;
       }
@@ -1692,7 +1681,7 @@
         for(int curItem = 0; curItem < itemCount; curItem++) {
           bool lastItem = curItem == (itemCount - 1);
           plc4c_modbus_read_write_modbus_pdu_write_file_record_response_item* _value = (plc4c_modbus_read_write_modbus_pdu_write_file_record_response_item*) plc4c_utils_list_get_value(_message->modbus_pdu_write_file_record_response_items, curItem);
-          _res = plc4c_modbus_read_write_modbus_pdu_write_file_record_response_item_serialize(buf, (void*) _value);
+          _res = plc4c_modbus_read_write_modbus_pdu_write_file_record_response_item_serialize(io, (void*) _value);
           if(_res != OK) {
             return _res;
           }
@@ -1708,7 +1697,7 @@
     case plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_read_exception_status_response: {
 
       // Simple Field (value)
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, _message->modbus_pdu_read_exception_status_response_value);
+      _res = plc4c_spi_write_unsigned_byte(io, 8, _message->modbus_pdu_read_exception_status_response_value);
       if(_res != OK) {
         return _res;
       }
@@ -1718,13 +1707,13 @@
     case plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_diagnostic_request: {
 
       // Simple Field (status)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_diagnostic_request_status);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_diagnostic_request_status);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (eventCount)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_diagnostic_request_event_count);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_diagnostic_request_event_count);
       if(_res != OK) {
         return _res;
       }
@@ -1738,25 +1727,25 @@
     case plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_get_com_event_log_response: {
 
       // Implicit Field (byteCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, (plc4c_spi_evaluation_helper_count(_message->modbus_pdu_get_com_event_log_response_events)) + (6));
+      _res = plc4c_spi_write_unsigned_byte(io, 8, (plc4c_spi_evaluation_helper_count(_message->modbus_pdu_get_com_event_log_response_events)) + (6));
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (status)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_get_com_event_log_response_status);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_get_com_event_log_response_status);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (eventCount)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_get_com_event_log_response_event_count);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_get_com_event_log_response_event_count);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (messageCount)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->modbus_pdu_get_com_event_log_response_message_count);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->modbus_pdu_get_com_event_log_response_message_count);
       if(_res != OK) {
         return _res;
       }
@@ -1767,7 +1756,7 @@
         for(int curItem = 0; curItem < itemCount; curItem++) {
 
           int8_t* _value = (int8_t*) plc4c_utils_list_get_value(_message->modbus_pdu_get_com_event_log_response_events, curItem);
-          plc4c_spi_write_signed_byte(buf, 8, *_value);
+          plc4c_spi_write_signed_byte(io, 8, *_value);
         }
       }
 
@@ -1780,7 +1769,7 @@
     case plc4c_modbus_read_write_modbus_pdu_type_plc4c_modbus_read_write_modbus_pdu_report_server_id_response: {
 
       // Implicit Field (byteCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, plc4c_spi_evaluation_helper_count(_message->modbus_pdu_report_server_id_response_value));
+      _res = plc4c_spi_write_unsigned_byte(io, 8, plc4c_spi_evaluation_helper_count(_message->modbus_pdu_report_server_id_response_value));
       if(_res != OK) {
         return _res;
       }
@@ -1791,7 +1780,7 @@
         for(int curItem = 0; curItem < itemCount; curItem++) {
 
           int8_t* _value = (int8_t*) plc4c_utils_list_get_value(_message->modbus_pdu_report_server_id_response_value, curItem);
-          plc4c_spi_write_signed_byte(buf, 8, *_value);
+          plc4c_spi_write_signed_byte(io, 8, *_value);
         }
       }
 
diff --git a/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu_read_file_record_request_item.c b/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu_read_file_record_request_item.c
index b11214e..a4cf978 100644
--- a/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu_read_file_record_request_item.c
+++ b/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu_read_file_record_request_item.c
@@ -23,8 +23,8 @@
 
 
 // Parse function.
-plc4c_return_code plc4c_modbus_read_write_modbus_pdu_read_file_record_request_item_parse(plc4c_spi_read_buffer* buf, plc4c_modbus_read_write_modbus_pdu_read_file_record_request_item** _message) {
-  uint16_t startPos = plc4c_spi_read_get_pos(buf);
+plc4c_return_code plc4c_modbus_read_write_modbus_pdu_read_file_record_request_item_parse(plc4c_spi_read_buffer* io, plc4c_modbus_read_write_modbus_pdu_read_file_record_request_item** _message) {
+  uint16_t startPos = plc4c_spi_read_get_pos(io);
   uint16_t curPos;
   plc4c_return_code _res = OK;
 
@@ -36,7 +36,7 @@
 
   // Simple Field (referenceType)
   uint8_t referenceType = 0;
-  _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &referenceType);
+  _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &referenceType);
   if(_res != OK) {
     return _res;
   }
@@ -44,7 +44,7 @@
 
   // Simple Field (fileNumber)
   uint16_t fileNumber = 0;
-  _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &fileNumber);
+  _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &fileNumber);
   if(_res != OK) {
     return _res;
   }
@@ -52,7 +52,7 @@
 
   // Simple Field (recordNumber)
   uint16_t recordNumber = 0;
-  _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &recordNumber);
+  _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &recordNumber);
   if(_res != OK) {
     return _res;
   }
@@ -60,7 +60,7 @@
 
   // Simple Field (recordLength)
   uint16_t recordLength = 0;
-  _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &recordLength);
+  _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &recordLength);
   if(_res != OK) {
     return _res;
   }
@@ -69,29 +69,29 @@
   return OK;
 }
 
-plc4c_return_code plc4c_modbus_read_write_modbus_pdu_read_file_record_request_item_serialize(plc4c_spi_write_buffer* buf, plc4c_modbus_read_write_modbus_pdu_read_file_record_request_item* _message) {
+plc4c_return_code plc4c_modbus_read_write_modbus_pdu_read_file_record_request_item_serialize(plc4c_spi_write_buffer* io, plc4c_modbus_read_write_modbus_pdu_read_file_record_request_item* _message) {
   plc4c_return_code _res = OK;
 
   // Simple Field (referenceType)
-  _res = plc4c_spi_write_unsigned_byte(buf, 8, _message->reference_type);
+  _res = plc4c_spi_write_unsigned_byte(io, 8, _message->reference_type);
   if(_res != OK) {
     return _res;
   }
 
   // Simple Field (fileNumber)
-  _res = plc4c_spi_write_unsigned_short(buf, 16, _message->file_number);
+  _res = plc4c_spi_write_unsigned_short(io, 16, _message->file_number);
   if(_res != OK) {
     return _res;
   }
 
   // Simple Field (recordNumber)
-  _res = plc4c_spi_write_unsigned_short(buf, 16, _message->record_number);
+  _res = plc4c_spi_write_unsigned_short(io, 16, _message->record_number);
   if(_res != OK) {
     return _res;
   }
 
   // Simple Field (recordLength)
-  _res = plc4c_spi_write_unsigned_short(buf, 16, _message->record_length);
+  _res = plc4c_spi_write_unsigned_short(io, 16, _message->record_length);
   if(_res != OK) {
     return _res;
   }
diff --git a/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu_read_file_record_response_item.c b/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu_read_file_record_response_item.c
index f3ffe9a..aeff2ae 100644
--- a/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu_read_file_record_response_item.c
+++ b/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu_read_file_record_response_item.c
@@ -23,8 +23,8 @@
 
 
 // Parse function.
-plc4c_return_code plc4c_modbus_read_write_modbus_pdu_read_file_record_response_item_parse(plc4c_spi_read_buffer* buf, plc4c_modbus_read_write_modbus_pdu_read_file_record_response_item** _message) {
-  uint16_t startPos = plc4c_spi_read_get_pos(buf);
+plc4c_return_code plc4c_modbus_read_write_modbus_pdu_read_file_record_response_item_parse(plc4c_spi_read_buffer* io, plc4c_modbus_read_write_modbus_pdu_read_file_record_response_item** _message) {
+  uint16_t startPos = plc4c_spi_read_get_pos(io);
   uint16_t curPos;
   plc4c_return_code _res = OK;
 
@@ -36,14 +36,14 @@
 
   // Implicit Field (dataLength) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
   uint8_t dataLength = 0;
-  _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &dataLength);
+  _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &dataLength);
   if(_res != OK) {
     return _res;
   }
 
   // Simple Field (referenceType)
   uint8_t referenceType = 0;
-  _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &referenceType);
+  _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &referenceType);
   if(_res != OK) {
     return _res;
   }
@@ -58,10 +58,10 @@
   {
     // Length array
     uint8_t _dataLength = (dataLength) - (1);
-    uint8_t dataEndPos = plc4c_spi_read_get_pos(buf) + _dataLength;
-    while(plc4c_spi_read_get_pos(buf) < dataEndPos) {
+    uint8_t dataEndPos = plc4c_spi_read_get_pos(io) + _dataLength;
+    while(plc4c_spi_read_get_pos(io) < dataEndPos) {
       int8_t _value = 0;
-      _res = plc4c_spi_read_signed_byte(buf, 8, (int8_t*) &_value);
+      _res = plc4c_spi_read_signed_byte(io, 8, (int8_t*) &_value);
       if(_res != OK) {
         return _res;
       }
@@ -73,17 +73,17 @@
   return OK;
 }
 
-plc4c_return_code plc4c_modbus_read_write_modbus_pdu_read_file_record_response_item_serialize(plc4c_spi_write_buffer* buf, plc4c_modbus_read_write_modbus_pdu_read_file_record_response_item* _message) {
+plc4c_return_code plc4c_modbus_read_write_modbus_pdu_read_file_record_response_item_serialize(plc4c_spi_write_buffer* io, plc4c_modbus_read_write_modbus_pdu_read_file_record_response_item* _message) {
   plc4c_return_code _res = OK;
 
   // Implicit Field (dataLength) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-  _res = plc4c_spi_write_unsigned_byte(buf, 8, (plc4c_spi_evaluation_helper_count(_message->data)) + (1));
+  _res = plc4c_spi_write_unsigned_byte(io, 8, (plc4c_spi_evaluation_helper_count(_message->data)) + (1));
   if(_res != OK) {
     return _res;
   }
 
   // Simple Field (referenceType)
-  _res = plc4c_spi_write_unsigned_byte(buf, 8, _message->reference_type);
+  _res = plc4c_spi_write_unsigned_byte(io, 8, _message->reference_type);
   if(_res != OK) {
     return _res;
   }
@@ -94,7 +94,7 @@
     for(int curItem = 0; curItem < itemCount; curItem++) {
 
       int8_t* _value = (int8_t*) plc4c_utils_list_get_value(_message->data, curItem);
-      plc4c_spi_write_signed_byte(buf, 8, *_value);
+      plc4c_spi_write_signed_byte(io, 8, *_value);
     }
   }
 
diff --git a/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu_write_file_record_request_item.c b/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu_write_file_record_request_item.c
index 1fc51b8..9855f70 100644
--- a/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu_write_file_record_request_item.c
+++ b/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu_write_file_record_request_item.c
@@ -23,8 +23,8 @@
 
 
 // Parse function.
-plc4c_return_code plc4c_modbus_read_write_modbus_pdu_write_file_record_request_item_parse(plc4c_spi_read_buffer* buf, plc4c_modbus_read_write_modbus_pdu_write_file_record_request_item** _message) {
-  uint16_t startPos = plc4c_spi_read_get_pos(buf);
+plc4c_return_code plc4c_modbus_read_write_modbus_pdu_write_file_record_request_item_parse(plc4c_spi_read_buffer* io, plc4c_modbus_read_write_modbus_pdu_write_file_record_request_item** _message) {
+  uint16_t startPos = plc4c_spi_read_get_pos(io);
   uint16_t curPos;
   plc4c_return_code _res = OK;
 
@@ -36,7 +36,7 @@
 
   // Simple Field (referenceType)
   uint8_t referenceType = 0;
-  _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &referenceType);
+  _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &referenceType);
   if(_res != OK) {
     return _res;
   }
@@ -44,7 +44,7 @@
 
   // Simple Field (fileNumber)
   uint16_t fileNumber = 0;
-  _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &fileNumber);
+  _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &fileNumber);
   if(_res != OK) {
     return _res;
   }
@@ -52,7 +52,7 @@
 
   // Simple Field (recordNumber)
   uint16_t recordNumber = 0;
-  _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &recordNumber);
+  _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &recordNumber);
   if(_res != OK) {
     return _res;
   }
@@ -60,7 +60,7 @@
 
   // Implicit Field (recordLength) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
   uint16_t recordLength = 0;
-  _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &recordLength);
+  _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &recordLength);
   if(_res != OK) {
     return _res;
   }
@@ -74,10 +74,10 @@
   {
     // Length array
     uint8_t _recordDataLength = (recordLength) * (2);
-    uint8_t recordDataEndPos = plc4c_spi_read_get_pos(buf) + _recordDataLength;
-    while(plc4c_spi_read_get_pos(buf) < recordDataEndPos) {
+    uint8_t recordDataEndPos = plc4c_spi_read_get_pos(io) + _recordDataLength;
+    while(plc4c_spi_read_get_pos(io) < recordDataEndPos) {
       uint16_t _value = 0;
-      _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &_value);
+      _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &_value);
       if(_res != OK) {
         return _res;
       }
@@ -89,29 +89,29 @@
   return OK;
 }
 
-plc4c_return_code plc4c_modbus_read_write_modbus_pdu_write_file_record_request_item_serialize(plc4c_spi_write_buffer* buf, plc4c_modbus_read_write_modbus_pdu_write_file_record_request_item* _message) {
+plc4c_return_code plc4c_modbus_read_write_modbus_pdu_write_file_record_request_item_serialize(plc4c_spi_write_buffer* io, plc4c_modbus_read_write_modbus_pdu_write_file_record_request_item* _message) {
   plc4c_return_code _res = OK;
 
   // Simple Field (referenceType)
-  _res = plc4c_spi_write_unsigned_byte(buf, 8, _message->reference_type);
+  _res = plc4c_spi_write_unsigned_byte(io, 8, _message->reference_type);
   if(_res != OK) {
     return _res;
   }
 
   // Simple Field (fileNumber)
-  _res = plc4c_spi_write_unsigned_short(buf, 16, _message->file_number);
+  _res = plc4c_spi_write_unsigned_short(io, 16, _message->file_number);
   if(_res != OK) {
     return _res;
   }
 
   // Simple Field (recordNumber)
-  _res = plc4c_spi_write_unsigned_short(buf, 16, _message->record_number);
+  _res = plc4c_spi_write_unsigned_short(io, 16, _message->record_number);
   if(_res != OK) {
     return _res;
   }
 
   // Implicit Field (recordLength) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-  _res = plc4c_spi_write_unsigned_short(buf, 16, (((plc4c_spi_evaluation_helper_count(_message->record_data)) * (2))) / (2));
+  _res = plc4c_spi_write_unsigned_short(io, 16, (((plc4c_spi_evaluation_helper_count(_message->record_data)) * (2))) / (2));
   if(_res != OK) {
     return _res;
   }
@@ -122,7 +122,7 @@
     for(int curItem = 0; curItem < itemCount; curItem++) {
 
       uint16_t* _value = (uint16_t*) plc4c_utils_list_get_value(_message->record_data, curItem);
-      plc4c_spi_write_unsigned_short(buf, 16, *_value);
+      plc4c_spi_write_unsigned_short(io, 16, *_value);
     }
   }
 
diff --git a/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu_write_file_record_response_item.c b/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu_write_file_record_response_item.c
index 3826640..906650e 100644
--- a/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu_write_file_record_response_item.c
+++ b/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu_write_file_record_response_item.c
@@ -23,8 +23,8 @@
 
 
 // Parse function.
-plc4c_return_code plc4c_modbus_read_write_modbus_pdu_write_file_record_response_item_parse(plc4c_spi_read_buffer* buf, plc4c_modbus_read_write_modbus_pdu_write_file_record_response_item** _message) {
-  uint16_t startPos = plc4c_spi_read_get_pos(buf);
+plc4c_return_code plc4c_modbus_read_write_modbus_pdu_write_file_record_response_item_parse(plc4c_spi_read_buffer* io, plc4c_modbus_read_write_modbus_pdu_write_file_record_response_item** _message) {
+  uint16_t startPos = plc4c_spi_read_get_pos(io);
   uint16_t curPos;
   plc4c_return_code _res = OK;
 
@@ -36,7 +36,7 @@
 
   // Simple Field (referenceType)
   uint8_t referenceType = 0;
-  _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &referenceType);
+  _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &referenceType);
   if(_res != OK) {
     return _res;
   }
@@ -44,7 +44,7 @@
 
   // Simple Field (fileNumber)
   uint16_t fileNumber = 0;
-  _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &fileNumber);
+  _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &fileNumber);
   if(_res != OK) {
     return _res;
   }
@@ -52,7 +52,7 @@
 
   // Simple Field (recordNumber)
   uint16_t recordNumber = 0;
-  _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &recordNumber);
+  _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &recordNumber);
   if(_res != OK) {
     return _res;
   }
@@ -60,7 +60,7 @@
 
   // Implicit Field (recordLength) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
   uint16_t recordLength = 0;
-  _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &recordLength);
+  _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &recordLength);
   if(_res != OK) {
     return _res;
   }
@@ -74,10 +74,10 @@
   {
     // Length array
     uint8_t _recordDataLength = (recordLength) * (2);
-    uint8_t recordDataEndPos = plc4c_spi_read_get_pos(buf) + _recordDataLength;
-    while(plc4c_spi_read_get_pos(buf) < recordDataEndPos) {
+    uint8_t recordDataEndPos = plc4c_spi_read_get_pos(io) + _recordDataLength;
+    while(plc4c_spi_read_get_pos(io) < recordDataEndPos) {
       uint16_t _value = 0;
-      _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &_value);
+      _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &_value);
       if(_res != OK) {
         return _res;
       }
@@ -89,29 +89,29 @@
   return OK;
 }
 
-plc4c_return_code plc4c_modbus_read_write_modbus_pdu_write_file_record_response_item_serialize(plc4c_spi_write_buffer* buf, plc4c_modbus_read_write_modbus_pdu_write_file_record_response_item* _message) {
+plc4c_return_code plc4c_modbus_read_write_modbus_pdu_write_file_record_response_item_serialize(plc4c_spi_write_buffer* io, plc4c_modbus_read_write_modbus_pdu_write_file_record_response_item* _message) {
   plc4c_return_code _res = OK;
 
   // Simple Field (referenceType)
-  _res = plc4c_spi_write_unsigned_byte(buf, 8, _message->reference_type);
+  _res = plc4c_spi_write_unsigned_byte(io, 8, _message->reference_type);
   if(_res != OK) {
     return _res;
   }
 
   // Simple Field (fileNumber)
-  _res = plc4c_spi_write_unsigned_short(buf, 16, _message->file_number);
+  _res = plc4c_spi_write_unsigned_short(io, 16, _message->file_number);
   if(_res != OK) {
     return _res;
   }
 
   // Simple Field (recordNumber)
-  _res = plc4c_spi_write_unsigned_short(buf, 16, _message->record_number);
+  _res = plc4c_spi_write_unsigned_short(io, 16, _message->record_number);
   if(_res != OK) {
     return _res;
   }
 
   // Implicit Field (recordLength) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-  _res = plc4c_spi_write_unsigned_short(buf, 16, (((plc4c_spi_evaluation_helper_count(_message->record_data)) * (2))) / (2));
+  _res = plc4c_spi_write_unsigned_short(io, 16, (((plc4c_spi_evaluation_helper_count(_message->record_data)) * (2))) / (2));
   if(_res != OK) {
     return _res;
   }
@@ -122,7 +122,7 @@
     for(int curItem = 0; curItem < itemCount; curItem++) {
 
       uint16_t* _value = (uint16_t*) plc4c_utils_list_get_value(_message->record_data, curItem);
-      plc4c_spi_write_unsigned_short(buf, 16, *_value);
+      plc4c_spi_write_unsigned_short(io, 16, *_value);
     }
   }
 
diff --git a/sandbox/plc4c/generated-sources/modbus/src/modbus_serial_adu.c b/sandbox/plc4c/generated-sources/modbus/src/modbus_serial_adu.c
index a24d383..5cc1a4e 100644
--- a/sandbox/plc4c/generated-sources/modbus/src/modbus_serial_adu.c
+++ b/sandbox/plc4c/generated-sources/modbus/src/modbus_serial_adu.c
@@ -23,8 +23,8 @@
 
 
 // Parse function.
-plc4c_return_code plc4c_modbus_read_write_modbus_serial_adu_parse(plc4c_spi_read_buffer* buf, bool response, plc4c_modbus_read_write_modbus_serial_adu** _message) {
-  uint16_t startPos = plc4c_spi_read_get_pos(buf);
+plc4c_return_code plc4c_modbus_read_write_modbus_serial_adu_parse(plc4c_spi_read_buffer* io, bool response, plc4c_modbus_read_write_modbus_serial_adu** _message) {
+  uint16_t startPos = plc4c_spi_read_get_pos(io);
   uint16_t curPos;
   plc4c_return_code _res = OK;
 
@@ -36,7 +36,7 @@
 
   // Simple Field (transactionId)
   uint16_t transactionId = 0;
-  _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &transactionId);
+  _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &transactionId);
   if(_res != OK) {
     return _res;
   }
@@ -45,7 +45,7 @@
   // Reserved Field (Compartmentalized so the "reserved" variable can't leak)
   {
     uint16_t _reserved = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &_reserved);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &_reserved);
     if(_res != OK) {
       return _res;
     }
@@ -56,7 +56,7 @@
 
   // Simple Field (length)
   uint16_t length = 0;
-  _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &length);
+  _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &length);
   if(_res != OK) {
     return _res;
   }
@@ -64,7 +64,7 @@
 
   // Simple Field (address)
   uint8_t address = 0;
-  _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &address);
+  _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &address);
   if(_res != OK) {
     return _res;
   }
@@ -72,7 +72,7 @@
 
   // Simple Field (pdu)
   plc4c_modbus_read_write_modbus_pdu* pdu;
-  _res = plc4c_modbus_read_write_modbus_pdu_parse(buf, response, (void*) &pdu);
+  _res = plc4c_modbus_read_write_modbus_pdu_parse(io, response, (void*) &pdu);
   if(_res != OK) {
     return _res;
   }
@@ -81,35 +81,35 @@
   return OK;
 }
 
-plc4c_return_code plc4c_modbus_read_write_modbus_serial_adu_serialize(plc4c_spi_write_buffer* buf, plc4c_modbus_read_write_modbus_serial_adu* _message) {
+plc4c_return_code plc4c_modbus_read_write_modbus_serial_adu_serialize(plc4c_spi_write_buffer* io, plc4c_modbus_read_write_modbus_serial_adu* _message) {
   plc4c_return_code _res = OK;
 
   // Simple Field (transactionId)
-  _res = plc4c_spi_write_unsigned_short(buf, 16, _message->transaction_id);
+  _res = plc4c_spi_write_unsigned_short(io, 16, _message->transaction_id);
   if(_res != OK) {
     return _res;
   }
 
   // Reserved Field
-  _res = plc4c_spi_write_unsigned_short(buf, 16, 0x0000);
+  _res = plc4c_spi_write_unsigned_short(io, 16, 0x0000);
   if(_res != OK) {
     return _res;
   }
 
   // Simple Field (length)
-  _res = plc4c_spi_write_unsigned_short(buf, 16, _message->length);
+  _res = plc4c_spi_write_unsigned_short(io, 16, _message->length);
   if(_res != OK) {
     return _res;
   }
 
   // Simple Field (address)
-  _res = plc4c_spi_write_unsigned_byte(buf, 8, _message->address);
+  _res = plc4c_spi_write_unsigned_byte(io, 8, _message->address);
   if(_res != OK) {
     return _res;
   }
 
   // Simple Field (pdu)
-  _res = plc4c_modbus_read_write_modbus_pdu_serialize(buf, _message->pdu);
+  _res = plc4c_modbus_read_write_modbus_pdu_serialize(io, _message->pdu);
   if(_res != OK) {
     return _res;
   }
diff --git a/sandbox/plc4c/generated-sources/modbus/src/modbus_tcp_adu.c b/sandbox/plc4c/generated-sources/modbus/src/modbus_tcp_adu.c
index 1060207..77dac92 100644
--- a/sandbox/plc4c/generated-sources/modbus/src/modbus_tcp_adu.c
+++ b/sandbox/plc4c/generated-sources/modbus/src/modbus_tcp_adu.c
@@ -29,8 +29,8 @@
 }
 
 // Parse function.
-plc4c_return_code plc4c_modbus_read_write_modbus_tcp_adu_parse(plc4c_spi_read_buffer* buf, bool response, plc4c_modbus_read_write_modbus_tcp_adu** _message) {
-  uint16_t startPos = plc4c_spi_read_get_pos(buf);
+plc4c_return_code plc4c_modbus_read_write_modbus_tcp_adu_parse(plc4c_spi_read_buffer* io, bool response, plc4c_modbus_read_write_modbus_tcp_adu** _message) {
+  uint16_t startPos = plc4c_spi_read_get_pos(io);
   uint16_t curPos;
   plc4c_return_code _res = OK;
 
@@ -42,7 +42,7 @@
 
   // Simple Field (transactionIdentifier)
   uint16_t transactionIdentifier = 0;
-  _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &transactionIdentifier);
+  _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &transactionIdentifier);
   if(_res != OK) {
     return _res;
   }
@@ -50,7 +50,7 @@
 
   // Const Field (protocolIdentifier)
   uint16_t protocolIdentifier = 0;
-  _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &protocolIdentifier);
+  _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &protocolIdentifier);
   if(_res != OK) {
     return _res;
   }
@@ -61,14 +61,14 @@
 
   // Implicit Field (length) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
   uint16_t length = 0;
-  _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &length);
+  _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &length);
   if(_res != OK) {
     return _res;
   }
 
   // Simple Field (unitIdentifier)
   uint8_t unitIdentifier = 0;
-  _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &unitIdentifier);
+  _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &unitIdentifier);
   if(_res != OK) {
     return _res;
   }
@@ -76,7 +76,7 @@
 
   // Simple Field (pdu)
   plc4c_modbus_read_write_modbus_pdu* pdu;
-  _res = plc4c_modbus_read_write_modbus_pdu_parse(buf, response, (void*) &pdu);
+  _res = plc4c_modbus_read_write_modbus_pdu_parse(io, response, (void*) &pdu);
   if(_res != OK) {
     return _res;
   }
@@ -85,32 +85,32 @@
   return OK;
 }
 
-plc4c_return_code plc4c_modbus_read_write_modbus_tcp_adu_serialize(plc4c_spi_write_buffer* buf, plc4c_modbus_read_write_modbus_tcp_adu* _message) {
+plc4c_return_code plc4c_modbus_read_write_modbus_tcp_adu_serialize(plc4c_spi_write_buffer* io, plc4c_modbus_read_write_modbus_tcp_adu* _message) {
   plc4c_return_code _res = OK;
 
   // Simple Field (transactionIdentifier)
-  _res = plc4c_spi_write_unsigned_short(buf, 16, _message->transaction_identifier);
+  _res = plc4c_spi_write_unsigned_short(io, 16, _message->transaction_identifier);
   if(_res != OK) {
     return _res;
   }
 
   // Const Field (protocolIdentifier)
-  plc4c_spi_write_unsigned_short(buf, 16, PLC4C_MODBUS_READ_WRITE_MODBUS_TCP_ADU_PROTOCOL_IDENTIFIER());
+  plc4c_spi_write_unsigned_short(io, 16, PLC4C_MODBUS_READ_WRITE_MODBUS_TCP_ADU_PROTOCOL_IDENTIFIER());
 
   // Implicit Field (length) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-  _res = plc4c_spi_write_unsigned_short(buf, 16, (plc4c_modbus_read_write_modbus_pdu_length_in_bytes(_message->pdu)) + (1));
+  _res = plc4c_spi_write_unsigned_short(io, 16, (plc4c_modbus_read_write_modbus_pdu_length_in_bytes(_message->pdu)) + (1));
   if(_res != OK) {
     return _res;
   }
 
   // Simple Field (unitIdentifier)
-  _res = plc4c_spi_write_unsigned_byte(buf, 8, _message->unit_identifier);
+  _res = plc4c_spi_write_unsigned_byte(io, 8, _message->unit_identifier);
   if(_res != OK) {
     return _res;
   }
 
   // Simple Field (pdu)
-  _res = plc4c_modbus_read_write_modbus_pdu_serialize(buf, _message->pdu);
+  _res = plc4c_modbus_read_write_modbus_pdu_serialize(io, _message->pdu);
   if(_res != OK) {
     return _res;
   }
diff --git a/sandbox/plc4c/generated-sources/s7/includes/cotp_packet.h b/sandbox/plc4c/generated-sources/s7/include/cotp_packet.h
similarity index 96%
rename from sandbox/plc4c/generated-sources/s7/includes/cotp_packet.h
rename to sandbox/plc4c/generated-sources/s7/include/cotp_packet.h
index d66d287..3df58ae 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/cotp_packet.h
+++ b/sandbox/plc4c/generated-sources/s7/include/cotp_packet.h
@@ -94,9 +94,9 @@
 // Create an empty NULL-struct
 plc4c_s7_read_write_cotp_packet plc4c_s7_read_write_cotp_packet_null();
 
-plc4c_return_code plc4c_s7_read_write_cotp_packet_parse(plc4c_spi_read_buffer* buf, uint16_t cotpLen, plc4c_s7_read_write_cotp_packet** message);
+plc4c_return_code plc4c_s7_read_write_cotp_packet_parse(plc4c_spi_read_buffer* io, uint16_t cotpLen, plc4c_s7_read_write_cotp_packet** message);
 
-plc4c_return_code plc4c_s7_read_write_cotp_packet_serialize(plc4c_spi_write_buffer* buf, plc4c_s7_read_write_cotp_packet* message);
+plc4c_return_code plc4c_s7_read_write_cotp_packet_serialize(plc4c_spi_write_buffer* io, plc4c_s7_read_write_cotp_packet* message);
 
 uint16_t plc4c_s7_read_write_cotp_packet_length_in_bytes(plc4c_s7_read_write_cotp_packet* message);
 
diff --git a/sandbox/plc4c/generated-sources/s7/includes/cotp_parameter.h b/sandbox/plc4c/generated-sources/s7/include/cotp_parameter.h
similarity index 95%
rename from sandbox/plc4c/generated-sources/s7/includes/cotp_parameter.h
rename to sandbox/plc4c/generated-sources/s7/include/cotp_parameter.h
index 2759553..332edac 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/cotp_parameter.h
+++ b/sandbox/plc4c/generated-sources/s7/include/cotp_parameter.h
@@ -77,9 +77,9 @@
 // Create an empty NULL-struct
 plc4c_s7_read_write_cotp_parameter plc4c_s7_read_write_cotp_parameter_null();
 
-plc4c_return_code plc4c_s7_read_write_cotp_parameter_parse(plc4c_spi_read_buffer* buf, uint8_t rest, plc4c_s7_read_write_cotp_parameter** message);
+plc4c_return_code plc4c_s7_read_write_cotp_parameter_parse(plc4c_spi_read_buffer* io, uint8_t rest, plc4c_s7_read_write_cotp_parameter** message);
 
-plc4c_return_code plc4c_s7_read_write_cotp_parameter_serialize(plc4c_spi_write_buffer* buf, plc4c_s7_read_write_cotp_parameter* message);
+plc4c_return_code plc4c_s7_read_write_cotp_parameter_serialize(plc4c_spi_write_buffer* io, plc4c_s7_read_write_cotp_parameter* message);
 
 uint16_t plc4c_s7_read_write_cotp_parameter_length_in_bytes(plc4c_s7_read_write_cotp_parameter* message);
 
diff --git a/sandbox/plc4c/generated-sources/s7/includes/cotp_protocol_class.h b/sandbox/plc4c/generated-sources/s7/include/cotp_protocol_class.h
similarity index 85%
rename from sandbox/plc4c/generated-sources/s7/includes/cotp_protocol_class.h
rename to sandbox/plc4c/generated-sources/s7/include/cotp_protocol_class.h
index 2efcff7..fc3dca0 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/cotp_protocol_class.h
+++ b/sandbox/plc4c/generated-sources/s7/include/cotp_protocol_class.h
@@ -39,6 +39,11 @@
 // Get an empty NULL-struct
 plc4c_s7_read_write_cotp_protocol_class plc4c_s7_read_write_cotp_protocol_class_null();
 
+plc4c_s7_read_write_cotp_protocol_class plc4c_s7_read_write_cotp_protocol_class_value_of(char* value_string);
+
+int plc4c_s7_read_write_cotp_protocol_class_num_values();
+
+plc4c_s7_read_write_cotp_protocol_class plc4c_s7_read_write_cotp_protocol_class_value_for_index(int index);
 
 #ifdef __cplusplus
 }
diff --git a/sandbox/plc4c/generated-sources/s7/includes/cotp_tpdu_size.h b/sandbox/plc4c/generated-sources/s7/include/cotp_tpdu_size.h
similarity index 87%
rename from sandbox/plc4c/generated-sources/s7/includes/cotp_tpdu_size.h
rename to sandbox/plc4c/generated-sources/s7/include/cotp_tpdu_size.h
index 38f156d..6906a00 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/cotp_tpdu_size.h
+++ b/sandbox/plc4c/generated-sources/s7/include/cotp_tpdu_size.h
@@ -41,6 +41,11 @@
 // Get an empty NULL-struct
 plc4c_s7_read_write_cotp_tpdu_size plc4c_s7_read_write_cotp_tpdu_size_null();
 
+plc4c_s7_read_write_cotp_tpdu_size plc4c_s7_read_write_cotp_tpdu_size_value_of(char* value_string);
+
+int plc4c_s7_read_write_cotp_tpdu_size_num_values();
+
+plc4c_s7_read_write_cotp_tpdu_size plc4c_s7_read_write_cotp_tpdu_size_value_for_index(int index);
 
 uint16_t plc4c_s7_read_write_cotp_tpdu_size_get_size_in_bytes(plc4c_s7_read_write_cotp_tpdu_size value);
 
diff --git a/sandbox/plc4c/generated-sources/s7/include/data_item.h b/sandbox/plc4c/generated-sources/s7/include/data_item.h
new file mode 100644
index 0000000..a0a5fa6
--- /dev/null
+++ b/sandbox/plc4c/generated-sources/s7/include/data_item.h
@@ -0,0 +1,43 @@
+/*
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+*/
+#ifndef PLC4C_S7_READ_WRITE_DATA_ITEM_H_
+#define PLC4C_S7_READ_WRITE_DATA_ITEM_H_
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <plc4c/spi/read_buffer.h>
+#include <plc4c/spi/write_buffer.h>
+#include <plc4c/utils/list.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+plc4c_return_code plc4c_s7_read_write_data_item_parse(plc4c_spi_read_buffer* buf, uint8_t dataProtocolId, int32_t stringLength, plc4c_data** data_item);
+
+plc4c_return_code plc4c_s7_read_write_data_item_serialize(plc4c_spi_write_buffer* buf, plc4c_data** data_item);
+
+uint16_t plc4c_s7_read_write_data_item_length_in_bytes(plc4c_data* data_item);
+
+uint16_t plc4c_s7_read_write_data_item_length_in_bits(plc4c_data* data_item);
+
+#ifdef __cplusplus
+}
+#endif
+#endif  // PLC4C_S7_READ_WRITE_DATA_ITEM_H_
diff --git a/sandbox/plc4c/generated-sources/s7/includes/data_transport_error_code.h b/sandbox/plc4c/generated-sources/s7/include/data_transport_error_code.h
similarity index 85%
rename from sandbox/plc4c/generated-sources/s7/includes/data_transport_error_code.h
rename to sandbox/plc4c/generated-sources/s7/include/data_transport_error_code.h
index 94bc081..99eb0e2 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/data_transport_error_code.h
+++ b/sandbox/plc4c/generated-sources/s7/include/data_transport_error_code.h
@@ -40,6 +40,11 @@
 // Get an empty NULL-struct
 plc4c_s7_read_write_data_transport_error_code plc4c_s7_read_write_data_transport_error_code_null();
 
+plc4c_s7_read_write_data_transport_error_code plc4c_s7_read_write_data_transport_error_code_value_of(char* value_string);
+
+int plc4c_s7_read_write_data_transport_error_code_num_values();
+
+plc4c_s7_read_write_data_transport_error_code plc4c_s7_read_write_data_transport_error_code_value_for_index(int index);
 
 #ifdef __cplusplus
 }
diff --git a/sandbox/plc4c/generated-sources/s7/includes/data_transport_size.h b/sandbox/plc4c/generated-sources/s7/include/data_transport_size.h
similarity index 86%
rename from sandbox/plc4c/generated-sources/s7/includes/data_transport_size.h
rename to sandbox/plc4c/generated-sources/s7/include/data_transport_size.h
index cbfc150..4525b5b 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/data_transport_size.h
+++ b/sandbox/plc4c/generated-sources/s7/include/data_transport_size.h
@@ -41,6 +41,11 @@
 // Get an empty NULL-struct
 plc4c_s7_read_write_data_transport_size plc4c_s7_read_write_data_transport_size_null();
 
+plc4c_s7_read_write_data_transport_size plc4c_s7_read_write_data_transport_size_value_of(char* value_string);
+
+int plc4c_s7_read_write_data_transport_size_num_values();
+
+plc4c_s7_read_write_data_transport_size plc4c_s7_read_write_data_transport_size_value_for_index(int index);
 
 bool plc4c_s7_read_write_data_transport_size_get_size_in_bits(plc4c_s7_read_write_data_transport_size value);
 
diff --git a/sandbox/plc4c/generated-sources/s7/includes/device_group.h b/sandbox/plc4c/generated-sources/s7/include/device_group.h
similarity index 85%
rename from sandbox/plc4c/generated-sources/s7/includes/device_group.h
rename to sandbox/plc4c/generated-sources/s7/include/device_group.h
index 9f8af73..e55667e 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/device_group.h
+++ b/sandbox/plc4c/generated-sources/s7/include/device_group.h
@@ -37,6 +37,11 @@
 // Get an empty NULL-struct
 plc4c_s7_read_write_device_group plc4c_s7_read_write_device_group_null();
 
+plc4c_s7_read_write_device_group plc4c_s7_read_write_device_group_value_of(char* value_string);
+
+int plc4c_s7_read_write_device_group_num_values();
+
+plc4c_s7_read_write_device_group plc4c_s7_read_write_device_group_value_for_index(int index);
 
 #ifdef __cplusplus
 }
diff --git a/sandbox/plc4c/generated-sources/s7/includes/memory_area.h b/sandbox/plc4c/generated-sources/s7/include/memory_area.h
similarity index 88%
rename from sandbox/plc4c/generated-sources/s7/includes/memory_area.h
rename to sandbox/plc4c/generated-sources/s7/include/memory_area.h
index d172543..f6f357e 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/memory_area.h
+++ b/sandbox/plc4c/generated-sources/s7/include/memory_area.h
@@ -43,6 +43,11 @@
 // Get an empty NULL-struct
 plc4c_s7_read_write_memory_area plc4c_s7_read_write_memory_area_null();
 
+plc4c_s7_read_write_memory_area plc4c_s7_read_write_memory_area_value_of(char* value_string);
+
+int plc4c_s7_read_write_memory_area_num_values();
+
+plc4c_s7_read_write_memory_area plc4c_s7_read_write_memory_area_value_for_index(int index);
 
 char* plc4c_s7_read_write_memory_area_get_short_name(plc4c_s7_read_write_memory_area value);
 
diff --git a/sandbox/plc4c/generated-sources/s7/includes/s7_address.h b/sandbox/plc4c/generated-sources/s7/include/s7_address.h
similarity index 95%
rename from sandbox/plc4c/generated-sources/s7/includes/s7_address.h
rename to sandbox/plc4c/generated-sources/s7/include/s7_address.h
index ff51ecf..6dcad26 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/s7_address.h
+++ b/sandbox/plc4c/generated-sources/s7/include/s7_address.h
@@ -67,9 +67,9 @@
 // Create an empty NULL-struct
 plc4c_s7_read_write_s7_address plc4c_s7_read_write_s7_address_null();
 
-plc4c_return_code plc4c_s7_read_write_s7_address_parse(plc4c_spi_read_buffer* buf, plc4c_s7_read_write_s7_address** message);
+plc4c_return_code plc4c_s7_read_write_s7_address_parse(plc4c_spi_read_buffer* io, plc4c_s7_read_write_s7_address** message);
 
-plc4c_return_code plc4c_s7_read_write_s7_address_serialize(plc4c_spi_write_buffer* buf, plc4c_s7_read_write_s7_address* message);
+plc4c_return_code plc4c_s7_read_write_s7_address_serialize(plc4c_spi_write_buffer* io, plc4c_s7_read_write_s7_address* message);
 
 uint16_t plc4c_s7_read_write_s7_address_length_in_bytes(plc4c_s7_read_write_s7_address* message);
 
diff --git a/sandbox/plc4c/generated-sources/s7/includes/s7_message.h b/sandbox/plc4c/generated-sources/s7/include/s7_message.h
similarity index 96%
rename from sandbox/plc4c/generated-sources/s7/includes/s7_message.h
rename to sandbox/plc4c/generated-sources/s7/include/s7_message.h
index ce2d9c5..a27d8ff 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/s7_message.h
+++ b/sandbox/plc4c/generated-sources/s7/include/s7_message.h
@@ -81,9 +81,9 @@
 // Create an empty NULL-struct
 plc4c_s7_read_write_s7_message plc4c_s7_read_write_s7_message_null();
 
-plc4c_return_code plc4c_s7_read_write_s7_message_parse(plc4c_spi_read_buffer* buf, plc4c_s7_read_write_s7_message** message);
+plc4c_return_code plc4c_s7_read_write_s7_message_parse(plc4c_spi_read_buffer* io, plc4c_s7_read_write_s7_message** message);
 
-plc4c_return_code plc4c_s7_read_write_s7_message_serialize(plc4c_spi_write_buffer* buf, plc4c_s7_read_write_s7_message* message);
+plc4c_return_code plc4c_s7_read_write_s7_message_serialize(plc4c_spi_write_buffer* io, plc4c_s7_read_write_s7_message* message);
 
 uint16_t plc4c_s7_read_write_s7_message_length_in_bytes(plc4c_s7_read_write_s7_message* message);
 
diff --git a/sandbox/plc4c/generated-sources/s7/includes/s7_parameter.h b/sandbox/plc4c/generated-sources/s7/include/s7_parameter.h
similarity index 96%
rename from sandbox/plc4c/generated-sources/s7/includes/s7_parameter.h
rename to sandbox/plc4c/generated-sources/s7/include/s7_parameter.h
index 6f42b4f..d601ba0 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/s7_parameter.h
+++ b/sandbox/plc4c/generated-sources/s7/include/s7_parameter.h
@@ -85,9 +85,9 @@
 // Create an empty NULL-struct
 plc4c_s7_read_write_s7_parameter plc4c_s7_read_write_s7_parameter_null();
 
-plc4c_return_code plc4c_s7_read_write_s7_parameter_parse(plc4c_spi_read_buffer* buf, uint8_t messageType, plc4c_s7_read_write_s7_parameter** message);
+plc4c_return_code plc4c_s7_read_write_s7_parameter_parse(plc4c_spi_read_buffer* io, uint8_t messageType, plc4c_s7_read_write_s7_parameter** message);
 
-plc4c_return_code plc4c_s7_read_write_s7_parameter_serialize(plc4c_spi_write_buffer* buf, plc4c_s7_read_write_s7_parameter* message);
+plc4c_return_code plc4c_s7_read_write_s7_parameter_serialize(plc4c_spi_write_buffer* io, plc4c_s7_read_write_s7_parameter* message);
 
 uint16_t plc4c_s7_read_write_s7_parameter_length_in_bytes(plc4c_s7_read_write_s7_parameter* message);
 
diff --git a/sandbox/plc4c/generated-sources/s7/includes/s7_parameter_user_data_item.h b/sandbox/plc4c/generated-sources/s7/include/s7_parameter_user_data_item.h
similarity index 94%
rename from sandbox/plc4c/generated-sources/s7/includes/s7_parameter_user_data_item.h
rename to sandbox/plc4c/generated-sources/s7/include/s7_parameter_user_data_item.h
index a3a5481..b0114c3 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/s7_parameter_user_data_item.h
+++ b/sandbox/plc4c/generated-sources/s7/include/s7_parameter_user_data_item.h
@@ -67,9 +67,9 @@
 // Create an empty NULL-struct
 plc4c_s7_read_write_s7_parameter_user_data_item plc4c_s7_read_write_s7_parameter_user_data_item_null();
 
-plc4c_return_code plc4c_s7_read_write_s7_parameter_user_data_item_parse(plc4c_spi_read_buffer* buf, plc4c_s7_read_write_s7_parameter_user_data_item** message);
+plc4c_return_code plc4c_s7_read_write_s7_parameter_user_data_item_parse(plc4c_spi_read_buffer* io, plc4c_s7_read_write_s7_parameter_user_data_item** message);
 
-plc4c_return_code plc4c_s7_read_write_s7_parameter_user_data_item_serialize(plc4c_spi_write_buffer* buf, plc4c_s7_read_write_s7_parameter_user_data_item* message);
+plc4c_return_code plc4c_s7_read_write_s7_parameter_user_data_item_serialize(plc4c_spi_write_buffer* io, plc4c_s7_read_write_s7_parameter_user_data_item* message);
 
 uint16_t plc4c_s7_read_write_s7_parameter_user_data_item_length_in_bytes(plc4c_s7_read_write_s7_parameter_user_data_item* message);
 
diff --git a/sandbox/plc4c/generated-sources/s7/includes/s7_payload.h b/sandbox/plc4c/generated-sources/s7/include/s7_payload.h
similarity index 94%
rename from sandbox/plc4c/generated-sources/s7/includes/s7_payload.h
rename to sandbox/plc4c/generated-sources/s7/include/s7_payload.h
index 297e7ad..26291f4 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/s7_payload.h
+++ b/sandbox/plc4c/generated-sources/s7/include/s7_payload.h
@@ -77,9 +77,9 @@
 // Create an empty NULL-struct
 plc4c_s7_read_write_s7_payload plc4c_s7_read_write_s7_payload_null();
 
-plc4c_return_code plc4c_s7_read_write_s7_payload_parse(plc4c_spi_read_buffer* buf, uint8_t messageType, plc4c_s7_read_write_s7_parameter* parameter, plc4c_s7_read_write_s7_payload** message);
+plc4c_return_code plc4c_s7_read_write_s7_payload_parse(plc4c_spi_read_buffer* io, uint8_t messageType, plc4c_s7_read_write_s7_parameter* parameter, plc4c_s7_read_write_s7_payload** message);
 
-plc4c_return_code plc4c_s7_read_write_s7_payload_serialize(plc4c_spi_write_buffer* buf, plc4c_s7_read_write_s7_payload* message);
+plc4c_return_code plc4c_s7_read_write_s7_payload_serialize(plc4c_spi_write_buffer* io, plc4c_s7_read_write_s7_payload* message);
 
 uint16_t plc4c_s7_read_write_s7_payload_length_in_bytes(plc4c_s7_read_write_s7_payload* message);
 
diff --git a/sandbox/plc4c/generated-sources/s7/includes/s7_payload_user_data_item.h b/sandbox/plc4c/generated-sources/s7/include/s7_payload_user_data_item.h
similarity index 94%
rename from sandbox/plc4c/generated-sources/s7/includes/s7_payload_user_data_item.h
rename to sandbox/plc4c/generated-sources/s7/include/s7_payload_user_data_item.h
index 5900576..5bd980b 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/s7_payload_user_data_item.h
+++ b/sandbox/plc4c/generated-sources/s7/include/s7_payload_user_data_item.h
@@ -74,9 +74,9 @@
 // Create an empty NULL-struct
 plc4c_s7_read_write_s7_payload_user_data_item plc4c_s7_read_write_s7_payload_user_data_item_null();
 
-plc4c_return_code plc4c_s7_read_write_s7_payload_user_data_item_parse(plc4c_spi_read_buffer* buf, unsigned int cpuFunctionType, plc4c_s7_read_write_s7_payload_user_data_item** message);
+plc4c_return_code plc4c_s7_read_write_s7_payload_user_data_item_parse(plc4c_spi_read_buffer* io, unsigned int cpuFunctionType, plc4c_s7_read_write_s7_payload_user_data_item** message);
 
-plc4c_return_code plc4c_s7_read_write_s7_payload_user_data_item_serialize(plc4c_spi_write_buffer* buf, plc4c_s7_read_write_s7_payload_user_data_item* message);
+plc4c_return_code plc4c_s7_read_write_s7_payload_user_data_item_serialize(plc4c_spi_write_buffer* io, plc4c_s7_read_write_s7_payload_user_data_item* message);
 
 uint16_t plc4c_s7_read_write_s7_payload_user_data_item_length_in_bytes(plc4c_s7_read_write_s7_payload_user_data_item* message);
 
diff --git a/sandbox/plc4c/generated-sources/s7/includes/s7_var_payload_data_item.h b/sandbox/plc4c/generated-sources/s7/include/s7_var_payload_data_item.h
similarity index 90%
rename from sandbox/plc4c/generated-sources/s7/includes/s7_var_payload_data_item.h
rename to sandbox/plc4c/generated-sources/s7/include/s7_var_payload_data_item.h
index 6181a4c..a7497f1 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/s7_var_payload_data_item.h
+++ b/sandbox/plc4c/generated-sources/s7/include/s7_var_payload_data_item.h
@@ -43,9 +43,9 @@
 // Create an empty NULL-struct
 plc4c_s7_read_write_s7_var_payload_data_item plc4c_s7_read_write_s7_var_payload_data_item_null();
 
-plc4c_return_code plc4c_s7_read_write_s7_var_payload_data_item_parse(plc4c_spi_read_buffer* buf, bool lastItem, plc4c_s7_read_write_s7_var_payload_data_item** message);
+plc4c_return_code plc4c_s7_read_write_s7_var_payload_data_item_parse(plc4c_spi_read_buffer* io, bool lastItem, plc4c_s7_read_write_s7_var_payload_data_item** message);
 
-plc4c_return_code plc4c_s7_read_write_s7_var_payload_data_item_serialize(plc4c_spi_write_buffer* buf, plc4c_s7_read_write_s7_var_payload_data_item* message, bool lastItem);
+plc4c_return_code plc4c_s7_read_write_s7_var_payload_data_item_serialize(plc4c_spi_write_buffer* io, plc4c_s7_read_write_s7_var_payload_data_item* message, bool lastItem);
 
 uint16_t plc4c_s7_read_write_s7_var_payload_data_item_length_in_bytes(plc4c_s7_read_write_s7_var_payload_data_item* message);
 
diff --git a/sandbox/plc4c/generated-sources/s7/includes/s7_var_payload_status_item.h b/sandbox/plc4c/generated-sources/s7/include/s7_var_payload_status_item.h
similarity index 91%
rename from sandbox/plc4c/generated-sources/s7/includes/s7_var_payload_status_item.h
rename to sandbox/plc4c/generated-sources/s7/include/s7_var_payload_status_item.h
index a8b9dab..fd8573d 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/s7_var_payload_status_item.h
+++ b/sandbox/plc4c/generated-sources/s7/include/s7_var_payload_status_item.h
@@ -40,9 +40,9 @@
 // Create an empty NULL-struct
 plc4c_s7_read_write_s7_var_payload_status_item plc4c_s7_read_write_s7_var_payload_status_item_null();
 
-plc4c_return_code plc4c_s7_read_write_s7_var_payload_status_item_parse(plc4c_spi_read_buffer* buf, plc4c_s7_read_write_s7_var_payload_status_item** message);
+plc4c_return_code plc4c_s7_read_write_s7_var_payload_status_item_parse(plc4c_spi_read_buffer* io, plc4c_s7_read_write_s7_var_payload_status_item** message);
 
-plc4c_return_code plc4c_s7_read_write_s7_var_payload_status_item_serialize(plc4c_spi_write_buffer* buf, plc4c_s7_read_write_s7_var_payload_status_item* message);
+plc4c_return_code plc4c_s7_read_write_s7_var_payload_status_item_serialize(plc4c_spi_write_buffer* io, plc4c_s7_read_write_s7_var_payload_status_item* message);
 
 uint16_t plc4c_s7_read_write_s7_var_payload_status_item_length_in_bytes(plc4c_s7_read_write_s7_var_payload_status_item* message);
 
diff --git a/sandbox/plc4c/generated-sources/s7/includes/s7_var_request_parameter_item.h b/sandbox/plc4c/generated-sources/s7/include/s7_var_request_parameter_item.h
similarity index 93%
rename from sandbox/plc4c/generated-sources/s7/includes/s7_var_request_parameter_item.h
rename to sandbox/plc4c/generated-sources/s7/include/s7_var_request_parameter_item.h
index 9e3a4e1..102c330 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/s7_var_request_parameter_item.h
+++ b/sandbox/plc4c/generated-sources/s7/include/s7_var_request_parameter_item.h
@@ -61,9 +61,9 @@
 // Create an empty NULL-struct
 plc4c_s7_read_write_s7_var_request_parameter_item plc4c_s7_read_write_s7_var_request_parameter_item_null();
 
-plc4c_return_code plc4c_s7_read_write_s7_var_request_parameter_item_parse(plc4c_spi_read_buffer* buf, plc4c_s7_read_write_s7_var_request_parameter_item** message);
+plc4c_return_code plc4c_s7_read_write_s7_var_request_parameter_item_parse(plc4c_spi_read_buffer* io, plc4c_s7_read_write_s7_var_request_parameter_item** message);
 
-plc4c_return_code plc4c_s7_read_write_s7_var_request_parameter_item_serialize(plc4c_spi_write_buffer* buf, plc4c_s7_read_write_s7_var_request_parameter_item* message);
+plc4c_return_code plc4c_s7_read_write_s7_var_request_parameter_item_serialize(plc4c_spi_write_buffer* io, plc4c_s7_read_write_s7_var_request_parameter_item* message);
 
 uint16_t plc4c_s7_read_write_s7_var_request_parameter_item_length_in_bytes(plc4c_s7_read_write_s7_var_request_parameter_item* message);
 
diff --git a/sandbox/plc4c/generated-sources/s7/includes/szl_data_tree_item.h b/sandbox/plc4c/generated-sources/s7/include/szl_data_tree_item.h
similarity index 92%
rename from sandbox/plc4c/generated-sources/s7/includes/szl_data_tree_item.h
rename to sandbox/plc4c/generated-sources/s7/include/szl_data_tree_item.h
index eff888d..9213328 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/szl_data_tree_item.h
+++ b/sandbox/plc4c/generated-sources/s7/include/szl_data_tree_item.h
@@ -43,9 +43,9 @@
 // Create an empty NULL-struct
 plc4c_s7_read_write_szl_data_tree_item plc4c_s7_read_write_szl_data_tree_item_null();
 
-plc4c_return_code plc4c_s7_read_write_szl_data_tree_item_parse(plc4c_spi_read_buffer* buf, plc4c_s7_read_write_szl_data_tree_item** message);
+plc4c_return_code plc4c_s7_read_write_szl_data_tree_item_parse(plc4c_spi_read_buffer* io, plc4c_s7_read_write_szl_data_tree_item** message);
 
-plc4c_return_code plc4c_s7_read_write_szl_data_tree_item_serialize(plc4c_spi_write_buffer* buf, plc4c_s7_read_write_szl_data_tree_item* message);
+plc4c_return_code plc4c_s7_read_write_szl_data_tree_item_serialize(plc4c_spi_write_buffer* io, plc4c_s7_read_write_szl_data_tree_item* message);
 
 uint16_t plc4c_s7_read_write_szl_data_tree_item_length_in_bytes(plc4c_s7_read_write_szl_data_tree_item* message);
 
diff --git a/sandbox/plc4c/generated-sources/s7/includes/szl_id.h b/sandbox/plc4c/generated-sources/s7/include/szl_id.h
similarity index 94%
rename from sandbox/plc4c/generated-sources/s7/includes/szl_id.h
rename to sandbox/plc4c/generated-sources/s7/include/szl_id.h
index d885067..db0486b 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/szl_id.h
+++ b/sandbox/plc4c/generated-sources/s7/include/szl_id.h
@@ -43,9 +43,9 @@
 // Create an empty NULL-struct
 plc4c_s7_read_write_szl_id plc4c_s7_read_write_szl_id_null();
 
-plc4c_return_code plc4c_s7_read_write_szl_id_parse(plc4c_spi_read_buffer* buf, plc4c_s7_read_write_szl_id** message);
+plc4c_return_code plc4c_s7_read_write_szl_id_parse(plc4c_spi_read_buffer* io, plc4c_s7_read_write_szl_id** message);
 
-plc4c_return_code plc4c_s7_read_write_szl_id_serialize(plc4c_spi_write_buffer* buf, plc4c_s7_read_write_szl_id* message);
+plc4c_return_code plc4c_s7_read_write_szl_id_serialize(plc4c_spi_write_buffer* io, plc4c_s7_read_write_szl_id* message);
 
 uint16_t plc4c_s7_read_write_szl_id_length_in_bytes(plc4c_s7_read_write_szl_id* message);
 
diff --git a/sandbox/plc4c/generated-sources/s7/includes/szl_module_type_class.h b/sandbox/plc4c/generated-sources/s7/include/szl_module_type_class.h
similarity index 84%
rename from sandbox/plc4c/generated-sources/s7/includes/szl_module_type_class.h
rename to sandbox/plc4c/generated-sources/s7/include/szl_module_type_class.h
index 0af468c..0e45c23 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/szl_module_type_class.h
+++ b/sandbox/plc4c/generated-sources/s7/include/szl_module_type_class.h
@@ -38,6 +38,11 @@
 // Get an empty NULL-struct
 plc4c_s7_read_write_szl_module_type_class plc4c_s7_read_write_szl_module_type_class_null();
 
+plc4c_s7_read_write_szl_module_type_class plc4c_s7_read_write_szl_module_type_class_value_of(char* value_string);
+
+int plc4c_s7_read_write_szl_module_type_class_num_values();
+
+plc4c_s7_read_write_szl_module_type_class plc4c_s7_read_write_szl_module_type_class_value_for_index(int index);
 
 #ifdef __cplusplus
 }
diff --git a/sandbox/plc4c/generated-sources/s7/includes/szl_sublist.h b/sandbox/plc4c/generated-sources/s7/include/szl_sublist.h
similarity index 91%
rename from sandbox/plc4c/generated-sources/s7/includes/szl_sublist.h
rename to sandbox/plc4c/generated-sources/s7/include/szl_sublist.h
index 4aa623e..1bdd96e 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/szl_sublist.h
+++ b/sandbox/plc4c/generated-sources/s7/include/szl_sublist.h
@@ -53,6 +53,11 @@
 // Get an empty NULL-struct
 plc4c_s7_read_write_szl_sublist plc4c_s7_read_write_szl_sublist_null();
 
+plc4c_s7_read_write_szl_sublist plc4c_s7_read_write_szl_sublist_value_of(char* value_string);
+
+int plc4c_s7_read_write_szl_sublist_num_values();
+
+plc4c_s7_read_write_szl_sublist plc4c_s7_read_write_szl_sublist_value_for_index(int index);
 
 #ifdef __cplusplus
 }
diff --git a/sandbox/plc4c/generated-sources/s7/includes/tpkt_packet.h b/sandbox/plc4c/generated-sources/s7/include/tpkt_packet.h
similarity index 93%
rename from sandbox/plc4c/generated-sources/s7/includes/tpkt_packet.h
rename to sandbox/plc4c/generated-sources/s7/include/tpkt_packet.h
index 34677c9..b11f507 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/tpkt_packet.h
+++ b/sandbox/plc4c/generated-sources/s7/include/tpkt_packet.h
@@ -44,9 +44,9 @@
 // Create an empty NULL-struct
 plc4c_s7_read_write_tpkt_packet plc4c_s7_read_write_tpkt_packet_null();
 
-plc4c_return_code plc4c_s7_read_write_tpkt_packet_parse(plc4c_spi_read_buffer* buf, plc4c_s7_read_write_tpkt_packet** message);
+plc4c_return_code plc4c_s7_read_write_tpkt_packet_parse(plc4c_spi_read_buffer* io, plc4c_s7_read_write_tpkt_packet** message);
 
-plc4c_return_code plc4c_s7_read_write_tpkt_packet_serialize(plc4c_spi_write_buffer* buf, plc4c_s7_read_write_tpkt_packet* message);
+plc4c_return_code plc4c_s7_read_write_tpkt_packet_serialize(plc4c_spi_write_buffer* io, plc4c_s7_read_write_tpkt_packet* message);
 
 uint16_t plc4c_s7_read_write_tpkt_packet_length_in_bytes(plc4c_s7_read_write_tpkt_packet* message);
 
diff --git a/sandbox/plc4c/generated-sources/s7/includes/transport_size.h b/sandbox/plc4c/generated-sources/s7/include/transport_size.h
similarity index 93%
rename from sandbox/plc4c/generated-sources/s7/includes/transport_size.h
rename to sandbox/plc4c/generated-sources/s7/include/transport_size.h
index 0991f54..9679277 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/transport_size.h
+++ b/sandbox/plc4c/generated-sources/s7/include/transport_size.h
@@ -61,6 +61,11 @@
 // Get an empty NULL-struct
 plc4c_s7_read_write_transport_size plc4c_s7_read_write_transport_size_null();
 
+plc4c_s7_read_write_transport_size plc4c_s7_read_write_transport_size_value_of(char* value_string);
+
+int plc4c_s7_read_write_transport_size_num_values();
+
+plc4c_s7_read_write_transport_size plc4c_s7_read_write_transport_size_value_for_index(int index);
 
 bool plc4c_s7_read_write_transport_size_get_supported__s7_300(plc4c_s7_read_write_transport_size value);
 
diff --git a/sandbox/plc4c/generated-sources/s7/src/cotp_packet.c b/sandbox/plc4c/generated-sources/s7/src/cotp_packet.c
index 3238c58..54684b0 100644
--- a/sandbox/plc4c/generated-sources/s7/src/cotp_packet.c
+++ b/sandbox/plc4c/generated-sources/s7/src/cotp_packet.c
@@ -53,8 +53,8 @@
 
 
 // Parse function.
-plc4c_return_code plc4c_s7_read_write_cotp_packet_parse(plc4c_spi_read_buffer* buf, uint16_t cotpLen, plc4c_s7_read_write_cotp_packet** _message) {
-  uint16_t startPos = plc4c_spi_read_get_pos(buf);
+plc4c_return_code plc4c_s7_read_write_cotp_packet_parse(plc4c_spi_read_buffer* io, uint16_t cotpLen, plc4c_s7_read_write_cotp_packet** _message) {
+  uint16_t startPos = plc4c_spi_read_get_pos(io);
   uint16_t curPos;
   plc4c_return_code _res = OK;
 
@@ -66,14 +66,14 @@
 
   // Implicit Field (headerLength) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
   uint8_t headerLength = 0;
-  _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &headerLength);
+  _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &headerLength);
   if(_res != OK) {
     return _res;
   }
 
   // Discriminator Field (tpduCode) (Used as input to a switch field)
   uint8_t tpduCode = 0;
-  _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &tpduCode);
+  _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &tpduCode);
   if(_res != OK) {
     return _res;
   }
@@ -84,7 +84,7 @@
                     
     // Simple Field (eot)
     bool eot = false;
-    _res = plc4c_spi_read_bit(buf, (bool*) &eot);
+    _res = plc4c_spi_read_bit(io, (bool*) &eot);
     if(_res != OK) {
       return _res;
     }
@@ -94,7 +94,7 @@
                     
     // Simple Field (tpduRef)
     unsigned int tpduRef = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 7, (uint8_t*) &tpduRef);
+    _res = plc4c_spi_read_unsigned_byte(io, 7, (uint8_t*) &tpduRef);
     if(_res != OK) {
       return _res;
     }
@@ -106,7 +106,7 @@
                     
     // Simple Field (destinationReference)
     uint16_t destinationReference = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &destinationReference);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &destinationReference);
     if(_res != OK) {
       return _res;
     }
@@ -116,7 +116,7 @@
                     
     // Simple Field (sourceReference)
     uint16_t sourceReference = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &sourceReference);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &sourceReference);
     if(_res != OK) {
       return _res;
     }
@@ -126,7 +126,7 @@
                     
     // Enum field (protocolClass)
     plc4c_s7_read_write_cotp_protocol_class protocolClass = plc4c_s7_read_write_cotp_protocol_class_null();
-    _res = plc4c_spi_read_signed_byte(buf, 8, (int8_t*) &protocolClass);
+    _res = plc4c_spi_read_signed_byte(io, 8, (int8_t*) &protocolClass);
     if(_res != OK) {
       return _res;
     }
@@ -138,7 +138,7 @@
                     
     // Simple Field (destinationReference)
     uint16_t destinationReference = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &destinationReference);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &destinationReference);
     if(_res != OK) {
       return _res;
     }
@@ -148,7 +148,7 @@
                     
     // Simple Field (sourceReference)
     uint16_t sourceReference = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &sourceReference);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &sourceReference);
     if(_res != OK) {
       return _res;
     }
@@ -158,7 +158,7 @@
                     
     // Enum field (protocolClass)
     plc4c_s7_read_write_cotp_protocol_class protocolClass = plc4c_s7_read_write_cotp_protocol_class_null();
-    _res = plc4c_spi_read_signed_byte(buf, 8, (int8_t*) &protocolClass);
+    _res = plc4c_spi_read_signed_byte(io, 8, (int8_t*) &protocolClass);
     if(_res != OK) {
       return _res;
     }
@@ -170,7 +170,7 @@
                     
     // Simple Field (destinationReference)
     uint16_t destinationReference = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &destinationReference);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &destinationReference);
     if(_res != OK) {
       return _res;
     }
@@ -180,7 +180,7 @@
                     
     // Simple Field (sourceReference)
     uint16_t sourceReference = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &sourceReference);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &sourceReference);
     if(_res != OK) {
       return _res;
     }
@@ -190,7 +190,7 @@
                     
     // Enum field (protocolClass)
     plc4c_s7_read_write_cotp_protocol_class protocolClass = plc4c_s7_read_write_cotp_protocol_class_null();
-    _res = plc4c_spi_read_signed_byte(buf, 8, (int8_t*) &protocolClass);
+    _res = plc4c_spi_read_signed_byte(io, 8, (int8_t*) &protocolClass);
     if(_res != OK) {
       return _res;
     }
@@ -202,7 +202,7 @@
                     
     // Simple Field (destinationReference)
     uint16_t destinationReference = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &destinationReference);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &destinationReference);
     if(_res != OK) {
       return _res;
     }
@@ -212,7 +212,7 @@
                     
     // Simple Field (sourceReference)
     uint16_t sourceReference = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &sourceReference);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &sourceReference);
     if(_res != OK) {
       return _res;
     }
@@ -224,7 +224,7 @@
                     
     // Simple Field (destinationReference)
     uint16_t destinationReference = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &destinationReference);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &destinationReference);
     if(_res != OK) {
       return _res;
     }
@@ -234,7 +234,7 @@
                     
     // Simple Field (rejectCause)
     uint8_t rejectCause = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &rejectCause);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &rejectCause);
     if(_res != OK) {
       return _res;
     }
@@ -243,7 +243,7 @@
   }
 
   // Array field (parameters)
-  curPos = plc4c_spi_read_get_pos(buf) - startPos;
+  curPos = plc4c_spi_read_get_pos(io) - startPos;
   plc4c_list* parameters = NULL;
   plc4c_utils_list_create(&parameters);
   if(parameters == NULL) {
@@ -252,28 +252,28 @@
   {
     // Length array
     uint8_t _parametersLength = (((headerLength) + (1))) - (curPos);
-    uint8_t parametersEndPos = plc4c_spi_read_get_pos(buf) + _parametersLength;
-    while(plc4c_spi_read_get_pos(buf) < parametersEndPos) {
-      plc4c_list* _value = NULL;
-      _res = plc4c_s7_read_write_cotp_parameter_parse(buf, (((headerLength) + (1))) - (curPos), (void*) &_value);
+    uint8_t parametersEndPos = plc4c_spi_read_get_pos(io) + _parametersLength;
+    while(plc4c_spi_read_get_pos(io) < parametersEndPos) {
+      plc4c_s7_read_write_cotp_parameter* _value = NULL;
+      _res = plc4c_s7_read_write_cotp_parameter_parse(io, (((headerLength) + (1))) - (curPos), (void*) &_value);
       if(_res != OK) {
         return _res;
       }
       plc4c_utils_list_insert_head_value(parameters, _value);
-      curPos = plc4c_spi_read_get_pos(buf) - startPos;
+      curPos = plc4c_spi_read_get_pos(io) - startPos;
     }
   }
   (*_message)->parameters = parameters;
 
   // Optional Field (payload) (Can be skipped, if a given expression evaluates to false)
-  curPos = plc4c_spi_read_get_pos(buf) - startPos;
+  curPos = plc4c_spi_read_get_pos(io) - startPos;
   plc4c_s7_read_write_s7_message* payload = NULL;
   if((curPos) < (cotpLen)) {
     payload = malloc(sizeof(plc4c_s7_read_write_s7_message));
     if(payload == NULL) {
       return NO_MEMORY;
     }
-    _res = plc4c_s7_read_write_s7_message_parse(buf, &payload);
+    _res = plc4c_s7_read_write_s7_message_parse(io, &payload);
     if(_res != OK) {
       return _res;
     }
@@ -285,30 +285,30 @@
   return OK;
 }
 
-plc4c_return_code plc4c_s7_read_write_cotp_packet_serialize(plc4c_spi_write_buffer* buf, plc4c_s7_read_write_cotp_packet* _message) {
+plc4c_return_code plc4c_s7_read_write_cotp_packet_serialize(plc4c_spi_write_buffer* io, plc4c_s7_read_write_cotp_packet* _message) {
   plc4c_return_code _res = OK;
 
   // Implicit Field (headerLength) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-  _res = plc4c_spi_write_unsigned_byte(buf, 8, (plc4c_s7_read_write_cotp_packet_length_in_bytes(_message)) - ((((((((_message->payload) != (NULL))) ? plc4c_s7_read_write_s7_message_length_in_bytes(_message->payload) : 0))) + (1))));
+  _res = plc4c_spi_write_unsigned_byte(io, 8, (plc4c_s7_read_write_cotp_packet_length_in_bytes(_message)) - ((((((((_message->payload) != (NULL))) ? plc4c_s7_read_write_s7_message_length_in_bytes(_message->payload) : 0))) + (1))));
   if(_res != OK) {
     return _res;
   }
 
   // Discriminator Field (tpduCode)
-  plc4c_spi_write_unsigned_byte(buf, 8, plc4c_s7_read_write_cotp_packet_get_discriminator(_message->_type).tpduCode);
+  plc4c_spi_write_unsigned_byte(io, 8, plc4c_s7_read_write_cotp_packet_get_discriminator(_message->_type).tpduCode);
 
   // Switch Field (Depending of the current type, serialize the sub-type elements)
   switch(_message->_type) {
     case plc4c_s7_read_write_cotp_packet_type_plc4c_s7_read_write_cotp_packet_data: {
 
       // Simple Field (eot)
-      _res = plc4c_spi_write_bit(buf, _message->cotp_packet_data_eot);
+      _res = plc4c_spi_write_bit(io, _message->cotp_packet_data_eot);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (tpduRef)
-      _res = plc4c_spi_write_unsigned_byte(buf, 7, _message->cotp_packet_data_tpdu_ref);
+      _res = plc4c_spi_write_unsigned_byte(io, 7, _message->cotp_packet_data_tpdu_ref);
       if(_res != OK) {
         return _res;
       }
@@ -318,19 +318,19 @@
     case plc4c_s7_read_write_cotp_packet_type_plc4c_s7_read_write_cotp_packet_connection_request: {
 
       // Simple Field (destinationReference)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->cotp_packet_connection_request_destination_reference);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->cotp_packet_connection_request_destination_reference);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (sourceReference)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->cotp_packet_connection_request_source_reference);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->cotp_packet_connection_request_source_reference);
       if(_res != OK) {
         return _res;
       }
 
       // Enum field (protocolClass)
-      _res = plc4c_spi_write_signed_byte(buf, 8, _message->cotp_packet_connection_request_protocol_class);
+      _res = plc4c_spi_write_signed_byte(io, 8, _message->cotp_packet_connection_request_protocol_class);
       if(_res != OK) {
         return _res;
       }
@@ -340,19 +340,19 @@
     case plc4c_s7_read_write_cotp_packet_type_plc4c_s7_read_write_cotp_packet_connection_response: {
 
       // Simple Field (destinationReference)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->cotp_packet_connection_response_destination_reference);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->cotp_packet_connection_response_destination_reference);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (sourceReference)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->cotp_packet_connection_response_source_reference);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->cotp_packet_connection_response_source_reference);
       if(_res != OK) {
         return _res;
       }
 
       // Enum field (protocolClass)
-      _res = plc4c_spi_write_signed_byte(buf, 8, _message->cotp_packet_connection_response_protocol_class);
+      _res = plc4c_spi_write_signed_byte(io, 8, _message->cotp_packet_connection_response_protocol_class);
       if(_res != OK) {
         return _res;
       }
@@ -362,19 +362,19 @@
     case plc4c_s7_read_write_cotp_packet_type_plc4c_s7_read_write_cotp_packet_disconnect_request: {
 
       // Simple Field (destinationReference)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->cotp_packet_disconnect_request_destination_reference);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->cotp_packet_disconnect_request_destination_reference);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (sourceReference)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->cotp_packet_disconnect_request_source_reference);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->cotp_packet_disconnect_request_source_reference);
       if(_res != OK) {
         return _res;
       }
 
       // Enum field (protocolClass)
-      _res = plc4c_spi_write_signed_byte(buf, 8, _message->cotp_packet_disconnect_request_protocol_class);
+      _res = plc4c_spi_write_signed_byte(io, 8, _message->cotp_packet_disconnect_request_protocol_class);
       if(_res != OK) {
         return _res;
       }
@@ -384,13 +384,13 @@
     case plc4c_s7_read_write_cotp_packet_type_plc4c_s7_read_write_cotp_packet_disconnect_response: {
 
       // Simple Field (destinationReference)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->cotp_packet_disconnect_response_destination_reference);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->cotp_packet_disconnect_response_destination_reference);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (sourceReference)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->cotp_packet_disconnect_response_source_reference);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->cotp_packet_disconnect_response_source_reference);
       if(_res != OK) {
         return _res;
       }
@@ -400,13 +400,13 @@
     case plc4c_s7_read_write_cotp_packet_type_plc4c_s7_read_write_cotp_packet_tpdu_error: {
 
       // Simple Field (destinationReference)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->cotp_packet_tpdu_error_destination_reference);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->cotp_packet_tpdu_error_destination_reference);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (rejectCause)
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, _message->cotp_packet_tpdu_error_reject_cause);
+      _res = plc4c_spi_write_unsigned_byte(io, 8, _message->cotp_packet_tpdu_error_reject_cause);
       if(_res != OK) {
         return _res;
       }
@@ -421,7 +421,7 @@
     for(int curItem = 0; curItem < itemCount; curItem++) {
       bool lastItem = curItem == (itemCount - 1);
       plc4c_s7_read_write_cotp_parameter* _value = (plc4c_s7_read_write_cotp_parameter*) plc4c_utils_list_get_value(_message->parameters, curItem);
-      _res = plc4c_s7_read_write_cotp_parameter_serialize(buf, (void*) _value);
+      _res = plc4c_s7_read_write_cotp_parameter_serialize(io, (void*) _value);
       if(_res != OK) {
         return _res;
       }
@@ -430,7 +430,7 @@
 
   // Optional Field (payload)
   if(_message->payload != NULL) {
-    _res = plc4c_s7_read_write_s7_message_serialize(buf, _message->payload);
+    _res = plc4c_s7_read_write_s7_message_serialize(io, _message->payload);
     if(_res != OK) {
       return _res;
     }
diff --git a/sandbox/plc4c/generated-sources/s7/src/cotp_parameter.c b/sandbox/plc4c/generated-sources/s7/src/cotp_parameter.c
index ce38827..88057b2 100644
--- a/sandbox/plc4c/generated-sources/s7/src/cotp_parameter.c
+++ b/sandbox/plc4c/generated-sources/s7/src/cotp_parameter.c
@@ -51,8 +51,8 @@
 
 
 // Parse function.
-plc4c_return_code plc4c_s7_read_write_cotp_parameter_parse(plc4c_spi_read_buffer* buf, uint8_t rest, plc4c_s7_read_write_cotp_parameter** _message) {
-  uint16_t startPos = plc4c_spi_read_get_pos(buf);
+plc4c_return_code plc4c_s7_read_write_cotp_parameter_parse(plc4c_spi_read_buffer* io, uint8_t rest, plc4c_s7_read_write_cotp_parameter** _message) {
+  uint16_t startPos = plc4c_spi_read_get_pos(io);
   uint16_t curPos;
   plc4c_return_code _res = OK;
 
@@ -64,14 +64,14 @@
 
   // Discriminator Field (parameterType) (Used as input to a switch field)
   uint8_t parameterType = 0;
-  _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &parameterType);
+  _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &parameterType);
   if(_res != OK) {
     return _res;
   }
 
   // Implicit Field (parameterLength) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
   uint8_t parameterLength = 0;
-  _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &parameterLength);
+  _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &parameterLength);
   if(_res != OK) {
     return _res;
   }
@@ -82,7 +82,7 @@
                     
     // Enum field (tpduSize)
     plc4c_s7_read_write_cotp_tpdu_size tpduSize = plc4c_s7_read_write_cotp_tpdu_size_null();
-    _res = plc4c_spi_read_signed_byte(buf, 8, (int8_t*) &tpduSize);
+    _res = plc4c_spi_read_signed_byte(io, 8, (int8_t*) &tpduSize);
     if(_res != OK) {
       return _res;
     }
@@ -94,7 +94,7 @@
                     
     // Simple Field (tsapId)
     uint16_t tsapId = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &tsapId);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &tsapId);
     if(_res != OK) {
       return _res;
     }
@@ -106,7 +106,7 @@
                     
     // Simple Field (tsapId)
     uint16_t tsapId = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &tsapId);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &tsapId);
     if(_res != OK) {
       return _res;
     }
@@ -118,7 +118,7 @@
                     
     // Simple Field (crc)
     uint8_t crc = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &crc);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &crc);
     if(_res != OK) {
       return _res;
     }
@@ -139,9 +139,8 @@
       uint8_t itemCount = rest;
       for(int curItem = 0; curItem < itemCount; curItem++) {
         
-                  
         uint8_t* _value = malloc(sizeof(uint8_t));
-        _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) _value);
+        _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) _value);
         if(_res != OK) {
           return _res;
         }
@@ -155,14 +154,14 @@
   return OK;
 }
 
-plc4c_return_code plc4c_s7_read_write_cotp_parameter_serialize(plc4c_spi_write_buffer* buf, plc4c_s7_read_write_cotp_parameter* _message) {
+plc4c_return_code plc4c_s7_read_write_cotp_parameter_serialize(plc4c_spi_write_buffer* io, plc4c_s7_read_write_cotp_parameter* _message) {
   plc4c_return_code _res = OK;
 
   // Discriminator Field (parameterType)
-  plc4c_spi_write_unsigned_byte(buf, 8, plc4c_s7_read_write_cotp_parameter_get_discriminator(_message->_type).parameterType);
+  plc4c_spi_write_unsigned_byte(io, 8, plc4c_s7_read_write_cotp_parameter_get_discriminator(_message->_type).parameterType);
 
   // Implicit Field (parameterLength) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-  _res = plc4c_spi_write_unsigned_byte(buf, 8, (plc4c_s7_read_write_cotp_parameter_length_in_bytes(_message)) - (2));
+  _res = plc4c_spi_write_unsigned_byte(io, 8, (plc4c_s7_read_write_cotp_parameter_length_in_bytes(_message)) - (2));
   if(_res != OK) {
     return _res;
   }
@@ -172,7 +171,7 @@
     case plc4c_s7_read_write_cotp_parameter_type_plc4c_s7_read_write_cotp_parameter_tpdu_size: {
 
       // Enum field (tpduSize)
-      _res = plc4c_spi_write_signed_byte(buf, 8, _message->cotp_parameter_tpdu_size_tpdu_size);
+      _res = plc4c_spi_write_signed_byte(io, 8, _message->cotp_parameter_tpdu_size_tpdu_size);
       if(_res != OK) {
         return _res;
       }
@@ -182,7 +181,7 @@
     case plc4c_s7_read_write_cotp_parameter_type_plc4c_s7_read_write_cotp_parameter_calling_tsap: {
 
       // Simple Field (tsapId)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->cotp_parameter_calling_tsap_tsap_id);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->cotp_parameter_calling_tsap_tsap_id);
       if(_res != OK) {
         return _res;
       }
@@ -192,7 +191,7 @@
     case plc4c_s7_read_write_cotp_parameter_type_plc4c_s7_read_write_cotp_parameter_called_tsap: {
 
       // Simple Field (tsapId)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->cotp_parameter_called_tsap_tsap_id);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->cotp_parameter_called_tsap_tsap_id);
       if(_res != OK) {
         return _res;
       }
@@ -202,7 +201,7 @@
     case plc4c_s7_read_write_cotp_parameter_type_plc4c_s7_read_write_cotp_parameter_checksum: {
 
       // Simple Field (crc)
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, _message->cotp_parameter_checksum_crc);
+      _res = plc4c_spi_write_unsigned_byte(io, 8, _message->cotp_parameter_checksum_crc);
       if(_res != OK) {
         return _res;
       }
@@ -217,7 +216,7 @@
         for(int curItem = 0; curItem < itemCount; curItem++) {
 
           uint8_t* _value = (uint8_t*) plc4c_utils_list_get_value(_message->cotp_parameter_disconnect_additional_information_data, curItem);
-          plc4c_spi_write_unsigned_byte(buf, 8, *_value);
+          plc4c_spi_write_unsigned_byte(io, 8, *_value);
         }
       }
 
diff --git a/sandbox/plc4c/generated-sources/s7/src/cotp_protocol_class.c b/sandbox/plc4c/generated-sources/s7/src/cotp_protocol_class.c
index 4f46d34..771d486 100644
--- a/sandbox/plc4c/generated-sources/s7/src/cotp_protocol_class.c
+++ b/sandbox/plc4c/generated-sources/s7/src/cotp_protocol_class.c
@@ -18,6 +18,7 @@
 */
 
 #include "cotp_protocol_class.h"
+#include <string.h>
 
 
 // Create an empty NULL-struct
@@ -27,3 +28,48 @@
   return plc4c_s7_read_write_cotp_protocol_class_null_const;
 }
 
+plc4c_s7_read_write_cotp_protocol_class plc4c_s7_read_write_cotp_protocol_class_value_of(char* value_string) {
+    if(strcmp(value_string, "CLASS_0") == 0) {
+        return 0x00;
+    }
+    if(strcmp(value_string, "CLASS_1") == 0) {
+        return 0x10;
+    }
+    if(strcmp(value_string, "CLASS_2") == 0) {
+        return 0x20;
+    }
+    if(strcmp(value_string, "CLASS_3") == 0) {
+        return 0x30;
+    }
+    if(strcmp(value_string, "CLASS_4") == 0) {
+        return 0x40;
+    }
+    return -1;
+}
+
+int plc4c_s7_read_write_cotp_protocol_class_num_values() {
+  return 5;
+}
+
+plc4c_s7_read_write_cotp_protocol_class plc4c_s7_read_write_cotp_protocol_class_value_for_index(int index) {
+    switch(index) {
+      case 0: {
+        return 0x00;
+      }
+      case 1: {
+        return 0x10;
+      }
+      case 2: {
+        return 0x20;
+      }
+      case 3: {
+        return 0x30;
+      }
+      case 4: {
+        return 0x40;
+      }
+      default: {
+        return -1;
+      }
+    }
+}
diff --git a/sandbox/plc4c/generated-sources/s7/src/cotp_tpdu_size.c b/sandbox/plc4c/generated-sources/s7/src/cotp_tpdu_size.c
index b6cfa78..7d78bf8 100644
--- a/sandbox/plc4c/generated-sources/s7/src/cotp_tpdu_size.c
+++ b/sandbox/plc4c/generated-sources/s7/src/cotp_tpdu_size.c
@@ -18,6 +18,7 @@
 */
 
 #include "cotp_tpdu_size.h"
+#include <string.h>
 
 
 // Create an empty NULL-struct
@@ -27,6 +28,63 @@
   return plc4c_s7_read_write_cotp_tpdu_size_null_const;
 }
 
+plc4c_s7_read_write_cotp_tpdu_size plc4c_s7_read_write_cotp_tpdu_size_value_of(char* value_string) {
+    if(strcmp(value_string, "SIZE_128") == 0) {
+        return 0x07;
+    }
+    if(strcmp(value_string, "SIZE_256") == 0) {
+        return 0x08;
+    }
+    if(strcmp(value_string, "SIZE_512") == 0) {
+        return 0x09;
+    }
+    if(strcmp(value_string, "SIZE_1024") == 0) {
+        return 0x0a;
+    }
+    if(strcmp(value_string, "SIZE_2048") == 0) {
+        return 0x0b;
+    }
+    if(strcmp(value_string, "SIZE_4096") == 0) {
+        return 0x0c;
+    }
+    if(strcmp(value_string, "SIZE_8192") == 0) {
+        return 0x0d;
+    }
+    return -1;
+}
+
+int plc4c_s7_read_write_cotp_tpdu_size_num_values() {
+  return 7;
+}
+
+plc4c_s7_read_write_cotp_tpdu_size plc4c_s7_read_write_cotp_tpdu_size_value_for_index(int index) {
+    switch(index) {
+      case 0: {
+        return 0x07;
+      }
+      case 1: {
+        return 0x08;
+      }
+      case 2: {
+        return 0x09;
+      }
+      case 3: {
+        return 0x0a;
+      }
+      case 4: {
+        return 0x0b;
+      }
+      case 5: {
+        return 0x0c;
+      }
+      case 6: {
+        return 0x0d;
+      }
+      default: {
+        return -1;
+      }
+    }
+}
 
 uint16_t plc4c_s7_read_write_cotp_tpdu_size_get_size_in_bytes(plc4c_s7_read_write_cotp_tpdu_size value) {
   switch(value) {
diff --git a/sandbox/plc4c/generated-sources/s7/src/data_item.c b/sandbox/plc4c/generated-sources/s7/src/data_item.c
new file mode 100644
index 0000000..1d0f20d
--- /dev/null
+++ b/sandbox/plc4c/generated-sources/s7/src/data_item.c
@@ -0,0 +1,256 @@
+/*
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+*/
+
+#include <stdio.h>
+#include <time.h>
+#include <plc4c/data.h>
+#include <plc4c/spi/evaluation_helper.h>
+#include <plc4c/driver_s7.h>
+#include "data_item.h"
+
+// Parse function.
+plc4c_return_code plc4c_s7_read_write_data_item_parse(plc4c_spi_read_buffer* io, uint8_t dataProtocolId, int32_t stringLength, plc4c_data** data_item) {
+    uint16_t startPos = plc4c_spi_read_get_pos(io);
+    uint16_t curPos;
+    plc4c_return_code _res = OK;
+
+        if(dataProtocolId == 01) { /* Boolean */
+
+                // Reserved Field (Compartmentalized so the "reserved" variable can't leak)
+                {
+                    unsigned int _reserved = 0;
+                    _res = plc4c_spi_read_unsigned_byte(io, 7, (uint8_t*) &_reserved);
+                    if(_res != OK) {
+                        return _res;
+                    }
+                    if(_reserved != 0x00) {
+                      printf("Expected constant value '%d' but got '%d' for reserved field.", 0x00, _reserved);
+                    }
+                }
+
+                // Simple Field (value)
+                bool value = false;
+                _res = plc4c_spi_read_bit(io, (bool*) &value);
+                if(_res != OK) {
+                    return _res;
+                }
+
+                *data_item = plc4c_data_create_bool_data(value);
+
+        } else 
+        if(dataProtocolId == 11) { /* List */
+
+                    // Array field (value)
+        } else 
+        if(dataProtocolId == 12) { /* List */
+
+                    // Array field (value)
+        } else 
+        if(dataProtocolId == 13) { /* List */
+
+                    // Array field (value)
+        } else 
+        if(dataProtocolId == 14) { /* List */
+
+                    // Array field (value)
+        } else 
+        if(dataProtocolId == 21) { /* Integer */
+
+                // Simple Field (value)
+                int8_t value = 0;
+                _res = plc4c_spi_read_signed_byte(io, 8, (int8_t*) &value);
+                if(_res != OK) {
+                    return _res;
+                }
+
+                *data_item = plc4c_data_create_int8_t_data(value);
+
+        } else 
+        if(dataProtocolId == 22) { /* Integer */
+
+                // Simple Field (value)
+                uint8_t value = 0;
+                _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &value);
+                if(_res != OK) {
+                    return _res;
+                }
+
+                *data_item = plc4c_data_create_uint8_t_data(value);
+
+        } else 
+        if(dataProtocolId == 23) { /* Integer */
+
+                // Simple Field (value)
+                int16_t value = 0;
+                _res = plc4c_spi_read_signed_short(io, 16, (int16_t*) &value);
+                if(_res != OK) {
+                    return _res;
+                }
+
+                *data_item = plc4c_data_create_int16_t_data(value);
+
+        } else 
+        if(dataProtocolId == 24) { /* Integer */
+
+                // Simple Field (value)
+                uint16_t value = 0;
+                _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &value);
+                if(_res != OK) {
+                    return _res;
+                }
+
+                *data_item = plc4c_data_create_uint16_t_data(value);
+
+        } else 
+        if(dataProtocolId == 25) { /* Integer */
+
+                // Simple Field (value)
+                int32_t value = 0;
+                _res = plc4c_spi_read_signed_int(io, 32, (int32_t*) &value);
+                if(_res != OK) {
+                    return _res;
+                }
+
+                *data_item = plc4c_data_create_int32_t_data(value);
+
+        } else 
+        if(dataProtocolId == 26) { /* Long */
+
+                // Simple Field (value)
+                uint32_t value = 0;
+                _res = plc4c_spi_read_unsigned_int(io, 32, (uint32_t*) &value);
+                if(_res != OK) {
+                    return _res;
+                }
+
+                *data_item = plc4c_data_create_uint32_t_data(value);
+
+        } else 
+        if(dataProtocolId == 27) { /* Long */
+
+                // Simple Field (value)
+                int64_t value = 0;
+                _res = plc4c_spi_read_signed_long(io, 64, (int64_t*) &value);
+                if(_res != OK) {
+                    return _res;
+                }
+
+                *data_item = plc4c_data_create_int64_t_data(value);
+
+        } else 
+        if(dataProtocolId == 28) { /* BigInteger */
+
+                // Simple Field (value)
+                uint64_t value = 0;
+                _res = plc4c_spi_read_unsigned_long(io, 64, (uint64_t*) &value);
+                if(_res != OK) {
+                    return _res;
+                }
+
+                *data_item = plc4c_data_create_uint64_t_data(value);
+
+        } else 
+        if(dataProtocolId == 31) { /* Float */
+
+                // Simple Field (value)
+                float value = 0.0;
+                _res = plc4c_spi_read_float(io, 32, (float*) &value);
+                if(_res != OK) {
+                    return _res;
+                }
+
+                *data_item = plc4c_data_create_float_data(value);
+
+        } else 
+        if(dataProtocolId == 32) { /* Double */
+
+                // Simple Field (value)
+                double value = 0.0;
+                _res = plc4c_spi_read_double(io, 64, (double*) &value);
+                if(_res != OK) {
+                    return _res;
+                }
+
+                *data_item = plc4c_data_create_double_data(value);
+
+        } else 
+        if(dataProtocolId == 41) { /* String */
+        } else 
+        if(dataProtocolId == 42) { /* String */
+        } else 
+        if(dataProtocolId == 43) { /* String */
+
+                    // Manual Field (value)
+                    char* value = (char*) (plc4c_s7_read_write_parse_s7_string(io, stringLength, "UTF-8"));
+        } else 
+        if(dataProtocolId == 44) { /* String */
+
+                    // Manual Field (value)
+                    char* value = (char*) (plc4c_s7_read_write_parse_s7_string(io, stringLength, "UTF-16"));
+        } else 
+        if(dataProtocolId == 51) { /* Time */
+
+                    // Manual Field (value)
+                    time_t value = (time_t) (plc4c_s7_read_write_parse_tia_time(io));
+        } else 
+        if(dataProtocolId == 52) { /* Time */
+
+                    // Manual Field (value)
+                    time_t value = (time_t) (plc4c_s7_read_write_parse_s5_time(io));
+        } else 
+        if(dataProtocolId == 53) { /* Time */
+
+                    // Manual Field (value)
+                    time_t value = (time_t) (plc4c_s7_read_write_parse_tia_l_time(io));
+        } else 
+        if(dataProtocolId == 54) { /* Date */
+
+                    // Manual Field (value)
+                    time_t value = (time_t) (plc4c_s7_read_write_parse_tia_date(io));
+        } else 
+        if(dataProtocolId == 55) { /* Time */
+
+                    // Manual Field (value)
+                    time_t value = (time_t) (plc4c_s7_read_write_parse_tia_time_of_day(io));
+        } else 
+        if(dataProtocolId == 56) { /* DateTime */
+
+                    // Manual Field (value)
+                    time_t value = (time_t) (plc4c_s7_read_write_parse_tia_date_time(io));
+        }
+
+  return OK;
+}
+
+plc4c_return_code plc4c_s7_read_write_data_item_serialize(plc4c_spi_write_buffer* io, plc4c_data** data_item) {
+  plc4c_return_code _res = OK;
+
+  return OK;
+}
+
+uint16_t plc4c_s7_read_write_data_item_length_in_bytes(plc4c_data* data_item) {
+  return plc4c_s7_read_write_data_item_length_in_bits(data_item) / 8;
+}
+
+uint16_t plc4c_s7_read_write_data_item_length_in_bits(plc4c_data* data_item) {
+  uint16_t lengthInBits = 0;
+
+  return lengthInBits;
+}
+
diff --git a/sandbox/plc4c/generated-sources/s7/src/data_transport_error_code.c b/sandbox/plc4c/generated-sources/s7/src/data_transport_error_code.c
index 7baf834..cb13d9d 100644
--- a/sandbox/plc4c/generated-sources/s7/src/data_transport_error_code.c
+++ b/sandbox/plc4c/generated-sources/s7/src/data_transport_error_code.c
@@ -18,6 +18,7 @@
 */
 
 #include "data_transport_error_code.h"
+#include <string.h>
 
 
 // Create an empty NULL-struct
@@ -27,3 +28,54 @@
   return plc4c_s7_read_write_data_transport_error_code_null_const;
 }
 
+plc4c_s7_read_write_data_transport_error_code plc4c_s7_read_write_data_transport_error_code_value_of(char* value_string) {
+    if(strcmp(value_string, "RESERVED") == 0) {
+        return 0x00;
+    }
+    if(strcmp(value_string, "ACCESS_DENIED") == 0) {
+        return 0x03;
+    }
+    if(strcmp(value_string, "INVALID_ADDRESS") == 0) {
+        return 0x05;
+    }
+    if(strcmp(value_string, "DATA_TYPE_NOT_SUPPORTED") == 0) {
+        return 0x06;
+    }
+    if(strcmp(value_string, "NOT_FOUND") == 0) {
+        return 0x0A;
+    }
+    if(strcmp(value_string, "OK") == 0) {
+        return 0xFF;
+    }
+    return -1;
+}
+
+int plc4c_s7_read_write_data_transport_error_code_num_values() {
+  return 6;
+}
+
+plc4c_s7_read_write_data_transport_error_code plc4c_s7_read_write_data_transport_error_code_value_for_index(int index) {
+    switch(index) {
+      case 0: {
+        return 0x00;
+      }
+      case 1: {
+        return 0x03;
+      }
+      case 2: {
+        return 0x05;
+      }
+      case 3: {
+        return 0x06;
+      }
+      case 4: {
+        return 0x0A;
+      }
+      case 5: {
+        return 0xFF;
+      }
+      default: {
+        return -1;
+      }
+    }
+}
diff --git a/sandbox/plc4c/generated-sources/s7/src/data_transport_size.c b/sandbox/plc4c/generated-sources/s7/src/data_transport_size.c
index dcea90b..5b2bf04 100644
--- a/sandbox/plc4c/generated-sources/s7/src/data_transport_size.c
+++ b/sandbox/plc4c/generated-sources/s7/src/data_transport_size.c
@@ -18,6 +18,7 @@
 */
 
 #include "data_transport_size.h"
+#include <string.h>
 
 
 // Create an empty NULL-struct
@@ -27,6 +28,63 @@
   return plc4c_s7_read_write_data_transport_size_null_const;
 }
 
+plc4c_s7_read_write_data_transport_size plc4c_s7_read_write_data_transport_size_value_of(char* value_string) {
+    if(strcmp(value_string, "NULL") == 0) {
+        return 0x00;
+    }
+    if(strcmp(value_string, "BIT") == 0) {
+        return 0x03;
+    }
+    if(strcmp(value_string, "BYTE_WORD_DWORD") == 0) {
+        return 0x04;
+    }
+    if(strcmp(value_string, "INTEGER") == 0) {
+        return 0x05;
+    }
+    if(strcmp(value_string, "DINTEGER") == 0) {
+        return 0x06;
+    }
+    if(strcmp(value_string, "REAL") == 0) {
+        return 0x07;
+    }
+    if(strcmp(value_string, "OCTET_STRING") == 0) {
+        return 0x09;
+    }
+    return -1;
+}
+
+int plc4c_s7_read_write_data_transport_size_num_values() {
+  return 7;
+}
+
+plc4c_s7_read_write_data_transport_size plc4c_s7_read_write_data_transport_size_value_for_index(int index) {
+    switch(index) {
+      case 0: {
+        return 0x00;
+      }
+      case 1: {
+        return 0x03;
+      }
+      case 2: {
+        return 0x04;
+      }
+      case 3: {
+        return 0x05;
+      }
+      case 4: {
+        return 0x06;
+      }
+      case 5: {
+        return 0x07;
+      }
+      case 6: {
+        return 0x09;
+      }
+      default: {
+        return -1;
+      }
+    }
+}
 
 bool plc4c_s7_read_write_data_transport_size_get_size_in_bits(plc4c_s7_read_write_data_transport_size value) {
   switch(value) {
diff --git a/sandbox/plc4c/generated-sources/s7/src/device_group.c b/sandbox/plc4c/generated-sources/s7/src/device_group.c
index 91bca89..08fff70 100644
--- a/sandbox/plc4c/generated-sources/s7/src/device_group.c
+++ b/sandbox/plc4c/generated-sources/s7/src/device_group.c
@@ -18,6 +18,7 @@
 */
 
 #include "device_group.h"
+#include <string.h>
 
 
 // Create an empty NULL-struct
@@ -27,3 +28,36 @@
   return plc4c_s7_read_write_device_group_null_const;
 }
 
+plc4c_s7_read_write_device_group plc4c_s7_read_write_device_group_value_of(char* value_string) {
+    if(strcmp(value_string, "PG_OR_PC") == 0) {
+        return 0x01;
+    }
+    if(strcmp(value_string, "OS") == 0) {
+        return 0x02;
+    }
+    if(strcmp(value_string, "OTHERS") == 0) {
+        return 0x03;
+    }
+    return -1;
+}
+
+int plc4c_s7_read_write_device_group_num_values() {
+  return 3;
+}
+
+plc4c_s7_read_write_device_group plc4c_s7_read_write_device_group_value_for_index(int index) {
+    switch(index) {
+      case 0: {
+        return 0x01;
+      }
+      case 1: {
+        return 0x02;
+      }
+      case 2: {
+        return 0x03;
+      }
+      default: {
+        return -1;
+      }
+    }
+}
diff --git a/sandbox/plc4c/generated-sources/s7/src/memory_area.c b/sandbox/plc4c/generated-sources/s7/src/memory_area.c
index 503ba73..6a7fe3a 100644
--- a/sandbox/plc4c/generated-sources/s7/src/memory_area.c
+++ b/sandbox/plc4c/generated-sources/s7/src/memory_area.c
@@ -18,6 +18,7 @@
 */
 
 #include "memory_area.h"
+#include <string.h>
 
 
 // Create an empty NULL-struct
@@ -27,6 +28,75 @@
   return plc4c_s7_read_write_memory_area_null_const;
 }
 
+plc4c_s7_read_write_memory_area plc4c_s7_read_write_memory_area_value_of(char* value_string) {
+    if(strcmp(value_string, "COUNTERS") == 0) {
+        return 0x1C;
+    }
+    if(strcmp(value_string, "TIMERS") == 0) {
+        return 0x1D;
+    }
+    if(strcmp(value_string, "DIRECT_PERIPHERAL_ACCESS") == 0) {
+        return 0x80;
+    }
+    if(strcmp(value_string, "INPUTS") == 0) {
+        return 0x81;
+    }
+    if(strcmp(value_string, "OUTPUTS") == 0) {
+        return 0x82;
+    }
+    if(strcmp(value_string, "FLAGS_MARKERS") == 0) {
+        return 0x83;
+    }
+    if(strcmp(value_string, "DATA_BLOCKS") == 0) {
+        return 0x84;
+    }
+    if(strcmp(value_string, "INSTANCE_DATA_BLOCKS") == 0) {
+        return 0x85;
+    }
+    if(strcmp(value_string, "LOCAL_DATA") == 0) {
+        return 0x86;
+    }
+    return -1;
+}
+
+int plc4c_s7_read_write_memory_area_num_values() {
+  return 9;
+}
+
+plc4c_s7_read_write_memory_area plc4c_s7_read_write_memory_area_value_for_index(int index) {
+    switch(index) {
+      case 0: {
+        return 0x1C;
+      }
+      case 1: {
+        return 0x1D;
+      }
+      case 2: {
+        return 0x80;
+      }
+      case 3: {
+        return 0x81;
+      }
+      case 4: {
+        return 0x82;
+      }
+      case 5: {
+        return 0x83;
+      }
+      case 6: {
+        return 0x84;
+      }
+      case 7: {
+        return 0x85;
+      }
+      case 8: {
+        return 0x86;
+      }
+      default: {
+        return -1;
+      }
+    }
+}
 
 char* plc4c_s7_read_write_memory_area_get_short_name(plc4c_s7_read_write_memory_area value) {
   switch(value) {
diff --git a/sandbox/plc4c/generated-sources/s7/src/s7_address.c b/sandbox/plc4c/generated-sources/s7/src/s7_address.c
index 4f4e5b0..99b5fef 100644
--- a/sandbox/plc4c/generated-sources/s7/src/s7_address.c
+++ b/sandbox/plc4c/generated-sources/s7/src/s7_address.c
@@ -43,8 +43,8 @@
 
 
 // Parse function.
-plc4c_return_code plc4c_s7_read_write_s7_address_parse(plc4c_spi_read_buffer* buf, plc4c_s7_read_write_s7_address** _message) {
-  uint16_t startPos = plc4c_spi_read_get_pos(buf);
+plc4c_return_code plc4c_s7_read_write_s7_address_parse(plc4c_spi_read_buffer* io, plc4c_s7_read_write_s7_address** _message) {
+  uint16_t startPos = plc4c_spi_read_get_pos(io);
   uint16_t curPos;
   plc4c_return_code _res = OK;
 
@@ -56,7 +56,7 @@
 
   // Discriminator Field (addressType) (Used as input to a switch field)
   uint8_t addressType = 0;
-  _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &addressType);
+  _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &addressType);
   if(_res != OK) {
     return _res;
   }
@@ -67,7 +67,7 @@
                     
     // Enum field (transportSize)
     plc4c_s7_read_write_transport_size transportSize = plc4c_s7_read_write_transport_size_null();
-    _res = plc4c_spi_read_signed_byte(buf, 8, (int8_t*) &transportSize);
+    _res = plc4c_spi_read_signed_byte(io, 8, (int8_t*) &transportSize);
     if(_res != OK) {
       return _res;
     }
@@ -77,7 +77,7 @@
                     
     // Simple Field (numberOfElements)
     uint16_t numberOfElements = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &numberOfElements);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &numberOfElements);
     if(_res != OK) {
       return _res;
     }
@@ -87,7 +87,7 @@
                     
     // Simple Field (dbNumber)
     uint16_t dbNumber = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &dbNumber);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &dbNumber);
     if(_res != OK) {
       return _res;
     }
@@ -97,7 +97,7 @@
                     
     // Enum field (area)
     plc4c_s7_read_write_memory_area area = plc4c_s7_read_write_memory_area_null();
-    _res = plc4c_spi_read_signed_byte(buf, 8, (int8_t*) &area);
+    _res = plc4c_spi_read_signed_byte(io, 8, (int8_t*) &area);
     if(_res != OK) {
       return _res;
     }
@@ -108,7 +108,7 @@
     // Reserved Field (Compartmentalized so the "reserved" variable can't leak)
     {
       unsigned int _reserved = 0;
-      _res = plc4c_spi_read_unsigned_byte(buf, 5, (uint8_t*) &_reserved);
+      _res = plc4c_spi_read_unsigned_byte(io, 5, (uint8_t*) &_reserved);
       if(_res != OK) {
         return _res;
       }
@@ -121,7 +121,7 @@
                     
     // Simple Field (byteAddress)
     uint16_t byteAddress = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &byteAddress);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &byteAddress);
     if(_res != OK) {
       return _res;
     }
@@ -131,7 +131,7 @@
                     
     // Simple Field (bitAddress)
     unsigned int bitAddress = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 3, (uint8_t*) &bitAddress);
+    _res = plc4c_spi_read_unsigned_byte(io, 3, (uint8_t*) &bitAddress);
     if(_res != OK) {
       return _res;
     }
@@ -142,54 +142,54 @@
   return OK;
 }
 
-plc4c_return_code plc4c_s7_read_write_s7_address_serialize(plc4c_spi_write_buffer* buf, plc4c_s7_read_write_s7_address* _message) {
+plc4c_return_code plc4c_s7_read_write_s7_address_serialize(plc4c_spi_write_buffer* io, plc4c_s7_read_write_s7_address* _message) {
   plc4c_return_code _res = OK;
 
   // Discriminator Field (addressType)
-  plc4c_spi_write_unsigned_byte(buf, 8, plc4c_s7_read_write_s7_address_get_discriminator(_message->_type).addressType);
+  plc4c_spi_write_unsigned_byte(io, 8, plc4c_s7_read_write_s7_address_get_discriminator(_message->_type).addressType);
 
   // Switch Field (Depending of the current type, serialize the sub-type elements)
   switch(_message->_type) {
     case plc4c_s7_read_write_s7_address_type_plc4c_s7_read_write_s7_address_any: {
 
       // Enum field (transportSize)
-      _res = plc4c_spi_write_signed_byte(buf, 8, _message->s7_address_any_transport_size);
+      _res = plc4c_spi_write_signed_byte(io, 8, _message->s7_address_any_transport_size);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (numberOfElements)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->s7_address_any_number_of_elements);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->s7_address_any_number_of_elements);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (dbNumber)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->s7_address_any_db_number);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->s7_address_any_db_number);
       if(_res != OK) {
         return _res;
       }
 
       // Enum field (area)
-      _res = plc4c_spi_write_signed_byte(buf, 8, _message->s7_address_any_area);
+      _res = plc4c_spi_write_signed_byte(io, 8, _message->s7_address_any_area);
       if(_res != OK) {
         return _res;
       }
 
       // Reserved Field
-      _res = plc4c_spi_write_unsigned_byte(buf, 5, 0x00);
+      _res = plc4c_spi_write_unsigned_byte(io, 5, 0x00);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (byteAddress)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->s7_address_any_byte_address);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->s7_address_any_byte_address);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (bitAddress)
-      _res = plc4c_spi_write_unsigned_byte(buf, 3, _message->s7_address_any_bit_address);
+      _res = plc4c_spi_write_unsigned_byte(io, 3, _message->s7_address_any_bit_address);
       if(_res != OK) {
         return _res;
       }
diff --git a/sandbox/plc4c/generated-sources/s7/src/s7_message.c b/sandbox/plc4c/generated-sources/s7/src/s7_message.c
index 69f20b8..15e0509 100644
--- a/sandbox/plc4c/generated-sources/s7/src/s7_message.c
+++ b/sandbox/plc4c/generated-sources/s7/src/s7_message.c
@@ -55,8 +55,8 @@
 }
 
 // Parse function.
-plc4c_return_code plc4c_s7_read_write_s7_message_parse(plc4c_spi_read_buffer* buf, plc4c_s7_read_write_s7_message** _message) {
-  uint16_t startPos = plc4c_spi_read_get_pos(buf);
+plc4c_return_code plc4c_s7_read_write_s7_message_parse(plc4c_spi_read_buffer* io, plc4c_s7_read_write_s7_message** _message) {
+  uint16_t startPos = plc4c_spi_read_get_pos(io);
   uint16_t curPos;
   plc4c_return_code _res = OK;
 
@@ -68,7 +68,7 @@
 
   // Const Field (protocolId)
   uint8_t protocolId = 0;
-  _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &protocolId);
+  _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &protocolId);
   if(_res != OK) {
     return _res;
   }
@@ -79,7 +79,7 @@
 
   // Discriminator Field (messageType) (Used as input to a switch field)
   uint8_t messageType = 0;
-  _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &messageType);
+  _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &messageType);
   if(_res != OK) {
     return _res;
   }
@@ -87,7 +87,7 @@
   // Reserved Field (Compartmentalized so the "reserved" variable can't leak)
   {
     uint16_t _reserved = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &_reserved);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &_reserved);
     if(_res != OK) {
       return _res;
     }
@@ -98,7 +98,7 @@
 
   // Simple Field (tpduReference)
   uint16_t tpduReference = 0;
-  _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &tpduReference);
+  _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &tpduReference);
   if(_res != OK) {
     return _res;
   }
@@ -106,14 +106,14 @@
 
   // Implicit Field (parameterLength) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
   uint16_t parameterLength = 0;
-  _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &parameterLength);
+  _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &parameterLength);
   if(_res != OK) {
     return _res;
   }
 
   // Implicit Field (payloadLength) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
   uint16_t payloadLength = 0;
-  _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &payloadLength);
+  _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &payloadLength);
   if(_res != OK) {
     return _res;
   }
@@ -127,7 +127,7 @@
                     
     // Simple Field (errorClass)
     uint8_t errorClass = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &errorClass);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &errorClass);
     if(_res != OK) {
       return _res;
     }
@@ -137,7 +137,7 @@
                     
     // Simple Field (errorCode)
     uint8_t errorCode = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &errorCode);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &errorCode);
     if(_res != OK) {
       return _res;
     }
@@ -149,7 +149,7 @@
                     
     // Simple Field (errorClass)
     uint8_t errorClass = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &errorClass);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &errorClass);
     if(_res != OK) {
       return _res;
     }
@@ -159,7 +159,7 @@
                     
     // Simple Field (errorCode)
     uint8_t errorCode = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &errorCode);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &errorCode);
     if(_res != OK) {
       return _res;
     }
@@ -177,7 +177,7 @@
     if(parameter == NULL) {
       return NO_MEMORY;
     }
-    _res = plc4c_s7_read_write_s7_parameter_parse(buf, messageType, &parameter);
+    _res = plc4c_s7_read_write_s7_parameter_parse(io, messageType, &parameter);
     if(_res != OK) {
       return _res;
     }
@@ -193,7 +193,7 @@
     if(payload == NULL) {
       return NO_MEMORY;
     }
-    _res = plc4c_s7_read_write_s7_payload_parse(buf, messageType, parameter, &payload);
+    _res = plc4c_s7_read_write_s7_payload_parse(io, messageType, parameter, &payload);
     if(_res != OK) {
       return _res;
     }
@@ -205,35 +205,35 @@
   return OK;
 }
 
-plc4c_return_code plc4c_s7_read_write_s7_message_serialize(plc4c_spi_write_buffer* buf, plc4c_s7_read_write_s7_message* _message) {
+plc4c_return_code plc4c_s7_read_write_s7_message_serialize(plc4c_spi_write_buffer* io, plc4c_s7_read_write_s7_message* _message) {
   plc4c_return_code _res = OK;
 
   // Const Field (protocolId)
-  plc4c_spi_write_unsigned_byte(buf, 8, PLC4C_S7_READ_WRITE_S7_MESSAGE_PROTOCOL_ID());
+  plc4c_spi_write_unsigned_byte(io, 8, PLC4C_S7_READ_WRITE_S7_MESSAGE_PROTOCOL_ID());
 
   // Discriminator Field (messageType)
-  plc4c_spi_write_unsigned_byte(buf, 8, plc4c_s7_read_write_s7_message_get_discriminator(_message->_type).messageType);
+  plc4c_spi_write_unsigned_byte(io, 8, plc4c_s7_read_write_s7_message_get_discriminator(_message->_type).messageType);
 
   // Reserved Field
-  _res = plc4c_spi_write_unsigned_short(buf, 16, 0x0000);
+  _res = plc4c_spi_write_unsigned_short(io, 16, 0x0000);
   if(_res != OK) {
     return _res;
   }
 
   // Simple Field (tpduReference)
-  _res = plc4c_spi_write_unsigned_short(buf, 16, _message->tpdu_reference);
+  _res = plc4c_spi_write_unsigned_short(io, 16, _message->tpdu_reference);
   if(_res != OK) {
     return _res;
   }
 
   // Implicit Field (parameterLength) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-  _res = plc4c_spi_write_unsigned_short(buf, 16, (((_message->parameter) != (NULL)) ? plc4c_s7_read_write_s7_parameter_length_in_bytes(_message->parameter) : 0));
+  _res = plc4c_spi_write_unsigned_short(io, 16, (((_message->parameter) != (NULL)) ? plc4c_s7_read_write_s7_parameter_length_in_bytes(_message->parameter) : 0));
   if(_res != OK) {
     return _res;
   }
 
   // Implicit Field (payloadLength) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-  _res = plc4c_spi_write_unsigned_short(buf, 16, (((_message->payload) != (NULL)) ? plc4c_s7_read_write_s7_payload_length_in_bytes(_message->payload) : 0));
+  _res = plc4c_spi_write_unsigned_short(io, 16, (((_message->payload) != (NULL)) ? plc4c_s7_read_write_s7_payload_length_in_bytes(_message->payload) : 0));
   if(_res != OK) {
     return _res;
   }
@@ -247,13 +247,13 @@
     case plc4c_s7_read_write_s7_message_type_plc4c_s7_read_write_s7_message_response: {
 
       // Simple Field (errorClass)
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, _message->s7_message_response_error_class);
+      _res = plc4c_spi_write_unsigned_byte(io, 8, _message->s7_message_response_error_class);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (errorCode)
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, _message->s7_message_response_error_code);
+      _res = plc4c_spi_write_unsigned_byte(io, 8, _message->s7_message_response_error_code);
       if(_res != OK) {
         return _res;
       }
@@ -263,13 +263,13 @@
     case plc4c_s7_read_write_s7_message_type_plc4c_s7_read_write_s7_message_response_data: {
 
       // Simple Field (errorClass)
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, _message->s7_message_response_data_error_class);
+      _res = plc4c_spi_write_unsigned_byte(io, 8, _message->s7_message_response_data_error_class);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (errorCode)
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, _message->s7_message_response_data_error_code);
+      _res = plc4c_spi_write_unsigned_byte(io, 8, _message->s7_message_response_data_error_code);
       if(_res != OK) {
         return _res;
       }
@@ -284,7 +284,7 @@
 
   // Optional Field (parameter)
   if(_message->parameter != NULL) {
-    _res = plc4c_s7_read_write_s7_parameter_serialize(buf, _message->parameter);
+    _res = plc4c_s7_read_write_s7_parameter_serialize(io, _message->parameter);
     if(_res != OK) {
       return _res;
     }
@@ -292,7 +292,7 @@
 
   // Optional Field (payload)
   if(_message->payload != NULL) {
-    _res = plc4c_s7_read_write_s7_payload_serialize(buf, _message->payload);
+    _res = plc4c_s7_read_write_s7_payload_serialize(io, _message->payload);
     if(_res != OK) {
       return _res;
     }
diff --git a/sandbox/plc4c/generated-sources/s7/src/s7_parameter.c b/sandbox/plc4c/generated-sources/s7/src/s7_parameter.c
index 25c1a92..696d0aa 100644
--- a/sandbox/plc4c/generated-sources/s7/src/s7_parameter.c
+++ b/sandbox/plc4c/generated-sources/s7/src/s7_parameter.c
@@ -53,8 +53,8 @@
 
 
 // Parse function.
-plc4c_return_code plc4c_s7_read_write_s7_parameter_parse(plc4c_spi_read_buffer* buf, uint8_t messageType, plc4c_s7_read_write_s7_parameter** _message) {
-  uint16_t startPos = plc4c_spi_read_get_pos(buf);
+plc4c_return_code plc4c_s7_read_write_s7_parameter_parse(plc4c_spi_read_buffer* io, uint8_t messageType, plc4c_s7_read_write_s7_parameter** _message) {
+  uint16_t startPos = plc4c_spi_read_get_pos(io);
   uint16_t curPos;
   plc4c_return_code _res = OK;
 
@@ -66,7 +66,7 @@
 
   // Discriminator Field (parameterType) (Used as input to a switch field)
   uint8_t parameterType = 0;
-  _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &parameterType);
+  _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &parameterType);
   if(_res != OK) {
     return _res;
   }
@@ -78,7 +78,7 @@
     // Reserved Field (Compartmentalized so the "reserved" variable can't leak)
     {
       uint8_t _reserved = 0;
-      _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &_reserved);
+      _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &_reserved);
       if(_res != OK) {
         return _res;
       }
@@ -91,7 +91,7 @@
                     
     // Simple Field (maxAmqCaller)
     uint16_t maxAmqCaller = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &maxAmqCaller);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &maxAmqCaller);
     if(_res != OK) {
       return _res;
     }
@@ -101,7 +101,7 @@
                     
     // Simple Field (maxAmqCallee)
     uint16_t maxAmqCallee = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &maxAmqCallee);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &maxAmqCallee);
     if(_res != OK) {
       return _res;
     }
@@ -111,7 +111,7 @@
                     
     // Simple Field (pduLength)
     uint16_t pduLength = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &pduLength);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &pduLength);
     if(_res != OK) {
       return _res;
     }
@@ -123,7 +123,7 @@
                     
     // Implicit Field (numItems) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
     uint8_t numItems = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &numItems);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &numItems);
     if(_res != OK) {
       return _res;
     }
@@ -141,8 +141,8 @@
       uint8_t itemCount = numItems;
       for(int curItem = 0; curItem < itemCount; curItem++) {
         bool lastItem = curItem == (itemCount - 1);
-                          plc4c_list* _value = NULL;
-        _res = plc4c_s7_read_write_s7_var_request_parameter_item_parse(buf, (void*) &_value);
+        plc4c_s7_read_write_s7_var_request_parameter_item* _value = NULL;
+        _res = plc4c_s7_read_write_s7_var_request_parameter_item_parse(io, (void*) &_value);
         if(_res != OK) {
           return _res;
         }
@@ -157,7 +157,7 @@
                     
     // Simple Field (numItems)
     uint8_t numItems = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &numItems);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &numItems);
     if(_res != OK) {
       return _res;
     }
@@ -169,7 +169,7 @@
                     
     // Implicit Field (numItems) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
     uint8_t numItems = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &numItems);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &numItems);
     if(_res != OK) {
       return _res;
     }
@@ -187,8 +187,8 @@
       uint8_t itemCount = numItems;
       for(int curItem = 0; curItem < itemCount; curItem++) {
         bool lastItem = curItem == (itemCount - 1);
-                          plc4c_list* _value = NULL;
-        _res = plc4c_s7_read_write_s7_var_request_parameter_item_parse(buf, (void*) &_value);
+        plc4c_s7_read_write_s7_var_request_parameter_item* _value = NULL;
+        _res = plc4c_s7_read_write_s7_var_request_parameter_item_parse(io, (void*) &_value);
         if(_res != OK) {
           return _res;
         }
@@ -203,7 +203,7 @@
                     
     // Simple Field (numItems)
     uint8_t numItems = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &numItems);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &numItems);
     if(_res != OK) {
       return _res;
     }
@@ -215,7 +215,7 @@
                     
     // Implicit Field (numItems) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
     uint8_t numItems = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &numItems);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &numItems);
     if(_res != OK) {
       return _res;
     }
@@ -233,8 +233,8 @@
       uint8_t itemCount = numItems;
       for(int curItem = 0; curItem < itemCount; curItem++) {
         bool lastItem = curItem == (itemCount - 1);
-                          plc4c_list* _value = NULL;
-        _res = plc4c_s7_read_write_s7_parameter_user_data_item_parse(buf, (void*) &_value);
+        plc4c_s7_read_write_s7_parameter_user_data_item* _value = NULL;
+        _res = plc4c_s7_read_write_s7_parameter_user_data_item_parse(io, (void*) &_value);
         if(_res != OK) {
           return _res;
         }
@@ -248,36 +248,36 @@
   return OK;
 }
 
-plc4c_return_code plc4c_s7_read_write_s7_parameter_serialize(plc4c_spi_write_buffer* buf, plc4c_s7_read_write_s7_parameter* _message) {
+plc4c_return_code plc4c_s7_read_write_s7_parameter_serialize(plc4c_spi_write_buffer* io, plc4c_s7_read_write_s7_parameter* _message) {
   plc4c_return_code _res = OK;
 
   // Discriminator Field (parameterType)
-  plc4c_spi_write_unsigned_byte(buf, 8, plc4c_s7_read_write_s7_parameter_get_discriminator(_message->_type).parameterType);
+  plc4c_spi_write_unsigned_byte(io, 8, plc4c_s7_read_write_s7_parameter_get_discriminator(_message->_type).parameterType);
 
   // Switch Field (Depending of the current type, serialize the sub-type elements)
   switch(_message->_type) {
     case plc4c_s7_read_write_s7_parameter_type_plc4c_s7_read_write_s7_parameter_setup_communication: {
 
       // Reserved Field
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, 0x00);
+      _res = plc4c_spi_write_unsigned_byte(io, 8, 0x00);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (maxAmqCaller)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->s7_parameter_setup_communication_max_amq_caller);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->s7_parameter_setup_communication_max_amq_caller);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (maxAmqCallee)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->s7_parameter_setup_communication_max_amq_callee);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->s7_parameter_setup_communication_max_amq_callee);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (pduLength)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, _message->s7_parameter_setup_communication_pdu_length);
+      _res = plc4c_spi_write_unsigned_short(io, 16, _message->s7_parameter_setup_communication_pdu_length);
       if(_res != OK) {
         return _res;
       }
@@ -287,7 +287,7 @@
     case plc4c_s7_read_write_s7_parameter_type_plc4c_s7_read_write_s7_parameter_read_var_request: {
 
       // Implicit Field (numItems) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, plc4c_spi_evaluation_helper_count(_message->s7_parameter_read_var_request_items));
+      _res = plc4c_spi_write_unsigned_byte(io, 8, plc4c_spi_evaluation_helper_count(_message->s7_parameter_read_var_request_items));
       if(_res != OK) {
         return _res;
       }
@@ -298,7 +298,7 @@
         for(int curItem = 0; curItem < itemCount; curItem++) {
           bool lastItem = curItem == (itemCount - 1);
           plc4c_s7_read_write_s7_var_request_parameter_item* _value = (plc4c_s7_read_write_s7_var_request_parameter_item*) plc4c_utils_list_get_value(_message->s7_parameter_read_var_request_items, curItem);
-          _res = plc4c_s7_read_write_s7_var_request_parameter_item_serialize(buf, (void*) _value);
+          _res = plc4c_s7_read_write_s7_var_request_parameter_item_serialize(io, (void*) _value);
           if(_res != OK) {
             return _res;
           }
@@ -310,7 +310,7 @@
     case plc4c_s7_read_write_s7_parameter_type_plc4c_s7_read_write_s7_parameter_read_var_response: {
 
       // Simple Field (numItems)
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, _message->s7_parameter_read_var_response_num_items);
+      _res = plc4c_spi_write_unsigned_byte(io, 8, _message->s7_parameter_read_var_response_num_items);
       if(_res != OK) {
         return _res;
       }
@@ -320,7 +320,7 @@
     case plc4c_s7_read_write_s7_parameter_type_plc4c_s7_read_write_s7_parameter_write_var_request: {
 
       // Implicit Field (numItems) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, plc4c_spi_evaluation_helper_count(_message->s7_parameter_write_var_request_items));
+      _res = plc4c_spi_write_unsigned_byte(io, 8, plc4c_spi_evaluation_helper_count(_message->s7_parameter_write_var_request_items));
       if(_res != OK) {
         return _res;
       }
@@ -331,7 +331,7 @@
         for(int curItem = 0; curItem < itemCount; curItem++) {
           bool lastItem = curItem == (itemCount - 1);
           plc4c_s7_read_write_s7_var_request_parameter_item* _value = (plc4c_s7_read_write_s7_var_request_parameter_item*) plc4c_utils_list_get_value(_message->s7_parameter_write_var_request_items, curItem);
-          _res = plc4c_s7_read_write_s7_var_request_parameter_item_serialize(buf, (void*) _value);
+          _res = plc4c_s7_read_write_s7_var_request_parameter_item_serialize(io, (void*) _value);
           if(_res != OK) {
             return _res;
           }
@@ -343,7 +343,7 @@
     case plc4c_s7_read_write_s7_parameter_type_plc4c_s7_read_write_s7_parameter_write_var_response: {
 
       // Simple Field (numItems)
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, _message->s7_parameter_write_var_response_num_items);
+      _res = plc4c_spi_write_unsigned_byte(io, 8, _message->s7_parameter_write_var_response_num_items);
       if(_res != OK) {
         return _res;
       }
@@ -353,7 +353,7 @@
     case plc4c_s7_read_write_s7_parameter_type_plc4c_s7_read_write_s7_parameter_user_data: {
 
       // Implicit Field (numItems) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, plc4c_spi_evaluation_helper_count(_message->s7_parameter_user_data_items));
+      _res = plc4c_spi_write_unsigned_byte(io, 8, plc4c_spi_evaluation_helper_count(_message->s7_parameter_user_data_items));
       if(_res != OK) {
         return _res;
       }
@@ -364,7 +364,7 @@
         for(int curItem = 0; curItem < itemCount; curItem++) {
           bool lastItem = curItem == (itemCount - 1);
           plc4c_s7_read_write_s7_parameter_user_data_item* _value = (plc4c_s7_read_write_s7_parameter_user_data_item*) plc4c_utils_list_get_value(_message->s7_parameter_user_data_items, curItem);
-          _res = plc4c_s7_read_write_s7_parameter_user_data_item_serialize(buf, (void*) _value);
+          _res = plc4c_s7_read_write_s7_parameter_user_data_item_serialize(io, (void*) _value);
           if(_res != OK) {
             return _res;
           }
diff --git a/sandbox/plc4c/generated-sources/s7/src/s7_parameter_user_data_item.c b/sandbox/plc4c/generated-sources/s7/src/s7_parameter_user_data_item.c
index 5b683aa..60d49f1 100644
--- a/sandbox/plc4c/generated-sources/s7/src/s7_parameter_user_data_item.c
+++ b/sandbox/plc4c/generated-sources/s7/src/s7_parameter_user_data_item.c
@@ -43,8 +43,8 @@
 
 
 // Parse function.
-plc4c_return_code plc4c_s7_read_write_s7_parameter_user_data_item_parse(plc4c_spi_read_buffer* buf, plc4c_s7_read_write_s7_parameter_user_data_item** _message) {
-  uint16_t startPos = plc4c_spi_read_get_pos(buf);
+plc4c_return_code plc4c_s7_read_write_s7_parameter_user_data_item_parse(plc4c_spi_read_buffer* io, plc4c_s7_read_write_s7_parameter_user_data_item** _message) {
+  uint16_t startPos = plc4c_spi_read_get_pos(io);
   uint16_t curPos;
   plc4c_return_code _res = OK;
 
@@ -56,7 +56,7 @@
 
   // Discriminator Field (itemType) (Used as input to a switch field)
   uint8_t itemType = 0;
-  _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &itemType);
+  _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &itemType);
   if(_res != OK) {
     return _res;
   }
@@ -67,7 +67,7 @@
                     
     // Implicit Field (itemLength) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
     uint8_t itemLength = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &itemLength);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &itemLength);
     if(_res != OK) {
       return _res;
     }
@@ -76,7 +76,7 @@
                     
     // Simple Field (method)
     uint8_t method = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &method);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &method);
     if(_res != OK) {
       return _res;
     }
@@ -86,7 +86,7 @@
                     
     // Simple Field (cpuFunctionType)
     unsigned int cpuFunctionType = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 4, (uint8_t*) &cpuFunctionType);
+    _res = plc4c_spi_read_unsigned_byte(io, 4, (uint8_t*) &cpuFunctionType);
     if(_res != OK) {
       return _res;
     }
@@ -96,7 +96,7 @@
                     
     // Simple Field (cpuFunctionGroup)
     unsigned int cpuFunctionGroup = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 4, (uint8_t*) &cpuFunctionGroup);
+    _res = plc4c_spi_read_unsigned_byte(io, 4, (uint8_t*) &cpuFunctionGroup);
     if(_res != OK) {
       return _res;
     }
@@ -106,7 +106,7 @@
                     
     // Simple Field (cpuSubfunction)
     uint8_t cpuSubfunction = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &cpuSubfunction);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &cpuSubfunction);
     if(_res != OK) {
       return _res;
     }
@@ -116,7 +116,7 @@
                     
     // Simple Field (sequenceNumber)
     uint8_t sequenceNumber = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &sequenceNumber);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &sequenceNumber);
     if(_res != OK) {
       return _res;
     }
@@ -132,7 +132,7 @@
         return NO_MEMORY;
       }
       *dataUnitReferenceNumber = 0;
-      _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) dataUnitReferenceNumber);
+      _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) dataUnitReferenceNumber);
       if(_res != OK) {
         return _res;
       }
@@ -151,7 +151,7 @@
         return NO_MEMORY;
       }
       *lastDataUnit = 0;
-      _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) lastDataUnit);
+      _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) lastDataUnit);
       if(_res != OK) {
         return _res;
       }
@@ -170,7 +170,7 @@
         return NO_MEMORY;
       }
       *errorCode = 0;
-      _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) errorCode);
+      _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) errorCode);
       if(_res != OK) {
         return _res;
       }
@@ -184,55 +184,55 @@
   return OK;
 }
 
-plc4c_return_code plc4c_s7_read_write_s7_parameter_user_data_item_serialize(plc4c_spi_write_buffer* buf, plc4c_s7_read_write_s7_parameter_user_data_item* _message) {
+plc4c_return_code plc4c_s7_read_write_s7_parameter_user_data_item_serialize(plc4c_spi_write_buffer* io, plc4c_s7_read_write_s7_parameter_user_data_item* _message) {
   plc4c_return_code _res = OK;
 
   // Discriminator Field (itemType)
-  plc4c_spi_write_unsigned_byte(buf, 8, plc4c_s7_read_write_s7_parameter_user_data_item_get_discriminator(_message->_type).itemType);
+  plc4c_spi_write_unsigned_byte(io, 8, plc4c_s7_read_write_s7_parameter_user_data_item_get_discriminator(_message->_type).itemType);
 
   // Switch Field (Depending of the current type, serialize the sub-type elements)
   switch(_message->_type) {
     case plc4c_s7_read_write_s7_parameter_user_data_item_type_plc4c_s7_read_write_s7_parameter_user_data_item_cpu_functions: {
 
       // Implicit Field (itemLength) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, (plc4c_s7_read_write_s7_parameter_user_data_item_length_in_bytes(_message)) - (2));
+      _res = plc4c_spi_write_unsigned_byte(io, 8, (plc4c_s7_read_write_s7_parameter_user_data_item_length_in_bytes(_message)) - (2));
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (method)
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, _message->s7_parameter_user_data_item_cpu_functions_method);
+      _res = plc4c_spi_write_unsigned_byte(io, 8, _message->s7_parameter_user_data_item_cpu_functions_method);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (cpuFunctionType)
-      _res = plc4c_spi_write_unsigned_byte(buf, 4, _message->s7_parameter_user_data_item_cpu_functions_cpu_function_type);
+      _res = plc4c_spi_write_unsigned_byte(io, 4, _message->s7_parameter_user_data_item_cpu_functions_cpu_function_type);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (cpuFunctionGroup)
-      _res = plc4c_spi_write_unsigned_byte(buf, 4, _message->s7_parameter_user_data_item_cpu_functions_cpu_function_group);
+      _res = plc4c_spi_write_unsigned_byte(io, 4, _message->s7_parameter_user_data_item_cpu_functions_cpu_function_group);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (cpuSubfunction)
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, _message->s7_parameter_user_data_item_cpu_functions_cpu_subfunction);
+      _res = plc4c_spi_write_unsigned_byte(io, 8, _message->s7_parameter_user_data_item_cpu_functions_cpu_subfunction);
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (sequenceNumber)
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, _message->s7_parameter_user_data_item_cpu_functions_sequence_number);
+      _res = plc4c_spi_write_unsigned_byte(io, 8, _message->s7_parameter_user_data_item_cpu_functions_sequence_number);
       if(_res != OK) {
         return _res;
       }
 
       // Optional Field (dataUnitReferenceNumber)
       if(_message->s7_parameter_user_data_item_cpu_functions_data_unit_reference_number != NULL) {
-        _res = plc4c_spi_write_unsigned_byte(buf, 8, *_message->s7_parameter_user_data_item_cpu_functions_data_unit_reference_number);
+        _res = plc4c_spi_write_unsigned_byte(io, 8, *_message->s7_parameter_user_data_item_cpu_functions_data_unit_reference_number);
         if(_res != OK) {
           return _res;
         }
@@ -240,7 +240,7 @@
 
       // Optional Field (lastDataUnit)
       if(_message->s7_parameter_user_data_item_cpu_functions_last_data_unit != NULL) {
-        _res = plc4c_spi_write_unsigned_byte(buf, 8, *_message->s7_parameter_user_data_item_cpu_functions_last_data_unit);
+        _res = plc4c_spi_write_unsigned_byte(io, 8, *_message->s7_parameter_user_data_item_cpu_functions_last_data_unit);
         if(_res != OK) {
           return _res;
         }
@@ -248,7 +248,7 @@
 
       // Optional Field (errorCode)
       if(_message->s7_parameter_user_data_item_cpu_functions_error_code != NULL) {
-        _res = plc4c_spi_write_unsigned_short(buf, 16, *_message->s7_parameter_user_data_item_cpu_functions_error_code);
+        _res = plc4c_spi_write_unsigned_short(io, 16, *_message->s7_parameter_user_data_item_cpu_functions_error_code);
         if(_res != OK) {
           return _res;
         }
diff --git a/sandbox/plc4c/generated-sources/s7/src/s7_payload.c b/sandbox/plc4c/generated-sources/s7/src/s7_payload.c
index 3911426..a273679 100644
--- a/sandbox/plc4c/generated-sources/s7/src/s7_payload.c
+++ b/sandbox/plc4c/generated-sources/s7/src/s7_payload.c
@@ -49,8 +49,8 @@
 
 
 // Parse function.
-plc4c_return_code plc4c_s7_read_write_s7_payload_parse(plc4c_spi_read_buffer* buf, uint8_t messageType, plc4c_s7_read_write_s7_parameter* parameter, plc4c_s7_read_write_s7_payload** _message) {
-  uint16_t startPos = plc4c_spi_read_get_pos(buf);
+plc4c_return_code plc4c_s7_read_write_s7_payload_parse(plc4c_spi_read_buffer* io, uint8_t messageType, plc4c_s7_read_write_s7_parameter* parameter, plc4c_s7_read_write_s7_payload** _message) {
+  uint16_t startPos = plc4c_spi_read_get_pos(io);
   uint16_t curPos;
   plc4c_return_code _res = OK;
 
@@ -75,8 +75,8 @@
       uint8_t itemCount = ((plc4c_s7_read_write_s7_parameter*) (parameter))->s7_parameter_read_var_response_num_items;
       for(int curItem = 0; curItem < itemCount; curItem++) {
         bool lastItem = curItem == (itemCount - 1);
-                          plc4c_list* _value = NULL;
-        _res = plc4c_s7_read_write_s7_var_payload_data_item_parse(buf, lastItem, (void*) &_value);
+        plc4c_s7_read_write_s7_var_payload_data_item* _value = NULL;
+        _res = plc4c_s7_read_write_s7_var_payload_data_item_parse(io, lastItem, (void*) &_value);
         if(_res != OK) {
           return _res;
         }
@@ -100,8 +100,8 @@
       uint8_t itemCount = plc4c_spi_evaluation_helper_count(((plc4c_s7_read_write_s7_parameter*) (parameter))->s7_parameter_write_var_request_items);
       for(int curItem = 0; curItem < itemCount; curItem++) {
         bool lastItem = curItem == (itemCount - 1);
-                          plc4c_list* _value = NULL;
-        _res = plc4c_s7_read_write_s7_var_payload_data_item_parse(buf, lastItem, (void*) &_value);
+        plc4c_s7_read_write_s7_var_payload_data_item* _value = NULL;
+        _res = plc4c_s7_read_write_s7_var_payload_data_item_parse(io, lastItem, (void*) &_value);
         if(_res != OK) {
           return _res;
         }
@@ -125,8 +125,8 @@
       uint8_t itemCount = ((plc4c_s7_read_write_s7_parameter*) (parameter))->s7_parameter_write_var_response_num_items;
       for(int curItem = 0; curItem < itemCount; curItem++) {
         bool lastItem = curItem == (itemCount - 1);
-                          plc4c_list* _value = NULL;
-        _res = plc4c_s7_read_write_s7_var_payload_status_item_parse(buf, (void*) &_value);
+        plc4c_s7_read_write_s7_var_payload_status_item* _value = NULL;
+        _res = plc4c_s7_read_write_s7_var_payload_status_item_parse(io, (void*) &_value);
         if(_res != OK) {
           return _res;
         }
@@ -150,8 +150,8 @@
       uint8_t itemCount = plc4c_spi_evaluation_helper_count(((plc4c_s7_read_write_s7_parameter*) (parameter))->s7_parameter_user_data_items);
       for(int curItem = 0; curItem < itemCount; curItem++) {
         bool lastItem = curItem == (itemCount - 1);
-                          plc4c_list* _value = NULL;
-        _res = plc4c_s7_read_write_s7_payload_user_data_item_parse(buf, ((plc4c_s7_read_write_s7_parameter_user_data_item*) (plc4c_utils_list_get_value(((plc4c_s7_read_write_s7_parameter*) (parameter))->s7_parameter_user_data_items, 0)))->s7_parameter_user_data_item_cpu_functions_cpu_function_type, (void*) &_value);
+        plc4c_s7_read_write_s7_payload_user_data_item* _value = NULL;
+        _res = plc4c_s7_read_write_s7_payload_user_data_item_parse(io, ((plc4c_s7_read_write_s7_parameter_user_data_item*) (plc4c_utils_list_get_value(((plc4c_s7_read_write_s7_parameter*) (parameter))->s7_parameter_user_data_items, 0)))->s7_parameter_user_data_item_cpu_functions_cpu_function_type, (void*) &_value);
         if(_res != OK) {
           return _res;
         }
@@ -165,7 +165,7 @@
   return OK;
 }
 
-plc4c_return_code plc4c_s7_read_write_s7_payload_serialize(plc4c_spi_write_buffer* buf, plc4c_s7_read_write_s7_payload* _message) {
+plc4c_return_code plc4c_s7_read_write_s7_payload_serialize(plc4c_spi_write_buffer* io, plc4c_s7_read_write_s7_payload* _message) {
   plc4c_return_code _res = OK;
 
   // Switch Field (Depending of the current type, serialize the sub-type elements)
@@ -178,7 +178,7 @@
         for(int curItem = 0; curItem < itemCount; curItem++) {
           bool lastItem = curItem == (itemCount - 1);
           plc4c_s7_read_write_s7_var_payload_data_item* _value = (plc4c_s7_read_write_s7_var_payload_data_item*) plc4c_utils_list_get_value(_message->s7_payload_read_var_response_items, curItem);
-          _res = plc4c_s7_read_write_s7_var_payload_data_item_serialize(buf, (void*) _value, lastItem);
+          _res = plc4c_s7_read_write_s7_var_payload_data_item_serialize(io, (void*) _value, lastItem);
           if(_res != OK) {
             return _res;
           }
@@ -195,7 +195,7 @@
         for(int curItem = 0; curItem < itemCount; curItem++) {
           bool lastItem = curItem == (itemCount - 1);
           plc4c_s7_read_write_s7_var_payload_data_item* _value = (plc4c_s7_read_write_s7_var_payload_data_item*) plc4c_utils_list_get_value(_message->s7_payload_write_var_request_items, curItem);
-          _res = plc4c_s7_read_write_s7_var_payload_data_item_serialize(buf, (void*) _value, lastItem);
+          _res = plc4c_s7_read_write_s7_var_payload_data_item_serialize(io, (void*) _value, lastItem);
           if(_res != OK) {
             return _res;
           }
@@ -212,7 +212,7 @@
         for(int curItem = 0; curItem < itemCount; curItem++) {
           bool lastItem = curItem == (itemCount - 1);
           plc4c_s7_read_write_s7_var_payload_status_item* _value = (plc4c_s7_read_write_s7_var_payload_status_item*) plc4c_utils_list_get_value(_message->s7_payload_write_var_response_items, curItem);
-          _res = plc4c_s7_read_write_s7_var_payload_status_item_serialize(buf, (void*) _value);
+          _res = plc4c_s7_read_write_s7_var_payload_status_item_serialize(io, (void*) _value);
           if(_res != OK) {
             return _res;
           }
@@ -229,7 +229,7 @@
         for(int curItem = 0; curItem < itemCount; curItem++) {
           bool lastItem = curItem == (itemCount - 1);
           plc4c_s7_read_write_s7_payload_user_data_item* _value = (plc4c_s7_read_write_s7_payload_user_data_item*) plc4c_utils_list_get_value(_message->s7_payload_user_data_items, curItem);
-          _res = plc4c_s7_read_write_s7_payload_user_data_item_serialize(buf, (void*) _value);
+          _res = plc4c_s7_read_write_s7_payload_user_data_item_serialize(io, (void*) _value);
           if(_res != OK) {
             return _res;
           }
diff --git a/sandbox/plc4c/generated-sources/s7/src/s7_payload_user_data_item.c b/sandbox/plc4c/generated-sources/s7/src/s7_payload_user_data_item.c
index ca75fb1..830f547 100644
--- a/sandbox/plc4c/generated-sources/s7/src/s7_payload_user_data_item.c
+++ b/sandbox/plc4c/generated-sources/s7/src/s7_payload_user_data_item.c
@@ -51,8 +51,8 @@
 }
 
 // Parse function.
-plc4c_return_code plc4c_s7_read_write_s7_payload_user_data_item_parse(plc4c_spi_read_buffer* buf, unsigned int cpuFunctionType, plc4c_s7_read_write_s7_payload_user_data_item** _message) {
-  uint16_t startPos = plc4c_spi_read_get_pos(buf);
+plc4c_return_code plc4c_s7_read_write_s7_payload_user_data_item_parse(plc4c_spi_read_buffer* io, unsigned int cpuFunctionType, plc4c_s7_read_write_s7_payload_user_data_item** _message) {
+  uint16_t startPos = plc4c_spi_read_get_pos(io);
   uint16_t curPos;
   plc4c_return_code _res = OK;
 
@@ -64,7 +64,7 @@
 
   // Enum field (returnCode)
   plc4c_s7_read_write_data_transport_error_code returnCode = plc4c_s7_read_write_data_transport_error_code_null();
-  _res = plc4c_spi_read_signed_byte(buf, 8, (int8_t*) &returnCode);
+  _res = plc4c_spi_read_signed_byte(io, 8, (int8_t*) &returnCode);
   if(_res != OK) {
     return _res;
   }
@@ -72,7 +72,7 @@
 
   // Enum field (transportSize)
   plc4c_s7_read_write_data_transport_size transportSize = plc4c_s7_read_write_data_transport_size_null();
-  _res = plc4c_spi_read_signed_byte(buf, 8, (int8_t*) &transportSize);
+  _res = plc4c_spi_read_signed_byte(io, 8, (int8_t*) &transportSize);
   if(_res != OK) {
     return _res;
   }
@@ -80,14 +80,14 @@
 
   // Implicit Field (dataLength) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
   uint16_t dataLength = 0;
-  _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &dataLength);
+  _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &dataLength);
   if(_res != OK) {
     return _res;
   }
 
   // Simple Field (szlId)
   plc4c_s7_read_write_szl_id* szlId;
-  _res = plc4c_s7_read_write_szl_id_parse(buf, (void*) &szlId);
+  _res = plc4c_s7_read_write_szl_id_parse(io, (void*) &szlId);
   if(_res != OK) {
     return _res;
   }
@@ -95,7 +95,7 @@
 
   // Simple Field (szlIndex)
   uint16_t szlIndex = 0;
-  _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &szlIndex);
+  _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &szlIndex);
   if(_res != OK) {
     return _res;
   }
@@ -110,7 +110,7 @@
                     
     // Const Field (szlItemLength)
     uint16_t szlItemLength = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &szlItemLength);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &szlItemLength);
     if(_res != OK) {
       return _res;
     }
@@ -123,7 +123,7 @@
                     
     // Implicit Field (szlItemCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
     uint16_t szlItemCount = 0;
-    _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &szlItemCount);
+    _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &szlItemCount);
     if(_res != OK) {
       return _res;
     }
@@ -141,8 +141,8 @@
       uint8_t itemCount = szlItemCount;
       for(int curItem = 0; curItem < itemCount; curItem++) {
         bool lastItem = curItem == (itemCount - 1);
-                          plc4c_list* _value = NULL;
-        _res = plc4c_s7_read_write_szl_data_tree_item_parse(buf, (void*) &_value);
+        plc4c_s7_read_write_szl_data_tree_item* _value = NULL;
+        _res = plc4c_s7_read_write_szl_data_tree_item_parse(io, (void*) &_value);
         if(_res != OK) {
           return _res;
         }
@@ -156,35 +156,35 @@
   return OK;
 }
 
-plc4c_return_code plc4c_s7_read_write_s7_payload_user_data_item_serialize(plc4c_spi_write_buffer* buf, plc4c_s7_read_write_s7_payload_user_data_item* _message) {
+plc4c_return_code plc4c_s7_read_write_s7_payload_user_data_item_serialize(plc4c_spi_write_buffer* io, plc4c_s7_read_write_s7_payload_user_data_item* _message) {
   plc4c_return_code _res = OK;
 
   // Enum field (returnCode)
-  _res = plc4c_spi_write_signed_byte(buf, 8, _message->return_code);
+  _res = plc4c_spi_write_signed_byte(io, 8, _message->return_code);
   if(_res != OK) {
     return _res;
   }
 
   // Enum field (transportSize)
-  _res = plc4c_spi_write_signed_byte(buf, 8, _message->transport_size);
+  _res = plc4c_spi_write_signed_byte(io, 8, _message->transport_size);
   if(_res != OK) {
     return _res;
   }
 
   // Implicit Field (dataLength) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-  _res = plc4c_spi_write_unsigned_short(buf, 16, (plc4c_s7_read_write_s7_payload_user_data_item_length_in_bytes(_message)) - (4));
+  _res = plc4c_spi_write_unsigned_short(io, 16, (plc4c_s7_read_write_s7_payload_user_data_item_length_in_bytes(_message)) - (4));
   if(_res != OK) {
     return _res;
   }
 
   // Simple Field (szlId)
-  _res = plc4c_s7_read_write_szl_id_serialize(buf, _message->szl_id);
+  _res = plc4c_s7_read_write_szl_id_serialize(io, _message->szl_id);
   if(_res != OK) {
     return _res;
   }
 
   // Simple Field (szlIndex)
-  _res = plc4c_spi_write_unsigned_short(buf, 16, _message->szl_index);
+  _res = plc4c_spi_write_unsigned_short(io, 16, _message->szl_index);
   if(_res != OK) {
     return _res;
   }
@@ -198,10 +198,10 @@
     case plc4c_s7_read_write_s7_payload_user_data_item_type_plc4c_s7_read_write_s7_payload_user_data_item_cpu_function_read_szl_response: {
 
       // Const Field (szlItemLength)
-      plc4c_spi_write_unsigned_short(buf, 16, PLC4C_S7_READ_WRITE_S7_PAYLOAD_USER_DATA_ITEM_CPU_FUNCTION_READ_SZL_RESPONSE_SZL_ITEM_LENGTH());
+      plc4c_spi_write_unsigned_short(io, 16, PLC4C_S7_READ_WRITE_S7_PAYLOAD_USER_DATA_ITEM_CPU_FUNCTION_READ_SZL_RESPONSE_SZL_ITEM_LENGTH());
 
       // Implicit Field (szlItemCount) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-      _res = plc4c_spi_write_unsigned_short(buf, 16, plc4c_spi_evaluation_helper_count(_message->s7_payload_user_data_item_cpu_function_read_szl_response_items));
+      _res = plc4c_spi_write_unsigned_short(io, 16, plc4c_spi_evaluation_helper_count(_message->s7_payload_user_data_item_cpu_function_read_szl_response_items));
       if(_res != OK) {
         return _res;
       }
@@ -212,7 +212,7 @@
         for(int curItem = 0; curItem < itemCount; curItem++) {
           bool lastItem = curItem == (itemCount - 1);
           plc4c_s7_read_write_szl_data_tree_item* _value = (plc4c_s7_read_write_szl_data_tree_item*) plc4c_utils_list_get_value(_message->s7_payload_user_data_item_cpu_function_read_szl_response_items, curItem);
-          _res = plc4c_s7_read_write_szl_data_tree_item_serialize(buf, (void*) _value);
+          _res = plc4c_s7_read_write_szl_data_tree_item_serialize(io, (void*) _value);
           if(_res != OK) {
             return _res;
           }
diff --git a/sandbox/plc4c/generated-sources/s7/src/s7_var_payload_data_item.c b/sandbox/plc4c/generated-sources/s7/src/s7_var_payload_data_item.c
index b7dbe3f..aa06042 100644
--- a/sandbox/plc4c/generated-sources/s7/src/s7_var_payload_data_item.c
+++ b/sandbox/plc4c/generated-sources/s7/src/s7_var_payload_data_item.c
@@ -23,8 +23,8 @@
 
 
 // Parse function.
-plc4c_return_code plc4c_s7_read_write_s7_var_payload_data_item_parse(plc4c_spi_read_buffer* buf, bool lastItem, plc4c_s7_read_write_s7_var_payload_data_item** _message) {
-  uint16_t startPos = plc4c_spi_read_get_pos(buf);
+plc4c_return_code plc4c_s7_read_write_s7_var_payload_data_item_parse(plc4c_spi_read_buffer* io, bool lastItem, plc4c_s7_read_write_s7_var_payload_data_item** _message) {
+  uint16_t startPos = plc4c_spi_read_get_pos(io);
   uint16_t curPos;
   plc4c_return_code _res = OK;
 
@@ -36,7 +36,7 @@
 
   // Enum field (returnCode)
   plc4c_s7_read_write_data_transport_error_code returnCode = plc4c_s7_read_write_data_transport_error_code_null();
-  _res = plc4c_spi_read_signed_byte(buf, 8, (int8_t*) &returnCode);
+  _res = plc4c_spi_read_signed_byte(io, 8, (int8_t*) &returnCode);
   if(_res != OK) {
     return _res;
   }
@@ -44,7 +44,7 @@
 
   // Enum field (transportSize)
   plc4c_s7_read_write_data_transport_size transportSize = plc4c_s7_read_write_data_transport_size_null();
-  _res = plc4c_spi_read_signed_byte(buf, 8, (int8_t*) &transportSize);
+  _res = plc4c_spi_read_signed_byte(io, 8, (int8_t*) &transportSize);
   if(_res != OK) {
     return _res;
   }
@@ -52,7 +52,7 @@
 
   // Implicit Field (dataLength) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
   uint16_t dataLength = 0;
-  _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &dataLength);
+  _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &dataLength);
   if(_res != OK) {
     return _res;
   }
@@ -68,9 +68,8 @@
     uint8_t itemCount = ((plc4c_s7_read_write_data_transport_size_get_size_in_bits(transportSize)) ? plc4c_spi_evaluation_helper_ceil((dataLength) / (8.0)) : dataLength);
     for(int curItem = 0; curItem < itemCount; curItem++) {
       
-                
       int8_t* _value = malloc(sizeof(int8_t));
-      _res = plc4c_spi_read_signed_byte(buf, 8, (int8_t*) _value);
+      _res = plc4c_spi_read_signed_byte(io, 8, (int8_t*) _value);
       if(_res != OK) {
         return _res;
       }
@@ -81,11 +80,11 @@
 
   // Padding Field (padding)
   {
-    int _timesPadding = (int) ((plc4c_spi_read_has_more(buf, 8)) && (((lastItem) ? 0 : (plc4c_spi_evaluation_helper_count(data)) % (2))));
+    int _timesPadding = (int) ((plc4c_spi_read_has_more(io, 8)) && (((lastItem) ? 0 : (plc4c_spi_evaluation_helper_count(data)) % (2))));
     while (_timesPadding-- > 0) {
       // Just read the padding data and ignore it
       uint8_t _paddingValue = 0;
-      _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &_paddingValue);
+      _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &_paddingValue);
       if(_res != OK) {
         return _res;
       }
@@ -95,23 +94,23 @@
   return OK;
 }
 
-plc4c_return_code plc4c_s7_read_write_s7_var_payload_data_item_serialize(plc4c_spi_write_buffer* buf, plc4c_s7_read_write_s7_var_payload_data_item* _message, bool lastItem) {
+plc4c_return_code plc4c_s7_read_write_s7_var_payload_data_item_serialize(plc4c_spi_write_buffer* io, plc4c_s7_read_write_s7_var_payload_data_item* _message, bool lastItem) {
   plc4c_return_code _res = OK;
 
   // Enum field (returnCode)
-  _res = plc4c_spi_write_signed_byte(buf, 8, _message->return_code);
+  _res = plc4c_spi_write_signed_byte(io, 8, _message->return_code);
   if(_res != OK) {
     return _res;
   }
 
   // Enum field (transportSize)
-  _res = plc4c_spi_write_signed_byte(buf, 8, _message->transport_size);
+  _res = plc4c_spi_write_signed_byte(io, 8, _message->transport_size);
   if(_res != OK) {
     return _res;
   }
 
   // Implicit Field (dataLength) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-  _res = plc4c_spi_write_unsigned_short(buf, 16, (plc4c_spi_evaluation_helper_count(_message->data)) * ((((((_message->transport_size) == (plc4c_s7_read_write_data_transport_size_BIT))) ? 1 : (((plc4c_s7_read_write_data_transport_size_get_size_in_bits(_message->transport_size)) ? 8 : 1))))));
+  _res = plc4c_spi_write_unsigned_short(io, 16, (plc4c_spi_evaluation_helper_count(_message->data)) * ((((((_message->transport_size) == (plc4c_s7_read_write_data_transport_size_BIT))) ? 1 : (((plc4c_s7_read_write_data_transport_size_get_size_in_bits(_message->transport_size)) ? 8 : 1))))));
   if(_res != OK) {
     return _res;
   }
@@ -122,7 +121,7 @@
     for(int curItem = 0; curItem < itemCount; curItem++) {
 
       int8_t* _value = (int8_t*) plc4c_utils_list_get_value(_message->data, curItem);
-      plc4c_spi_write_signed_byte(buf, 8, *_value);
+      plc4c_spi_write_signed_byte(io, 8, *_value);
     }
   }
 
@@ -131,7 +130,7 @@
     int _timesPadding = (int) (((lastItem) ? 0 : (plc4c_spi_evaluation_helper_count(_message->data)) % (2)));
     while (_timesPadding-- > 0) {
       // Just output the default padding data
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, 0);
+      _res = plc4c_spi_write_unsigned_byte(io, 8, 0);
       if(_res != OK) {
         return _res;
       }
diff --git a/sandbox/plc4c/generated-sources/s7/src/s7_var_payload_status_item.c b/sandbox/plc4c/generated-sources/s7/src/s7_var_payload_status_item.c
index 7d4b955..94e9b04 100644
--- a/sandbox/plc4c/generated-sources/s7/src/s7_var_payload_status_item.c
+++ b/sandbox/plc4c/generated-sources/s7/src/s7_var_payload_status_item.c
@@ -23,8 +23,8 @@
 
 
 // Parse function.
-plc4c_return_code plc4c_s7_read_write_s7_var_payload_status_item_parse(plc4c_spi_read_buffer* buf, plc4c_s7_read_write_s7_var_payload_status_item** _message) {
-  uint16_t startPos = plc4c_spi_read_get_pos(buf);
+plc4c_return_code plc4c_s7_read_write_s7_var_payload_status_item_parse(plc4c_spi_read_buffer* io, plc4c_s7_read_write_s7_var_payload_status_item** _message) {
+  uint16_t startPos = plc4c_spi_read_get_pos(io);
   uint16_t curPos;
   plc4c_return_code _res = OK;
 
@@ -36,7 +36,7 @@
 
   // Enum field (returnCode)
   plc4c_s7_read_write_data_transport_error_code returnCode = plc4c_s7_read_write_data_transport_error_code_null();
-  _res = plc4c_spi_read_signed_byte(buf, 8, (int8_t*) &returnCode);
+  _res = plc4c_spi_read_signed_byte(io, 8, (int8_t*) &returnCode);
   if(_res != OK) {
     return _res;
   }
@@ -45,11 +45,11 @@
   return OK;
 }
 
-plc4c_return_code plc4c_s7_read_write_s7_var_payload_status_item_serialize(plc4c_spi_write_buffer* buf, plc4c_s7_read_write_s7_var_payload_status_item* _message) {
+plc4c_return_code plc4c_s7_read_write_s7_var_payload_status_item_serialize(plc4c_spi_write_buffer* io, plc4c_s7_read_write_s7_var_payload_status_item* _message) {
   plc4c_return_code _res = OK;
 
   // Enum field (returnCode)
-  _res = plc4c_spi_write_signed_byte(buf, 8, _message->return_code);
+  _res = plc4c_spi_write_signed_byte(io, 8, _message->return_code);
   if(_res != OK) {
     return _res;
   }
diff --git a/sandbox/plc4c/generated-sources/s7/src/s7_var_request_parameter_item.c b/sandbox/plc4c/generated-sources/s7/src/s7_var_request_parameter_item.c
index a6726bb..f4f48f2 100644
--- a/sandbox/plc4c/generated-sources/s7/src/s7_var_request_parameter_item.c
+++ b/sandbox/plc4c/generated-sources/s7/src/s7_var_request_parameter_item.c
@@ -43,8 +43,8 @@
 
 
 // Parse function.
-plc4c_return_code plc4c_s7_read_write_s7_var_request_parameter_item_parse(plc4c_spi_read_buffer* buf, plc4c_s7_read_write_s7_var_request_parameter_item** _message) {
-  uint16_t startPos = plc4c_spi_read_get_pos(buf);
+plc4c_return_code plc4c_s7_read_write_s7_var_request_parameter_item_parse(plc4c_spi_read_buffer* io, plc4c_s7_read_write_s7_var_request_parameter_item** _message) {
+  uint16_t startPos = plc4c_spi_read_get_pos(io);
   uint16_t curPos;
   plc4c_return_code _res = OK;
 
@@ -56,7 +56,7 @@
 
   // Discriminator Field (itemType) (Used as input to a switch field)
   uint8_t itemType = 0;
-  _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &itemType);
+  _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &itemType);
   if(_res != OK) {
     return _res;
   }
@@ -67,7 +67,7 @@
                     
     // Implicit Field (itemLength) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
     uint8_t itemLength = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &itemLength);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &itemLength);
     if(_res != OK) {
       return _res;
     }
@@ -76,7 +76,7 @@
                     
     // Simple Field (address)
     plc4c_s7_read_write_s7_address* address;
-    _res = plc4c_s7_read_write_s7_address_parse(buf, (void*) &address);
+    _res = plc4c_s7_read_write_s7_address_parse(io, (void*) &address);
     if(_res != OK) {
       return _res;
     }
@@ -87,24 +87,24 @@
   return OK;
 }
 
-plc4c_return_code plc4c_s7_read_write_s7_var_request_parameter_item_serialize(plc4c_spi_write_buffer* buf, plc4c_s7_read_write_s7_var_request_parameter_item* _message) {
+plc4c_return_code plc4c_s7_read_write_s7_var_request_parameter_item_serialize(plc4c_spi_write_buffer* io, plc4c_s7_read_write_s7_var_request_parameter_item* _message) {
   plc4c_return_code _res = OK;
 
   // Discriminator Field (itemType)
-  plc4c_spi_write_unsigned_byte(buf, 8, plc4c_s7_read_write_s7_var_request_parameter_item_get_discriminator(_message->_type).itemType);
+  plc4c_spi_write_unsigned_byte(io, 8, plc4c_s7_read_write_s7_var_request_parameter_item_get_discriminator(_message->_type).itemType);
 
   // Switch Field (Depending of the current type, serialize the sub-type elements)
   switch(_message->_type) {
     case plc4c_s7_read_write_s7_var_request_parameter_item_type_plc4c_s7_read_write_s7_var_request_parameter_item_address: {
 
       // Implicit Field (itemLength) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-      _res = plc4c_spi_write_unsigned_byte(buf, 8, plc4c_s7_read_write_s7_address_length_in_bytes(_message->s7_var_request_parameter_item_address_address));
+      _res = plc4c_spi_write_unsigned_byte(io, 8, plc4c_s7_read_write_s7_address_length_in_bytes(_message->s7_var_request_parameter_item_address_address));
       if(_res != OK) {
         return _res;
       }
 
       // Simple Field (address)
-      _res = plc4c_s7_read_write_s7_address_serialize(buf, _message->s7_var_request_parameter_item_address_address);
+      _res = plc4c_s7_read_write_s7_address_serialize(io, _message->s7_var_request_parameter_item_address_address);
       if(_res != OK) {
         return _res;
       }
diff --git a/sandbox/plc4c/generated-sources/s7/src/szl_data_tree_item.c b/sandbox/plc4c/generated-sources/s7/src/szl_data_tree_item.c
index ba34255..ab5b17a 100644
--- a/sandbox/plc4c/generated-sources/s7/src/szl_data_tree_item.c
+++ b/sandbox/plc4c/generated-sources/s7/src/szl_data_tree_item.c
@@ -23,8 +23,8 @@
 
 
 // Parse function.
-plc4c_return_code plc4c_s7_read_write_szl_data_tree_item_parse(plc4c_spi_read_buffer* buf, plc4c_s7_read_write_szl_data_tree_item** _message) {
-  uint16_t startPos = plc4c_spi_read_get_pos(buf);
+plc4c_return_code plc4c_s7_read_write_szl_data_tree_item_parse(plc4c_spi_read_buffer* io, plc4c_s7_read_write_szl_data_tree_item** _message) {
+  uint16_t startPos = plc4c_spi_read_get_pos(io);
   uint16_t curPos;
   plc4c_return_code _res = OK;
 
@@ -36,7 +36,7 @@
 
   // Simple Field (itemIndex)
   uint16_t itemIndex = 0;
-  _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &itemIndex);
+  _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &itemIndex);
   if(_res != OK) {
     return _res;
   }
@@ -53,9 +53,8 @@
     uint8_t itemCount = 20;
     for(int curItem = 0; curItem < itemCount; curItem++) {
       
-                
       int8_t* _value = malloc(sizeof(int8_t));
-      _res = plc4c_spi_read_signed_byte(buf, 8, (int8_t*) _value);
+      _res = plc4c_spi_read_signed_byte(io, 8, (int8_t*) _value);
       if(_res != OK) {
         return _res;
       }
@@ -66,7 +65,7 @@
 
   // Simple Field (moduleTypeId)
   uint16_t moduleTypeId = 0;
-  _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &moduleTypeId);
+  _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &moduleTypeId);
   if(_res != OK) {
     return _res;
   }
@@ -74,7 +73,7 @@
 
   // Simple Field (ausbg)
   uint16_t ausbg = 0;
-  _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &ausbg);
+  _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &ausbg);
   if(_res != OK) {
     return _res;
   }
@@ -82,7 +81,7 @@
 
   // Simple Field (ausbe)
   uint16_t ausbe = 0;
-  _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &ausbe);
+  _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &ausbe);
   if(_res != OK) {
     return _res;
   }
@@ -91,11 +90,11 @@
   return OK;
 }
 
-plc4c_return_code plc4c_s7_read_write_szl_data_tree_item_serialize(plc4c_spi_write_buffer* buf, plc4c_s7_read_write_szl_data_tree_item* _message) {
+plc4c_return_code plc4c_s7_read_write_szl_data_tree_item_serialize(plc4c_spi_write_buffer* io, plc4c_s7_read_write_szl_data_tree_item* _message) {
   plc4c_return_code _res = OK;
 
   // Simple Field (itemIndex)
-  _res = plc4c_spi_write_unsigned_short(buf, 16, _message->item_index);
+  _res = plc4c_spi_write_unsigned_short(io, 16, _message->item_index);
   if(_res != OK) {
     return _res;
   }
@@ -106,24 +105,24 @@
     for(int curItem = 0; curItem < itemCount; curItem++) {
 
       int8_t* _value = (int8_t*) plc4c_utils_list_get_value(_message->mlfb, curItem);
-      plc4c_spi_write_signed_byte(buf, 8, *_value);
+      plc4c_spi_write_signed_byte(io, 8, *_value);
     }
   }
 
   // Simple Field (moduleTypeId)
-  _res = plc4c_spi_write_unsigned_short(buf, 16, _message->module_type_id);
+  _res = plc4c_spi_write_unsigned_short(io, 16, _message->module_type_id);
   if(_res != OK) {
     return _res;
   }
 
   // Simple Field (ausbg)
-  _res = plc4c_spi_write_unsigned_short(buf, 16, _message->ausbg);
+  _res = plc4c_spi_write_unsigned_short(io, 16, _message->ausbg);
   if(_res != OK) {
     return _res;
   }
 
   // Simple Field (ausbe)
-  _res = plc4c_spi_write_unsigned_short(buf, 16, _message->ausbe);
+  _res = plc4c_spi_write_unsigned_short(io, 16, _message->ausbe);
   if(_res != OK) {
     return _res;
   }
diff --git a/sandbox/plc4c/generated-sources/s7/src/szl_id.c b/sandbox/plc4c/generated-sources/s7/src/szl_id.c
index 78ac7ce..21a77ad 100644
--- a/sandbox/plc4c/generated-sources/s7/src/szl_id.c
+++ b/sandbox/plc4c/generated-sources/s7/src/szl_id.c
@@ -23,8 +23,8 @@
 
 
 // Parse function.
-plc4c_return_code plc4c_s7_read_write_szl_id_parse(plc4c_spi_read_buffer* buf, plc4c_s7_read_write_szl_id** _message) {
-  uint16_t startPos = plc4c_spi_read_get_pos(buf);
+plc4c_return_code plc4c_s7_read_write_szl_id_parse(plc4c_spi_read_buffer* io, plc4c_s7_read_write_szl_id** _message) {
+  uint16_t startPos = plc4c_spi_read_get_pos(io);
   uint16_t curPos;
   plc4c_return_code _res = OK;
 
@@ -36,7 +36,7 @@
 
   // Enum field (typeClass)
   plc4c_s7_read_write_szl_module_type_class typeClass = plc4c_s7_read_write_szl_module_type_class_null();
-  _res = plc4c_spi_read_signed_byte(buf, 4, (int8_t*) &typeClass);
+  _res = plc4c_spi_read_signed_byte(io, 4, (int8_t*) &typeClass);
   if(_res != OK) {
     return _res;
   }
@@ -44,7 +44,7 @@
 
   // Simple Field (sublistExtract)
   unsigned int sublistExtract = 0;
-  _res = plc4c_spi_read_unsigned_byte(buf, 4, (uint8_t*) &sublistExtract);
+  _res = plc4c_spi_read_unsigned_byte(io, 4, (uint8_t*) &sublistExtract);
   if(_res != OK) {
     return _res;
   }
@@ -52,7 +52,7 @@
 
   // Enum field (sublistList)
   plc4c_s7_read_write_szl_sublist sublistList = plc4c_s7_read_write_szl_sublist_null();
-  _res = plc4c_spi_read_signed_byte(buf, 8, (int8_t*) &sublistList);
+  _res = plc4c_spi_read_signed_byte(io, 8, (int8_t*) &sublistList);
   if(_res != OK) {
     return _res;
   }
@@ -61,23 +61,23 @@
   return OK;
 }
 
-plc4c_return_code plc4c_s7_read_write_szl_id_serialize(plc4c_spi_write_buffer* buf, plc4c_s7_read_write_szl_id* _message) {
+plc4c_return_code plc4c_s7_read_write_szl_id_serialize(plc4c_spi_write_buffer* io, plc4c_s7_read_write_szl_id* _message) {
   plc4c_return_code _res = OK;
 
   // Enum field (typeClass)
-  _res = plc4c_spi_write_signed_byte(buf, 4, _message->type_class);
+  _res = plc4c_spi_write_signed_byte(io, 4, _message->type_class);
   if(_res != OK) {
     return _res;
   }
 
   // Simple Field (sublistExtract)
-  _res = plc4c_spi_write_unsigned_byte(buf, 4, _message->sublist_extract);
+  _res = plc4c_spi_write_unsigned_byte(io, 4, _message->sublist_extract);
   if(_res != OK) {
     return _res;
   }
 
   // Enum field (sublistList)
-  _res = plc4c_spi_write_signed_byte(buf, 8, _message->sublist_list);
+  _res = plc4c_spi_write_signed_byte(io, 8, _message->sublist_list);
   if(_res != OK) {
     return _res;
   }
diff --git a/sandbox/plc4c/generated-sources/s7/src/szl_module_type_class.c b/sandbox/plc4c/generated-sources/s7/src/szl_module_type_class.c
index fe5ec8f..220cea1 100644
--- a/sandbox/plc4c/generated-sources/s7/src/szl_module_type_class.c
+++ b/sandbox/plc4c/generated-sources/s7/src/szl_module_type_class.c
@@ -18,6 +18,7 @@
 */
 
 #include "szl_module_type_class.h"
+#include <string.h>
 
 
 // Create an empty NULL-struct
@@ -27,3 +28,42 @@
   return plc4c_s7_read_write_szl_module_type_class_null_const;
 }
 
+plc4c_s7_read_write_szl_module_type_class plc4c_s7_read_write_szl_module_type_class_value_of(char* value_string) {
+    if(strcmp(value_string, "CPU") == 0) {
+        return 0x0;
+    }
+    if(strcmp(value_string, "IM") == 0) {
+        return 0x4;
+    }
+    if(strcmp(value_string, "FM") == 0) {
+        return 0x8;
+    }
+    if(strcmp(value_string, "CP") == 0) {
+        return 0xC;
+    }
+    return -1;
+}
+
+int plc4c_s7_read_write_szl_module_type_class_num_values() {
+  return 4;
+}
+
+plc4c_s7_read_write_szl_module_type_class plc4c_s7_read_write_szl_module_type_class_value_for_index(int index) {
+    switch(index) {
+      case 0: {
+        return 0x0;
+      }
+      case 1: {
+        return 0x4;
+      }
+      case 2: {
+        return 0x8;
+      }
+      case 3: {
+        return 0xC;
+      }
+      default: {
+        return -1;
+      }
+    }
+}
diff --git a/sandbox/plc4c/generated-sources/s7/src/szl_sublist.c b/sandbox/plc4c/generated-sources/s7/src/szl_sublist.c
index e33f462..b727b2f 100644
--- a/sandbox/plc4c/generated-sources/s7/src/szl_sublist.c
+++ b/sandbox/plc4c/generated-sources/s7/src/szl_sublist.c
@@ -18,6 +18,7 @@
 */
 
 #include "szl_sublist.h"
+#include <string.h>
 
 
 // Create an empty NULL-struct
@@ -27,3 +28,132 @@
   return plc4c_s7_read_write_szl_sublist_null_const;
 }
 
+plc4c_s7_read_write_szl_sublist plc4c_s7_read_write_szl_sublist_value_of(char* value_string) {
+    if(strcmp(value_string, "MODULE_IDENTIFICATION") == 0) {
+        return 0x11;
+    }
+    if(strcmp(value_string, "CPU_FEATURES") == 0) {
+        return 0x12;
+    }
+    if(strcmp(value_string, "USER_MEMORY_AREA") == 0) {
+        return 0x13;
+    }
+    if(strcmp(value_string, "SYSTEM_AREAS") == 0) {
+        return 0x14;
+    }
+    if(strcmp(value_string, "BLOCK_TYPES") == 0) {
+        return 0x15;
+    }
+    if(strcmp(value_string, "STATUS_MODULE_LEDS") == 0) {
+        return 0x19;
+    }
+    if(strcmp(value_string, "COMPONENT_IDENTIFICATION") == 0) {
+        return 0x1C;
+    }
+    if(strcmp(value_string, "INTERRUPT_STATUS") == 0) {
+        return 0x22;
+    }
+    if(strcmp(value_string, "ASSIGNMENT_BETWEEN_PROCESS_IMAGE_PARTITIONS_AND_OBS") == 0) {
+        return 0x25;
+    }
+    if(strcmp(value_string, "COMMUNICATION_STATUS_DATA") == 0) {
+        return 0x32;
+    }
+    if(strcmp(value_string, "STATUS_SINGLE_MODULE_LED") == 0) {
+        return 0x74;
+    }
+    if(strcmp(value_string, "DP_MASTER_SYSTEM_INFORMATION") == 0) {
+        return 0x90;
+    }
+    if(strcmp(value_string, "MODULE_STATUS_INFORMATION") == 0) {
+        return 0x91;
+    }
+    if(strcmp(value_string, "RACK_OR_STATION_STATUS_INFORMATION") == 0) {
+        return 0x92;
+    }
+    if(strcmp(value_string, "RACK_OR_STATION_STATUS_INFORMATION_2") == 0) {
+        return 0x94;
+    }
+    if(strcmp(value_string, "ADDITIONAL_DP_MASTER_SYSTEM_OR_PROFINET_IO_SYSTEM_INFORMATION") == 0) {
+        return 0x95;
+    }
+    if(strcmp(value_string, "MODULE_STATUS_INFORMATION_PROFINET_IO_AND_PROFIBUS_DP") == 0) {
+        return 0x96;
+    }
+    if(strcmp(value_string, "DIAGNOSTIC_BUFFER") == 0) {
+        return 0xA0;
+    }
+    if(strcmp(value_string, "MODULE_DIAGNOSTIC_DATA") == 0) {
+        return 0xB1;
+    }
+    return -1;
+}
+
+int plc4c_s7_read_write_szl_sublist_num_values() {
+  return 19;
+}
+
+plc4c_s7_read_write_szl_sublist plc4c_s7_read_write_szl_sublist_value_for_index(int index) {
+    switch(index) {
+      case 0: {
+        return 0x11;
+      }
+      case 1: {
+        return 0x12;
+      }
+      case 2: {
+        return 0x13;
+      }
+      case 3: {
+        return 0x14;
+      }
+      case 4: {
+        return 0x15;
+      }
+      case 5: {
+        return 0x19;
+      }
+      case 6: {
+        return 0x1C;
+      }
+      case 7: {
+        return 0x22;
+      }
+      case 8: {
+        return 0x25;
+      }
+      case 9: {
+        return 0x32;
+      }
+      case 10: {
+        return 0x74;
+      }
+      case 11: {
+        return 0x90;
+      }
+      case 12: {
+        return 0x91;
+      }
+      case 13: {
+        return 0x92;
+      }
+      case 14: {
+        return 0x94;
+      }
+      case 15: {
+        return 0x95;
+      }
+      case 16: {
+        return 0x96;
+      }
+      case 17: {
+        return 0xA0;
+      }
+      case 18: {
+        return 0xB1;
+      }
+      default: {
+        return -1;
+      }
+    }
+}
diff --git a/sandbox/plc4c/generated-sources/s7/src/tpkt_packet.c b/sandbox/plc4c/generated-sources/s7/src/tpkt_packet.c
index 05d51cc..28145d8 100644
--- a/sandbox/plc4c/generated-sources/s7/src/tpkt_packet.c
+++ b/sandbox/plc4c/generated-sources/s7/src/tpkt_packet.c
@@ -29,8 +29,8 @@
 }
 
 // Parse function.
-plc4c_return_code plc4c_s7_read_write_tpkt_packet_parse(plc4c_spi_read_buffer* buf, plc4c_s7_read_write_tpkt_packet** _message) {
-  uint16_t startPos = plc4c_spi_read_get_pos(buf);
+plc4c_return_code plc4c_s7_read_write_tpkt_packet_parse(plc4c_spi_read_buffer* io, plc4c_s7_read_write_tpkt_packet** _message) {
+  uint16_t startPos = plc4c_spi_read_get_pos(io);
   uint16_t curPos;
   plc4c_return_code _res = OK;
 
@@ -42,7 +42,7 @@
 
   // Const Field (protocolId)
   uint8_t protocolId = 0;
-  _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &protocolId);
+  _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &protocolId);
   if(_res != OK) {
     return _res;
   }
@@ -54,7 +54,7 @@
   // Reserved Field (Compartmentalized so the "reserved" variable can't leak)
   {
     uint8_t _reserved = 0;
-    _res = plc4c_spi_read_unsigned_byte(buf, 8, (uint8_t*) &_reserved);
+    _res = plc4c_spi_read_unsigned_byte(io, 8, (uint8_t*) &_reserved);
     if(_res != OK) {
       return _res;
     }
@@ -65,14 +65,14 @@
 
   // Implicit Field (len) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
   uint16_t len = 0;
-  _res = plc4c_spi_read_unsigned_short(buf, 16, (uint16_t*) &len);
+  _res = plc4c_spi_read_unsigned_short(io, 16, (uint16_t*) &len);
   if(_res != OK) {
     return _res;
   }
 
   // Simple Field (payload)
   plc4c_s7_read_write_cotp_packet* payload;
-  _res = plc4c_s7_read_write_cotp_packet_parse(buf, (len) - (4), (void*) &payload);
+  _res = plc4c_s7_read_write_cotp_packet_parse(io, (len) - (4), (void*) &payload);
   if(_res != OK) {
     return _res;
   }
@@ -81,26 +81,26 @@
   return OK;
 }
 
-plc4c_return_code plc4c_s7_read_write_tpkt_packet_serialize(plc4c_spi_write_buffer* buf, plc4c_s7_read_write_tpkt_packet* _message) {
+plc4c_return_code plc4c_s7_read_write_tpkt_packet_serialize(plc4c_spi_write_buffer* io, plc4c_s7_read_write_tpkt_packet* _message) {
   plc4c_return_code _res = OK;
 
   // Const Field (protocolId)
-  plc4c_spi_write_unsigned_byte(buf, 8, PLC4C_S7_READ_WRITE_TPKT_PACKET_PROTOCOL_ID());
+  plc4c_spi_write_unsigned_byte(io, 8, PLC4C_S7_READ_WRITE_TPKT_PACKET_PROTOCOL_ID());
 
   // Reserved Field
-  _res = plc4c_spi_write_unsigned_byte(buf, 8, 0x00);
+  _res = plc4c_spi_write_unsigned_byte(io, 8, 0x00);
   if(_res != OK) {
     return _res;
   }
 
   // Implicit Field (len) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
-  _res = plc4c_spi_write_unsigned_short(buf, 16, (plc4c_s7_read_write_cotp_packet_length_in_bytes(_message->payload)) + (4));
+  _res = plc4c_spi_write_unsigned_short(io, 16, (plc4c_s7_read_write_cotp_packet_length_in_bytes(_message->payload)) + (4));
   if(_res != OK) {
     return _res;
   }
 
   // Simple Field (payload)
-  _res = plc4c_s7_read_write_cotp_packet_serialize(buf, _message->payload);
+  _res = plc4c_s7_read_write_cotp_packet_serialize(io, _message->payload);
   if(_res != OK) {
     return _res;
   }
diff --git a/sandbox/plc4c/generated-sources/s7/src/transport_size.c b/sandbox/plc4c/generated-sources/s7/src/transport_size.c
index e8cd2a9..24505a1 100644
--- a/sandbox/plc4c/generated-sources/s7/src/transport_size.c
+++ b/sandbox/plc4c/generated-sources/s7/src/transport_size.c
@@ -18,6 +18,7 @@
 */
 
 #include "transport_size.h"
+#include <string.h>
 
 #include "data_transport_size.h"
 #include "transport_size.h"
@@ -29,6 +30,117 @@
   return plc4c_s7_read_write_transport_size_null_const;
 }
 
+plc4c_s7_read_write_transport_size plc4c_s7_read_write_transport_size_value_of(char* value_string) {
+    if(strcmp(value_string, "LWORD") == 0) {
+        return 0x00;
+    }
+    if(strcmp(value_string, "BOOL") == 0) {
+        return 0x01;
+    }
+    if(strcmp(value_string, "BYTE") == 0) {
+        return 0x02;
+    }
+    if(strcmp(value_string, "CHAR") == 0) {
+        return 0x03;
+    }
+    if(strcmp(value_string, "WORD") == 0) {
+        return 0x04;
+    }
+    if(strcmp(value_string, "INT") == 0) {
+        return 0x05;
+    }
+    if(strcmp(value_string, "DWORD") == 0) {
+        return 0x06;
+    }
+    if(strcmp(value_string, "DINT") == 0) {
+        return 0x07;
+    }
+    if(strcmp(value_string, "REAL") == 0) {
+        return 0x08;
+    }
+    if(strcmp(value_string, "DATE") == 0) {
+        return 0x09;
+    }
+    if(strcmp(value_string, "TIME_OF_DAY") == 0) {
+        return 0x0A;
+    }
+    if(strcmp(value_string, "TIME") == 0) {
+        return 0x0B;
+    }
+    if(strcmp(value_string, "S5TIME") == 0) {
+        return 0x0C;
+    }
+    if(strcmp(value_string, "DATE_AND_TIME") == 0) {
+        return 0x0F;
+    }
+    if(strcmp(value_string, "WCHAR") == 0) {
+        return 0x13;
+    }
+    if(strcmp(value_string, "LREAL") == 0) {
+        return 0x30;
+    }
+    return -1;
+}
+
+int plc4c_s7_read_write_transport_size_num_values() {
+  return 25;
+}
+
+plc4c_s7_read_write_transport_size plc4c_s7_read_write_transport_size_value_for_index(int index) {
+    switch(index) {
+      case 0: {
+        return 0x00;
+      }
+      case 1: {
+        return 0x01;
+      }
+      case 2: {
+        return 0x02;
+      }
+      case 3: {
+        return 0x03;
+      }
+      case 4: {
+        return 0x04;
+      }
+      case 5: {
+        return 0x05;
+      }
+      case 6: {
+        return 0x06;
+      }
+      case 7: {
+        return 0x07;
+      }
+      case 8: {
+        return 0x08;
+      }
+      case 9: {
+        return 0x09;
+      }
+      case 10: {
+        return 0x0A;
+      }
+      case 11: {
+        return 0x0B;
+      }
+      case 12: {
+        return 0x0C;
+      }
+      case 13: {
+        return 0x0F;
+      }
+      case 14: {
+        return 0x13;
+      }
+      case 15: {
+        return 0x30;
+      }
+      default: {
+        return -1;
+      }
+    }
+}
 
 bool plc4c_s7_read_write_transport_size_get_supported__s7_300(plc4c_s7_read_write_transport_size value) {
   switch(value) {
diff --git a/sandbox/plc4c/spi/include/plc4c/spi/read_buffer.h b/sandbox/plc4c/spi/include/plc4c/spi/read_buffer.h
index 9604d45..7489d88 100644
--- a/sandbox/plc4c/spi/include/plc4c/spi/read_buffer.h
+++ b/sandbox/plc4c/spi/include/plc4c/spi/read_buffer.h
@@ -88,4 +88,11 @@
 
 plc4c_return_code plc4c_spi_read_string(plc4c_spi_read_buffer* buf, uint8_t num_bits, char* encoding, char** value);
 
+/**
+ * Converts the bytes contained in a list into a '\0' terminated string.
+ * @param list of bytes
+ * @return '\0' terminated string
+ */
+char* list_to_string(plc4c_list* list);
+
 #endif  // PLC4C_READ_BUFFER_H_
\ No newline at end of file
diff --git a/sandbox/plc4c/spi/include/plc4c/spi/types_private.h b/sandbox/plc4c/spi/include/plc4c/spi/types_private.h
index f34dcfb..81a2049 100644
--- a/sandbox/plc4c/spi/include/plc4c/spi/types_private.h
+++ b/sandbox/plc4c/spi/include/plc4c/spi/types_private.h
@@ -25,6 +25,9 @@
 #include <plc4c/utils/list.h>
 #include <plc4c/utils/queue.h>
 
+#include "read_buffer.h"
+#include "write_buffer.h"
+
 typedef struct plc4c_item_t plc4c_item;
 typedef struct plc4c_driver_list_item_t plc4c_driver_list_item;
 typedef struct plc4c_transport_list_item_t plc4c_transport_list_item;
@@ -35,8 +38,11 @@
 typedef struct plc4c_response_subscription_item_t plc4c_response_subscription_item;
 typedef struct plc4c_response_unsubscription_item_t plc4c_response_unsubscription_item;
 
-typedef plc4c_item *(*plc4c_connection_parse_address_item)(
-    char *address_string);
+typedef plc4c_return_code (*plc4c_connection_configure_function)(
+    plc4c_list* parameters, void** configuration);
+
+typedef plc4c_return_code (*plc4c_connection_parse_address_item)(
+    char *address_string, void** encoded_address);
 
 typedef plc4c_return_code (*plc4c_connection_encode_value_item)(
     plc4c_item *item, void *value, void **encoded_value);
@@ -80,6 +86,32 @@
 typedef void (*plc4c_connect_free_unsubscription_response_function)(
     plc4c_unsubscription_response *response);
 
+typedef plc4c_return_code (*plc4c_transport_configure_function)(
+    plc4c_list* parameters, void** configuration);
+
+// TODO: Implement the argument.
+typedef plc4c_return_code (*plc4c_transport_open_function)(void* config);
+
+// TODO: Implement the argument.
+typedef plc4c_return_code (*plc4c_transport_close_function)(void* config);
+
+typedef plc4c_return_code (*plc4c_transport_send_message_function)(
+    void* transport_configuration, plc4c_spi_write_buffer* message);
+
+// Helper function that tells the transport what to do with the current input
+// on positive return value: a read-buffer with given number of bytes is
+// returned. RESPONSE_ACCEPT_INCOMPLETE or 0: Currently not enough data is
+// or this content is not applicable for the current task. Don't consume
+// anything and potentially re-check next time. If however the value is negative
+// the buffer seems to contain corrupt data, clean up by skipping the number of
+// bytes you get by making the negative value a positive and not returning any
+// read-buffer.
+typedef int16_t (*accept_message_function)(
+    uint8_t* data, uint16_t length);
+
+typedef plc4c_return_code (*plc4c_transport_select_message_function)(
+    void* transport_configuration, uint8_t min_size, accept_message_function accept_message, plc4c_spi_read_buffer** message);
+
 struct plc4c_system_t {
   /* drivers */
   plc4c_list *driver_list;
@@ -105,12 +137,14 @@
 
 struct plc4c_item_t {
   char *name;
+  void *address;
 };
 
 struct plc4c_driver_t {
   char *protocol_code;
   char *protocol_name;
   char *default_transport_code;
+  plc4c_connection_configure_function configure_function;
   plc4c_connection_parse_address_item parse_address_function;
   plc4c_connection_connect_function connect_function;
   plc4c_connection_disconnect_function disconnect_function;
@@ -129,10 +163,23 @@
   plc4c_driver_list_item *next;
 };
 
+struct plc4c_transport_message_t {
+  int length;
+  uint8_t data[];
+};
+
 struct plc4c_transport_t {
   char *transport_code;
+  char* transport_name;
 
-  // TODO: add the send and receive function references here ...
+  plc4c_transport_configure_function configure;
+  plc4c_transport_open_function open;
+  plc4c_transport_close_function close;
+  plc4c_transport_send_message_function send_message;
+  // Function that uses a function passed in to see if a given system-task
+  // will be able to consume the current content of the transports input
+  // buffer.
+  plc4c_transport_select_message_function select_message;
 };
 
 struct plc4c_transport_list_item_t {
@@ -145,7 +192,9 @@
   char *protocol_code;
   char *transport_code;
   char *transport_connect_information;
+  void *transport_configuration;
   char *parameters;
+  void *configuration;
 
   bool connected;
   // Internal flag indicating the connection should be disconnected
@@ -173,14 +222,17 @@
   size_t size;
   union {
     bool boolean_value;
-    char char_value;
-    unsigned char uchar_value;
-    short short_value;
-    unsigned short ushort_value;
-    int int_value;
-    unsigned int uint_value;
+    int8_t char_value;
+    uint8_t uchar_value;
+    int16_t short_value;
+    uint16_t ushort_value;
+    int32_t int_value;
+    uint32_t uint_value;
+    int64_t lint_value;
+    uint64_t ulint_value;
     /* more */
     float float_value;
+    double double_value;
     char *pstring_value;
     char *const_string_value;
     void *pvoid_value;
diff --git a/sandbox/plc4c/spi/src/connection.c b/sandbox/plc4c/spi/src/connection.c
index f3a1a53..370cefa 100644
--- a/sandbox/plc4c/spi/src/connection.c
+++ b/sandbox/plc4c/spi/src/connection.c
@@ -154,6 +154,11 @@
   connection->driver = driver;
 }
 
+void plc4c_connection_set_configuration(plc4c_connection *connection,
+                                        void *configuration) {
+  connection->configuration = configuration;
+}
+
 bool plc4c_connection_has_error(plc4c_connection *connection) { return false; }
 
 plc4c_return_code plc4c_connection_disconnect(plc4c_connection *connection) {
diff --git a/sandbox/plc4c/spi/src/data.c b/sandbox/plc4c/spi/src/data.c
index 53284dd..6654e44 100644
--- a/sandbox/plc4c/spi/src/data.c
+++ b/sandbox/plc4c/spi/src/data.c
@@ -24,83 +24,93 @@
 #include <stdint.h>
 #include <stdio.h>
 
-plc4c_data *plc4c_data_create_boolean_data(bool b) {
+plc4c_data *plc4c_data_create_bool_data(bool b) {
   plc4c_data *data = malloc(sizeof(plc4c_data));
   data->data_type = PLC4C_BOOL;
   data->size = sizeof(bool);
   data->data.boolean_value = b;
+  data->custom_destroy = NULL;
+  data->custom_printf = NULL;
   return data;
 }
 
-plc4c_data *plc4c_data_create_char_data(char c) {
+plc4c_data *plc4c_data_create_int8_t_data(int8_t c) {
   plc4c_data *data = malloc(sizeof(plc4c_data));
   data->data_type = PLC4C_CHAR;
   data->size = sizeof(char);
   data->data.char_value = c;
+  data->custom_destroy = NULL;
+  data->custom_printf = NULL;
   return data;
 }
 
-plc4c_data *plc4c_data_create_uchar_data(unsigned char uc) {
+plc4c_data *plc4c_data_create_uint8_t_data(uint8_t uc) {
   plc4c_data *data = malloc(sizeof(plc4c_data));
   data->data_type = PLC4C_UCHAR;
   data->size = sizeof(unsigned char);
   data->data.uchar_value = uc;
+  data->custom_destroy = NULL;
+  data->custom_printf = NULL;
   return data;
 }
 
-plc4c_data *plc4c_data_create_short_data(short s) {
+plc4c_data *plc4c_data_create_int16_t_data(int16_t s) {
   plc4c_data *data = malloc(sizeof(plc4c_data));
   data->data_type = PLC4C_SHORT;
   data->size = sizeof(short);
   data->data.short_value = s;
+  data->custom_destroy = NULL;
+  data->custom_printf = NULL;
   return data;
 }
 
-plc4c_data *plc4c_data_create_ushort_data(unsigned short us) {
+plc4c_data *plc4c_data_create_uint16_t_data(uint16_t us) {
   plc4c_data *data = malloc(sizeof(plc4c_data));
   data->data_type = PLC4C_USHORT;
   data->size = sizeof(unsigned short);
   data->data.ushort_value = us;
+  data->custom_destroy = NULL;
+  data->custom_printf = NULL;
   return data;
 }
 
-plc4c_data *plc4c_data_create_int_data(int i) {
+plc4c_data *plc4c_data_create_int32_t_data(int32_t i) {
   plc4c_data *data = malloc(sizeof(plc4c_data));
   data->data_type = PLC4C_INT;
   data->size = sizeof(int);
   data->data.int_value = i;
+  data->custom_destroy = NULL;
+  data->custom_printf = NULL;
   return data;
 }
 
-plc4c_data *plc4c_data_create_uint_data(unsigned int ui) {
+plc4c_data *plc4c_data_create_uint32_t_data(uint32_t ui) {
   plc4c_data *data = malloc(sizeof(plc4c_data));
   data->data_type = PLC4C_UINT;
   data->size = sizeof(unsigned int);
   data->data.uint_value = ui;
+  data->custom_destroy = NULL;
+  data->custom_printf = NULL;
   return data;
 }
 
-plc4c_data *plc4c_data_create_string_data(unsigned int size, char *s) {
+plc4c_data *plc4c_data_create_int64_t_data(int64_t i) {
   plc4c_data *data = malloc(sizeof(plc4c_data));
-  data->data_type = PLC4C_STRING_POINTER;
-  data->size = size;
-  data->data.pstring_value = s;
+  data->data_type = PLC4C_LINT;
+  data->size = sizeof(int);
+  data->data.lint_value = i;
+  data->custom_destroy = NULL;
+  data->custom_printf = NULL;
   return data;
 }
 
-plc4c_data *plc4c_data_create_constant_string_data(unsigned int size, char *s) {
+plc4c_data *plc4c_data_create_uint64_t_data(uint64_t ui) {
   plc4c_data *data = malloc(sizeof(plc4c_data));
-  data->data_type = PLC4C_CONSTANT_STRING;
-  data->size = size;
-  data->data.const_string_value = s;
-  return data;
-}
-
-plc4c_data *plc4c_data_create_void_pointer_data(void *v) {
-  plc4c_data *data = malloc(sizeof(plc4c_data));
-  data->data_type = PLC4C_VOID_POINTER;
-  data->size = 0;
-  data->data.pvoid_value = v;
+  data->data_type = PLC4C_ULINT;
+  data->size = sizeof(unsigned int);
+  data->data.ulint_value = ui;
+  data->custom_destroy = NULL;
+  data->custom_printf = NULL;
   return data;
 }
 
@@ -109,16 +119,61 @@
   data->data_type = PLC4C_FLOAT;
   data->size = sizeof(float);
   data->data.float_value = f;
+  data->custom_destroy = NULL;
+  data->custom_printf = NULL;
+  return data;
+}
+
+plc4c_data *plc4c_data_create_double_data(double d) {
+  plc4c_data *data = malloc(sizeof(plc4c_data));
+  data->data_type = PLC4C_DOUBLE;
+  data->size = sizeof(float);
+  data->data.double_value = d;
+  data->custom_destroy = NULL;
+  data->custom_printf = NULL;
+  return data;
+}
+
+plc4c_data *plc4c_data_create_string_data(unsigned int size, char *s) {
+  plc4c_data *data = malloc(sizeof(plc4c_data));
+  data->data_type = PLC4C_STRING_POINTER;
+  data->size = size;
+  data->data.pstring_value = s;
+  data->custom_destroy = NULL;
+  data->custom_printf = NULL;
+  return data;
+}
+
+plc4c_data *plc4c_data_create_constant_string_data(unsigned int size, char *s) {
+  plc4c_data *data = malloc(sizeof(plc4c_data));
+  data->data_type = PLC4C_CONSTANT_STRING;
+  data->size = size;
+  data->data.const_string_value = s;
+  data->custom_destroy = NULL;
+  data->custom_printf = NULL;
+  return data;
+}
+
+plc4c_data *plc4c_data_create_void_pointer_data(void *v) {
+  plc4c_data *data = malloc(sizeof(plc4c_data));
+  data->data_type = PLC4C_VOID_POINTER;
+  data->size = 0;
+  data->data.pvoid_value = v;
+  data->custom_destroy = NULL;
+  data->custom_printf = NULL;
   return data;
 }
 
 void plc4c_data_printf(plc4c_data *data) {
   switch (data->data_type) {
+    case PLC4C_BOOL:
+      printf("%s", data->data.boolean_value ? "true" : "false");
+      break;
     case PLC4C_CHAR:
-      printf("%c", data->data.char_value);
+      printf("%d", data->data.char_value);
       break;
     case PLC4C_UCHAR:
-      printf("%c", data->data.uchar_value);
+      printf("%d", data->data.uchar_value);
       break;
     case PLC4C_SHORT:
       printf("%d", data->data.short_value);
@@ -132,6 +187,12 @@
     case PLC4C_UINT:
       printf("%iu", data->data.uint_value);
       break;
+    case PLC4C_LINT:
+      printf("%d", data->data.lint_value);
+      break;
+    case PLC4C_ULINT:
+      printf("%d", data->data.ulint_value);
+      break;
     case PLC4C_FLOAT:
       printf("%f", data->data.float_value);
       break;
diff --git a/sandbox/plc4c/spi/src/evaluation_helper.c b/sandbox/plc4c/spi/src/evaluation_helper.c
index a0aff22..04c4197 100644
--- a/sandbox/plc4c/spi/src/evaluation_helper.c
+++ b/sandbox/plc4c/spi/src/evaluation_helper.c
@@ -34,3 +34,7 @@
   return plc4c_utils_list_size(a);
 }
 
+uint8_t plc4c_spi_evaluation_helper_array_size_in_bytes(plc4c_list* a) {
+  // TODO: This sort of can't work in C as we don't have the type information ...
+  return 0;
+}
diff --git a/sandbox/plc4c/spi/src/read.c b/sandbox/plc4c/spi/src/read.c
index 4b92265..5a0a41c 100644
--- a/sandbox/plc4c/spi/src/read.c
+++ b/sandbox/plc4c/spi/src/read.c
@@ -33,10 +33,14 @@
 }
 
 plc4c_return_code plc4c_read_request_add_item(plc4c_read_request *read_request,
-                                              char *address) {
-  plc4c_item *item =
-      read_request->connection->driver->parse_address_function(address);
-  plc4c_utils_list_insert_tail_value(read_request->items, item);
+                                              char* field_name, char *address) {
+  plc4c_item *item = malloc(sizeof(plc4c_item));
+  if(item == NULL) {
+    return NO_MEMORY;
+  }
+  item->name = field_name;
+  read_request->connection->driver->parse_address_function(address, &(item->address));
+  plc4c_utils_list_insert_head_value(read_request->items, item);
   return OK;
 }
 
@@ -46,21 +50,23 @@
   // Inject the default read context into the system task.
   plc4c_read_request_execution *new_read_request_execution =
       malloc(sizeof(plc4c_read_request_execution));
+  if(new_read_request_execution == NULL) {
+    return NO_MEMORY;
+  }
   new_read_request_execution->read_request = read_request;
   new_read_request_execution->read_response = NULL;
   new_read_request_execution->system_task = NULL;
 
-  plc4c_system_task *system_task;
-  plc4c_connection_get_driver(plc4c_read_request_get_connection(read_request))
-      ->read_function(new_read_request_execution, &system_task);
+  read_request->connection->driver->read_function(
+      new_read_request_execution, &(new_read_request_execution->system_task));
 
   // Increment the number of running tasks for this connection.
   plc4c_connection_task_added(read_request->connection);
   // Add the new task to the task-list.
-  plc4c_utils_list_insert_tail_value(
+  plc4c_utils_list_insert_head_value(
       plc4c_system_get_task_list(plc4c_connection_get_system(
           plc4c_read_request_get_connection(read_request))),
-      system_task);
+      new_read_request_execution->system_task);
 
   *read_request_execution = new_read_request_execution;
   return OK;
diff --git a/sandbox/plc4c/spi/src/system.c b/sandbox/plc4c/spi/src/system.c
index 5e45339..c4744c4 100644
--- a/sandbox/plc4c/spi/src/system.c
+++ b/sandbox/plc4c/spi/src/system.c
@@ -371,7 +371,7 @@
   if (plc4c_utils_list_empty(system->driver_list)) {
     return NO_DRIVER_AVAILABLE;
   }
-  plc4c_list_element *cur_driver_list_element = system->driver_list->head;
+  plc4c_list_element *cur_driver_list_element = system->driver_list->tail;
   do {
     plc4c_driver *cur_driver = (plc4c_driver *)cur_driver_list_element->value;
     if (strcmp(cur_driver->protocol_code,
@@ -412,7 +412,7 @@
   if (plc4c_utils_list_empty(system->transport_list)) {
     return NO_TRANSPORT_AVAILABLE;
   }
-  plc4c_list_element *cur_transport_list_element = system->transport_list->head;
+  plc4c_list_element *cur_transport_list_element = system->transport_list->tail;
   do {
     plc4c_transport *cur_transport =
         (plc4c_transport *)cur_transport_list_element->value;
@@ -435,9 +435,22 @@
   // Initialize a new connection task and schedule that.
   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
+  plc4c_driver* driver = plc4c_connection_get_driver(new_connection);
+
+  // Configure the driver configuration first.
+  void* configuration = NULL;
+  // TODO: Pass in the configuration options ...
+  driver->configure_function(NULL, &configuration);
+  plc4c_connection_set_configuration(new_connection, configuration);
+
+  // TODO: Somehow let the driver inject default values which the transport can then pickup ...
+
+  // Prepare a configuration data structure for the current transport.
+  new_connection->transport->configure(NULL, &new_connection->transport_configuration);
+
+  // Create a new connection task.
   plc4c_system_task *new_connection_task = NULL;
-  result = plc4c_connection_get_driver(new_connection)
-               ->connect_function(new_connection, &new_connection_task);
+  result = driver->connect_function(new_connection, &new_connection_task);
   if (result != OK) {
     return -1;
   }
@@ -493,3 +506,23 @@
 
   return OK;
 }
+
+char* list_to_string(plc4c_list* list) {
+  uint8_t string_length = plc4c_utils_list_size(list);
+  char* chars = malloc(sizeof(char) * (string_length + 1));
+  if(chars == NULL) {
+    return NULL;
+  }
+  char* cur_pos = chars;
+  plc4c_list_element* cur_element = list->tail;
+  while(cur_element != NULL) {
+    char cur_char = *((char*)(cur_element->value));
+    *cur_pos = cur_char;
+    cur_element = cur_element->next;
+    cur_pos++;
+  }
+  // Terminate the string.
+  *cur_pos = '\0';
+  return chars;
+}
+
diff --git a/sandbox/plc4c/spi/src/utils/list.c b/sandbox/plc4c/spi/src/utils/list.c
index d570cc3..f6ceab7 100644
--- a/sandbox/plc4c/spi/src/utils/list.c
+++ b/sandbox/plc4c/spi/src/utils/list.c
@@ -20,6 +20,7 @@
 #include <plc4c/utils/list.h>
 
 void plc4c_utils_list_create(plc4c_list **list) {
+  // TODO: Add a NULL-Check ...
   plc4c_list *new_list = malloc(sizeof(plc4c_list));
   new_list->head = NULL;
   new_list->tail = NULL;
@@ -27,7 +28,7 @@
 }
 
 size_t plc4c_utils_list_size(plc4c_list *list) {
-  if (list->tail == NULL) {
+  if ((list == NULL) || (list->tail == NULL)) {
     return 0;
   }
   plc4c_list_element *cur_element = list->tail;
diff --git a/sandbox/plc4c/spi/src/write.c b/sandbox/plc4c/spi/src/write.c
index 0da6177..9a410ef 100644
--- a/sandbox/plc4c/spi/src/write.c
+++ b/sandbox/plc4c/spi/src/write.c
@@ -36,8 +36,13 @@
     plc4c_write_request *write_request, char *address, plc4c_data *value) {
   // Parse an address string and get a driver-dependent data-structure
   // representing the address back.
-  plc4c_item *address_item =
-      write_request->connection->driver->parse_address_function(address);
+  plc4c_item *address_item = malloc(sizeof(plc4c_item));
+  if(address_item == NULL) {
+    return NO_MEMORY;
+  }
+
+  plc4c_return_code result =
+      write_request->connection->driver->parse_address_function(address, &(address_item->address));
 
   // Create a new value item, binding an address item to a value.
   plc4c_request_value_item *value_item =
diff --git a/sandbox/plc4c/transports/dummy/src/transport_dummy.c b/sandbox/plc4c/transports/dummy/src/transport_dummy.c
index 2c35eb2..610f30d 100644
--- a/sandbox/plc4c/transports/dummy/src/transport_dummy.c
+++ b/sandbox/plc4c/transports/dummy/src/transport_dummy.c
@@ -25,5 +25,10 @@
   plc4c_transport *transport =
       (plc4c_transport *)malloc(sizeof(plc4c_transport));
   transport->transport_code = "dummy";
+  transport->transport_name = "Dummy driver not actually doing any IO";
+  transport->open = NULL;
+  transport->close = NULL;
+  transport->send_message = NULL;
+  transport->select_message = NULL;
   return transport;
 }
diff --git a/sandbox/plc4c/transports/serial/CMakeLists.txt b/sandbox/plc4c/transports/serial/CMakeLists.txt
index 943e090..c486b3b 100644
--- a/sandbox/plc4c/transports/serial/CMakeLists.txt
+++ b/sandbox/plc4c/transports/serial/CMakeLists.txt
@@ -22,6 +22,6 @@
 # Add the sources
 file(GLOB sources "src/*.c")
 
-add_library(plc4c-transports-serial ${sources})
+add_library(plc4c-transport-serial ${sources})
 
-target_link_libraries(plc4c-transports-serial ${CMAKE_DL_LIBS})
\ No newline at end of file
+target_link_libraries(plc4c-transport-serial ${CMAKE_DL_LIBS})
\ No newline at end of file
diff --git a/sandbox/plc4c/transports/serial/src/transport_serial.c b/sandbox/plc4c/transports/serial/src/transport_serial.c
index adf0996..2b1d073 100644
--- a/sandbox/plc4c/transports/serial/src/transport_serial.c
+++ b/sandbox/plc4c/transports/serial/src/transport_serial.c
@@ -21,9 +21,33 @@
 #include <plc4c/transport_serial.h>
 #include <stdlib.h>
 
+plc4c_return_code plc4c_transport_serial_open_function(void* config) {
+  return OK;
+}
+
+plc4c_return_code plc4c_transport_serial_close_function(void* config) {
+  return OK;
+}
+
+plc4c_return_code plc4c_transport_serial_send_message_function(
+    plc4c_spi_write_buffer* message) {
+  return OK;
+}
+
+plc4c_return_code plc4c_transport_serial_select_message_function(
+    void* transport_configuration, accept_message_function accept_message,
+    plc4c_spi_read_buffer** message) {
+  return OK;
+}
+
 plc4c_transport *plc4c_transport_serial_create() {
   plc4c_transport *transport =
       (plc4c_transport *)malloc(sizeof(plc4c_transport));
   transport->transport_code = "serial";
+  transport->transport_name = "Serial port transport";
+  transport->open = &plc4c_transport_serial_open_function;
+  transport->close = &plc4c_transport_serial_close_function;
+  transport->send_message = &plc4c_transport_serial_send_message_function;
+  transport->select_message = &plc4c_transport_serial_select_message_function;
   return transport;
 }
diff --git a/sandbox/plc4c/transports/tcp/CMakeLists.txt b/sandbox/plc4c/transports/tcp/CMakeLists.txt
index f950cdb..afc8658 100644
--- a/sandbox/plc4c/transports/tcp/CMakeLists.txt
+++ b/sandbox/plc4c/transports/tcp/CMakeLists.txt
@@ -22,6 +22,6 @@
 # Add the sources
 file(GLOB sources "src/*.c")
 
-add_library(plc4c-transports-tcp ${sources})
+add_library(plc4c-transport-tcp ${sources})
 
-target_link_libraries(plc4c-transports-tcp ${CMAKE_DL_LIBS})
\ No newline at end of file
+target_link_libraries(plc4c-transport-tcp ${CMAKE_DL_LIBS})
\ No newline at end of file
diff --git a/sandbox/plc4c/transports/tcp/include/plc4c/transport_tcp.h b/sandbox/plc4c/transports/tcp/include/plc4c/transport_tcp.h
index fb57734..18998b1 100644
--- a/sandbox/plc4c/transports/tcp/include/plc4c/transport_tcp.h
+++ b/sandbox/plc4c/transports/tcp/include/plc4c/transport_tcp.h
@@ -24,6 +24,14 @@
 
 #include <plc4c/types.h>
 
+struct plc4c_transport_tcp_config {
+  char* address;
+  uint16_t port;
+
+  int sockfd;
+};
+typedef struct plc4c_transport_tcp_config plc4c_transport_tcp_config;
+
 plc4c_transport *plc4c_transport_tcp_create();
 
 #ifdef __cplusplus
diff --git a/sandbox/plc4c/transports/tcp/src/transport_tcp.c b/sandbox/plc4c/transports/tcp/src/transport_tcp.c
index 6836ad5..0bc0a79 100644
--- a/sandbox/plc4c/transports/tcp/src/transport_tcp.c
+++ b/sandbox/plc4c/transports/tcp/src/transport_tcp.c
@@ -20,10 +20,134 @@
 #include <plc4c/spi/types_private.h>
 #include <plc4c/transport_tcp.h>
 #include <stdlib.h>
+#include <stdio.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include <errno.h>
+
+extern int errno;
+
+plc4c_return_code plc4c_transport_tcp_configure_function(
+    plc4c_list* parameters, void** configuration) {
+  plc4c_transport_tcp_config* tcp_configuration = malloc(sizeof(plc4c_transport_tcp_config));
+  if(tcp_configuration == NULL) {
+    return NO_MEMORY;
+  }
+  // TODO: Implement this ...
+  tcp_configuration->address = "192.168.23.30";
+  tcp_configuration->port = 102;
+
+  *configuration = tcp_configuration;
+  return OK;
+}
+
+plc4c_return_code plc4c_transport_tcp_open_function(void* config) {
+  int sockfd;
+  int connfd;
+  struct sockaddr_in servaddr;
+
+  plc4c_transport_tcp_config* tcp_config = config;
+
+  tcp_config->sockfd = socket(AF_INET, SOCK_STREAM, 0);
+  if (tcp_config->sockfd < 0) {
+    return CONNECTION_ERROR;
+  }
+
+  // Configure where to connect to.
+  bzero(&servaddr, sizeof(struct sockaddr_in));
+  servaddr.sin_family = AF_INET;
+  servaddr.sin_addr.s_addr = inet_addr(tcp_config->address);
+  servaddr.sin_port = htons(tcp_config->port);
+
+  int result = connect(tcp_config->sockfd, (struct sockaddr*) &servaddr,
+                       sizeof(servaddr));
+  if(result != 0) {
+    char* error_msg = strerror(errno);
+    printf(error_msg);
+    return CONNECTION_ERROR;
+  }
+  return OK;
+}
+
+plc4c_return_code plc4c_transport_tcp_close_function(void* config) {
+  plc4c_transport_tcp_config* tcp_config = config;
+
+  // If the sockfd is zero we're not really connected.
+  if(tcp_config->sockfd == 0) {
+    return INTERNAL_ERROR;
+  }
+
+  // Stop receiving as well as sending.
+  shutdown(tcp_config->sockfd, 2);
+  return OK;
+}
+
+plc4c_return_code plc4c_transport_tcp_send_message_function(
+    void* transport_configuration, plc4c_spi_write_buffer* message) {
+  plc4c_transport_tcp_config* tcp_config = transport_configuration;
+
+  ssize_t bytes_sent = send(tcp_config->sockfd, message->data, message->length, MSG_DONTWAIT);
+  if(bytes_sent < 0) {
+    return CONNECTION_ERROR;
+  }
+
+  return OK;
+}
+
+plc4c_return_code plc4c_transport_tcp_select_message_function(
+    void* transport_configuration, uint8_t min_size,
+    accept_message_function accept_message, plc4c_spi_read_buffer** message) {
+  plc4c_transport_tcp_config* tcp_config = transport_configuration;
+
+  // First try to read the minimum number of bytes the driver needs to know
+  // how big a packet is.
+  uint8_t* size_buffer = malloc(sizeof(uint8_t) * min_size);
+  if(size_buffer == NULL) {
+    return NO_MEMORY;
+  }
+  int received_bytes = recv(tcp_config->sockfd, size_buffer, min_size, 0);
+  // TODO: if the value is negative, it's more a "please remove this much of corrupt data" ...
+  if(received_bytes < 0) {
+    return CONNECTION_ERROR;
+  }
+
+  // Now that we have enough data to find out how many bytes we need, have
+  // the accept_message function find out how many
+  int16_t message_size = accept_message(size_buffer, min_size);
+  if(message_size < 0) {
+    return INTERNAL_ERROR;
+  }
+  uint8_t* message_buffer = malloc(sizeof(uint8_t) * message_size);
+  if(message_size < 0) {
+    return NO_MEMORY;
+  }
+
+  // Copy the size_buffer to the start of the new buffer.
+  memcpy(message_buffer, size_buffer, min_size);
+  free(size_buffer);
+
+  // Read the rest of the packet.
+  received_bytes = recv(tcp_config->sockfd, message_buffer + min_size, message_size - min_size, 0);
+  if(received_bytes != message_size - min_size) {
+    return CONNECTION_ERROR;
+  }
+
+  // Create a new read-buffer with the read message data.
+  plc4c_spi_read_buffer_create(message_buffer, message_size, message);
+  return OK;
+}
 
 plc4c_transport *plc4c_transport_tcp_create() {
   plc4c_transport *transport =
       (plc4c_transport *)malloc(sizeof(plc4c_transport));
   transport->transport_code = "tcp";
+  transport->transport_name = "TCP transport";
+  transport->configure = &plc4c_transport_tcp_configure_function;
+  transport->open = &plc4c_transport_tcp_open_function;
+  transport->close = &plc4c_transport_tcp_close_function;
+  transport->send_message = &plc4c_transport_tcp_send_message_function;
+  transport->select_message = &plc4c_transport_tcp_select_message_function;
   return transport;
 }
diff --git a/src/site/asciidoc/users/preparing-issues.adoc b/src/site/asciidoc/users/preparing-issues.adoc
new file mode 100644
index 0000000..b5fad3e
--- /dev/null
+++ b/src/site/asciidoc/users/preparing-issues.adoc
@@ -0,0 +1,19 @@
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+
+== Preparing Issues & Bug Reports
+