You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by cd...@apache.org on 2024/10/02 15:28:06 UTC

(plc4x) branch develop updated: refactor: Fine tuning of the API and SPI (#1786)

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

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


The following commit(s) were added to refs/heads/develop by this push:
     new 69b8bc1aad refactor: Fine tuning of the API and SPI (#1786)
69b8bc1aad is described below

commit 69b8bc1aad5f2c6466618b8b825e923d4ab4fada
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Wed Oct 2 17:28:01 2024 +0200

    refactor: Fine tuning of the API and SPI (#1786)
    
    * refactor: Fine tuning of the API and SPI to allow ILLEGAL_ADDRESS responses for individual invalid addresses (Alongside a major cleanup)
    
    * refactor: Major cleanup of the PlcValueHandler
    
    * refactor: Major cleanup of the PlcValueHandler
    
    * refactor: Added more testcases to the PlcValueHandler tests
    
    * refactor: Updated the PlcValue types and the single item tests.
    
    * refactor: Moved the PlcTagHandler from the driver to the PlcConnection/Protocol so we can start making connection-aware tag-handlers in the future.
    
    * fix: Disabled another OPC-UA test, which seems to be randomly failing the build.
    
    * doc: Updated the RELEASE_NOTES
    
    * refactor: Renamed some of the variables in the Plc4xProtocolBase class
    
    ---------
    
    Co-authored-by: Sebastian Rühl <sr...@apache.org>
---
 RELEASE_NOTES                                      |   6 +
 .../testing/protocols/ads/DriverTestsuite.xml      |  38 +-
 .../testing/protocols/eip/DriverTestsuite.xml      |  18 +-
 .../protocols/modbus/tcp/DriverTestsuite.xml       |  16 +-
 .../modbus/tcp/DriverTestsuiteOptimized.xml        | 122 +++--
 .../tcp/Modbus-all-datatypes-little-endian.xml     | 560 +++++++++++---------
 .../protocols/modbus/tcp/Modbus-all-datatypes.xml  | 560 +++++++++++---------
 .../testing/protocols/s7/DriverTestsuite.xml       |   8 +-
 plc4go/spi/model/DefaultPlcReadResponse.go         |   6 +-
 plc4go/spi/model/DefaultPlcReadResponse_test.go    |  18 +-
 .../model/{ResponseItem.go => PlcResponseItem.go}  |  12 +-
 ...tem_plc4xgen.go => PlcResponseItem_plc4xgen.go} |  12 +-
 plc4go/spi/model/render_test.go                    |   2 +-
 .../org/apache/plc4x/java/api/PlcConnection.java   |   3 +
 .../api/exceptions/PlcTagNotFoundException.java}   |  29 +-
 .../plc4x/java/api/messages/PlcTagRequest.java     |   5 +-
 .../org/apache/plc4x/java/abeth/AbEthDriver.java   |  12 -
 .../java/abeth/protocol/AbEthProtocolLogic.java    |  36 +-
 .../java/abeth/protocol/Plc4xAbEthProtocol.java    |  22 +-
 .../ab-eth/src/test/resources/logback-test.xml     |   2 +-
 .../org/apache/plc4x/java/ads/AdsPlcDriver.java    |  12 -
 .../plc4x/java/ads/protocol/AdsProtocolLogic.java  |  66 +--
 .../apache/plc4x/java/ads/tag/SymbolicAdsTag.java  |   8 +-
 .../plc4x/java/ads/tag/SymbolicAdsTagTest.java}    |  17 +-
 .../org/apache/plc4x/protocol/ads/AdsDriverIT.java |   2 +-
 .../apache/plc4x/protocol/ads/ManualAdsBrowse.java |   7 +-
 .../plc4x/protocol/ads/ManualAdsDriverTest.java    |   7 +-
 .../apache/plc4x/java/bacnetip/BacNetIpDriver.java |  12 -
 .../bacnetip/protocol/BacNetIpProtocolLogic.java   |  25 +-
 .../bacnet/src/test/resources/logback-test.xml     |   2 +-
 .../org/apache/plc4x/java/cbus/CBusDriver.java     |  14 -
 .../java/cbus/protocol/CBusProtocolLogic.java      |   6 +
 .../c-bus/src/test/resources/logback-test.xml      |   2 +-
 .../plc4x/java/can/adapter/CANDriverAdapter.java   |  14 +-
 .../DeferredRequestContextWrapper.java             |   8 +
 .../ResolvedSendRequestContextWrapper.java         |   8 +
 .../conversation/SendRequestContextWrapper.java    |   8 +
 .../plc4x/java/can/generic/GenericCANDriver.java   |  16 +-
 .../generic/protocol/GenericCANProtocolLogic.java  |  33 +-
 .../plc4x/java/can/generic/tag/GenericCANTag.java  |   2 +-
 .../java/can/generic/GenericCANDriverTest.java     |  22 +-
 .../can/src/test/resources/logback-test.xml        |   2 +-
 .../plc4x/java/canopen/CANOpenPlcDriver.java       |  15 +-
 .../canopen/protocol/CANOpenProtocolLogic.java     |  47 +-
 .../canopen/src/test/resources/logback-test.xml    |   2 +-
 .../readwrite/connection/CtrlXConnection.java      |  20 +-
 .../org/apache/plc4x/java/eip/base/EIPDriver.java  |  14 -
 .../java/eip/base/protocol/EipProtocolLogic.java   |  44 +-
 .../apache/plc4x/java/eip/logix/LogixDriver.java   |  12 -
 .../apache/plc4x/java/eip/base/EIPDriverIT.java    |   2 +-
 .../eip/src/test/resources/logback-test.xml        |   2 +-
 .../java/firmata/readwrite/FirmataDriver.java      |  13 -
 .../readwrite/protocol/FirmataProtocolLogic.java   |  22 +-
 .../readwrite/Iec60870514PlcDriver.java            |  12 -
 .../messages/Iec608705104PlcSubscriptionEvent.java |   4 +-
 .../readwrite/protocol/Iec608705104Protocol.java   |  18 +-
 .../apache/plc4x/java/knxnetip/KnxNetIpDriver.java |  13 -
 .../knxnetip/protocol/KnxNetIpProtocolLogic.java   |  22 +-
 .../apache/plc4x/java/knxnetip/ManualKnxNetIp.java |   4 +-
 .../knxnetip/src/test/resources/logback-test.xml   |   2 +-
 .../plc4x/java/mock/connection/MockConnection.java |  24 +-
 .../plc4x/java/mock/connection/MockDevice.java     |   7 +-
 .../plc4x/java/modbus/ascii/ModbusAsciiDriver.java |  14 -
 .../ascii/protocol/ModbusAsciiProtocolLogic.java   |  17 +-
 .../modbus/base/optimizer/ModbusOptimizer.java     |  37 +-
 .../plc4x/java/modbus/base/tag/ModbusTag.java      |   4 +-
 .../plc4x/java/modbus/rtu/ModbusRtuDriver.java     |  13 -
 .../rtu/protocol/ModbusRtuProtocolLogic.java       |  17 +-
 .../plc4x/java/modbus/tcp/ModbusTcpDriver.java     |  13 -
 .../tcp/protocol/ModbusTcpProtocolLogic.java       |  16 +-
 .../apache/plc4x/java/modbus/ModbusEncodeTest.java |  74 +--
 .../apache/plc4x/java/modbus/ModbusTagTest.java    |   2 +-
 .../base/optimizer/LittleEndianByteSwapTest.java   |   8 +-
 .../modbus/base/optimizer/ModbusOptimizerTest.java |   6 +-
 .../modbus/src/test/resources/logback-test.xml     |   2 +-
 .../apache/plc4x/java/opcua/OpcuaPlcDriver.java    |  17 +-
 .../plc4x/java/opcua/optimizer/OpcuaOptimizer.java |   8 +-
 .../java/opcua/protocol/OpcuaProtocolLogic.java    |  73 +--
 .../opcua/protocol/OpcuaSubscriptionHandle.java    |  11 +-
 .../plc4x/java/opcua/OpcuaPlcDriverTest.java       |  22 +-
 .../opcua/protocol/chunk/ChunkFactoryTest.java     |   2 +
 .../opcua/src/test/resources/logback-test.xml      |   2 +-
 .../java/openprotocol/OpenProtocolDriver.java      |  12 -
 .../protocol/OpenProtocolProtocolLogic.java        |   7 +
 .../src/test/resources/logback-test.xml            |   2 +-
 .../org/apache/plc4x/java/plc4x/Plc4xDriver.java   |  13 -
 .../java/plc4x/protocol/Plc4xProtocolLogic.java    |  18 +-
 .../apache/plc4x/java/profinet/ProfinetDriver.java |  11 -
 .../profinet/discovery/ProfinetDiscoverer.java     |  22 +-
 .../profinet/protocol/ProfinetProtocolLogic.java   |  19 +-
 .../apache/plc4x/java/profinet/ProfinetDriver.java |  11 -
 .../plc4x/java/profinet/device/ProfinetDevice.java |  12 +-
 .../java/profinet/device/ProfinetEmptyModule.java  |   4 +-
 .../plc4x/java/profinet/device/ProfinetModule.java |   6 +-
 .../java/profinet/device/ProfinetModuleImpl.java   |  16 +-
 .../device/ProfinetSubscriptionHandle.java         |  12 -
 .../profinet/protocol/ProfinetProtocolLogic.java   |  22 +-
 .../apache/plc4x/java/s7/events/S7CyclicEvent.java |  26 +-
 .../apache/plc4x/java/s7/readwrite/S7Driver.java   |  12 -
 .../java/s7/readwrite/connection/S7HMuxImpl.java   | 156 +++---
 .../s7/readwrite/discovery/S7PlcDiscoverer.java    |  22 +-
 .../java/s7/readwrite/optimizer/S7Optimizer.java   |  53 +-
 .../readwrite/protocol/S7HGeneratedDriverBase.java |  12 -
 .../java/s7/readwrite/protocol/S7HMuxImpl.java     | 184 +++----
 .../s7/readwrite/protocol/S7HPlcConnection.java    |   4 +-
 .../s7/readwrite/protocol/S7ProtocolLogic.java     | 120 +++--
 .../apache/plc4x/java/s7/readwrite/tag/S7Tag.java  |  12 +-
 .../plc4x/java/s7/readwrite/DatatypesTest.java     |   2 +-
 .../java/s7/readwrite/ManualS71200DriverTest.java  |   4 +-
 .../drivers/s7/src/test/resources/logback-test.xml |   2 +-
 .../simulated/connection/SimulatedConnection.java  |  39 +-
 .../plc4x/java/simulated/tag/SimulatedTag.java     |   2 +-
 .../java/simulated/tag/SimulatedTagHandler.java    |   5 +-
 .../connection/SimulatedConnectionTest.java        |   2 +-
 .../simulated/tag/SimularedTagHandlerTest.java     | 119 -----
 .../plc4x/java/simulated/tag/SimulatedTagTest.java |   1 -
 .../simulated/src/test/resources/logback-test.xml  |   2 +-
 .../apache/plc4x/java/spi/ConversationContext.java |   3 +
 .../apache/plc4x/java/spi/Plc4xNettyWrapper.java   |   7 +-
 .../apache/plc4x/java/spi/Plc4xProtocolBase.java   |  17 +-
 .../java/spi/connection/AbstractPlcConnection.java |  39 +-
 .../spi/connection/DefaultNettyPlcConnection.java  |   5 +-
 .../java/spi/connection/GeneratedDriverBase.java   |  10 +-
 .../spi/internal/DefaultSendRequestContext.java    |   8 +
 .../java/spi/messages/DefaultPlcBrowseItem.java    |   4 +-
 ...owseItem.java => DefaultPlcBrowseItemList.java} |  13 +-
 .../java/spi/messages/DefaultPlcBrowseRequest.java |   5 +-
 .../java/spi/messages/DefaultPlcDiscoveryItem.java |   4 +-
 .../spi/messages/DefaultPlcDiscoveryRequest.java   |   3 +-
 .../java/spi/messages/DefaultPlcReadRequest.java   |  70 ++-
 .../java/spi/messages/DefaultPlcReadResponse.java  |  25 +-
 .../spi/messages/DefaultPlcSubscriptionEvent.java  |   4 +-
 .../messages/DefaultPlcSubscriptionRequest.java    |   4 +-
 .../messages/DefaultPlcSubscriptionResponse.java   |  23 +-
 .../messages/DefaultPlcUnsubscriptionRequest.java  |   2 +-
 .../java/spi/messages/DefaultPlcWriteRequest.java  | 117 ++---
 ...sponseItem.java => DefaultPlcResponseItem.java} |  10 +-
 .../utils/DefaultPlcTagErrorItem.java}             |  42 +-
 .../{TagValueItem.java => DefaultPlcTagItem.java}  |  24 +-
 ...sponseItem.java => DefaultPlcTagValueItem.java} |  41 +-
 .../java/spi/messages/utils/PlcResponseItem.java}  |  11 +-
 .../plc4x/java/spi/messages/utils/PlcTagItem.java} |  22 +-
 .../{TagValueItem.java => PlcTagValueItem.java}    |  19 +-
 .../plc4x/java/spi/model/DefaultArrayInfo.java     |   2 +-
 .../plc4x/java/spi/optimizer/BaseOptimizer.java    |   9 +-
 .../java/spi/optimizer/SingleTagOptimizer.java     |  10 +-
 .../spi/transaction/RequestTransactionManager.java |  21 +-
 .../java/spi/values/DefaultPlcValueHandler.java    | 275 ++++++++++
 ...alueHandler.java => LegacyPlcValueHandler.java} |   5 +-
 .../org/apache/plc4x/java/spi/values/PlcBINT.java  | 237 ---------
 .../org/apache/plc4x/java/spi/values/PlcBOOL.java  |  60 +--
 .../org/apache/plc4x/java/spi/values/PlcBREAL.java | 238 ---------
 .../org/apache/plc4x/java/spi/values/PlcBYTE.java  |  52 +-
 .../org/apache/plc4x/java/spi/values/PlcCHAR.java  |  58 ++-
 .../org/apache/plc4x/java/spi/values/PlcDATE.java  |  92 +++-
 .../plc4x/java/spi/values/PlcDATE_AND_LTIME.java   | 112 +++-
 .../plc4x/java/spi/values/PlcDATE_AND_TIME.java    |  94 +++-
 .../org/apache/plc4x/java/spi/values/PlcDINT.java  |  32 +-
 .../org/apache/plc4x/java/spi/values/PlcDWORD.java |  52 +-
 .../org/apache/plc4x/java/spi/values/PlcINT.java   |  36 +-
 .../org/apache/plc4x/java/spi/values/PlcLDATE.java |  98 +++-
 .../plc4x/java/spi/values/PlcLDATE_AND_TIME.java   | 101 +++-
 .../org/apache/plc4x/java/spi/values/PlcLINT.java  |  28 +-
 .../org/apache/plc4x/java/spi/values/PlcLREAL.java |  27 +-
 .../org/apache/plc4x/java/spi/values/PlcLTIME.java |  79 ++-
 .../plc4x/java/spi/values/PlcLTIME_OF_DAY.java     |  74 ++-
 .../org/apache/plc4x/java/spi/values/PlcLWORD.java |  54 +-
 .../org/apache/plc4x/java/spi/values/PlcList.java  |   1 -
 .../org/apache/plc4x/java/spi/values/PlcREAL.java  |  29 +-
 .../plc4x/java/spi/values/PlcRawByteArray.java     |   4 +-
 .../org/apache/plc4x/java/spi/values/PlcSINT.java  |  40 +-
 .../apache/plc4x/java/spi/values/PlcSTRING.java    |  11 +-
 .../plc4x/java/spi/values/PlcSimpleValue.java      |  71 ---
 .../org/apache/plc4x/java/spi/values/PlcTIME.java  |  77 ++-
 .../plc4x/java/spi/values/PlcTIME_OF_DAY.java      |  73 ++-
 .../org/apache/plc4x/java/spi/values/PlcUBINT.java | 292 -----------
 .../org/apache/plc4x/java/spi/values/PlcUDINT.java |  52 +-
 .../org/apache/plc4x/java/spi/values/PlcUINT.java  |  48 +-
 .../org/apache/plc4x/java/spi/values/PlcULINT.java |  54 +-
 .../org/apache/plc4x/java/spi/values/PlcUSINT.java |  52 +-
 .../plc4x/java/spi/values/PlcValueAdapter.java     |  35 +-
 .../plc4x/java/spi/values/PlcValueHandler.java     | 244 +--------
 .../org/apache/plc4x/java/spi/values/PlcWCHAR.java |  56 +-
 .../org/apache/plc4x/java/spi/values/PlcWORD.java  |  48 +-
 .../apache/plc4x/java/spi/values/PlcWSTRING.java   |  11 +-
 .../connection/DefaultNettyPlcConnectionTest.java  |   5 +
 .../java/spi/connection/PlcConnectionFactory.java  |   2 +-
 .../plc4x/java/spi/connection/TestProtocol.java    |   5 +
 .../spi/values/DefaultPlcValueHandlerTest.java     | 573 +++++++++++++++++++++
 .../java/utils/cache/LeasedPlcConnection.java      |  22 +-
 .../apache/plc4x/java/opm/ConnectedEntityTest.java |   4 +-
 .../plc4x/java/opm/PlcEntityInterceptorTest.java   |   4 +-
 .../java/opm/PlcEntityManagerComplexTest.java      |  80 ++-
 .../plc4x/java/opm/PlcEntityManagerTest.java       |  10 +-
 .../apache/plc4x/java/scraper/ScraperTaskTest.java |   6 +-
 .../org/apache/plc4x/java/scraper/ScraperTest.java |   6 +-
 .../triggeredscraper/TriggeredScraperImplTest.java |  14 +-
 .../org/apache/plc4x/test/manual/ManualTest.java   |  60 ++-
 .../resources/protocols/ads/DriverTestsuite.xml    |  38 +-
 .../protocols/canopen/CANOpenDriverSDOIT.xml       |  20 +-
 .../resources/protocols/eip/DriverTestsuite.xml    |  18 +-
 .../iec-60870/src/test/resources/logback-test.xml  |   2 +-
 .../protocols/modbus/tcp/DriverTestsuite.xml       |  16 +-
 .../modbus/tcp/DriverTestsuiteOptimized.xml        | 122 +++--
 .../tcp/Modbus-all-datatypes-little-endian.xml     | 560 +++++++++++---------
 .../protocols/modbus/tcp/Modbus-all-datatypes.xml  | 560 +++++++++++---------
 .../resources/protocols/s7/DriverTestsuite.xml     |   8 +-
 207 files changed, 4914 insertions(+), 4200 deletions(-)

diff --git a/RELEASE_NOTES b/RELEASE_NOTES
index a299b25354..9dc43e96d8 100644
--- a/RELEASE_NOTES
+++ b/RELEASE_NOTES
@@ -29,6 +29,12 @@ Incompatible changes
   efficient PlcRawByteArray type is used, that gives users
   direct access to the bytes returned from the PLC instead of
   a list of PlcValues.
+- The builders for read- and write-requests now process tags
+  and values on a per-field level. If one field has an invalid
+  address it will now only fail the one item related to that.
+  Same applies to values. Only the tag who's value was invalid
+  will be considered failed and no longer an exception should
+  be thrown.
 
 Bug Fixes
 ---------
diff --git a/plc4go/assets/testing/protocols/ads/DriverTestsuite.xml b/plc4go/assets/testing/protocols/ads/DriverTestsuite.xml
index 73ddc89785..3770e9d267 100644
--- a/plc4go/assets/testing/protocols/ads/DriverTestsuite.xml
+++ b/plc4go/assets/testing/protocols/ads/DriverTestsuite.xml
@@ -1150,9 +1150,13 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <SymbolicAdsTag>
-                      <symbolicAddress dataType="string" bitLength="128" encoding="UTF-8">MAIN.hurz_Struct</symbolicAddress>
-                    </SymbolicAdsTag>
+                    <PlcTagItem>
+                      <tag>
+                        <SymbolicAdsTag>
+                          <symbolicAddress dataType="string" bitLength="128" encoding="UTF-8">MAIN.hurz_Struct</symbolicAddress>
+                        </SymbolicAdsTag>
+                      </tag>
+                    </PlcTagItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
@@ -1160,7 +1164,7 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcStruct>
@@ -1232,7 +1236,7 @@
                     </hurz_DATE>
                   </PlcStruct>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -1580,12 +1584,12 @@
           </PlcReadRequest>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcBOOL dataType="bit" bitLength="1">true</PlcBOOL>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -1754,20 +1758,20 @@
           </PlcReadRequest>
           <values isList="true">
             <hurz1>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcBOOL dataType="bit" bitLength="1">true</PlcBOOL>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz1>
             <hurz2>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcBOOL dataType="bit" bitLength="1">true</PlcBOOL>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz2>
           </values>
         </PlcReadResponse>
@@ -2040,12 +2044,12 @@
           </PlcReadRequest>
           <values isList="true">
             <hurz1>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcBOOL dataType="bit" bitLength="1">false</PlcBOOL>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz1>
           </values>
         </PlcReadResponse>
@@ -2319,12 +2323,12 @@
           </PlcReadRequest>
           <values isList="true">
             <hurz1>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcBOOL dataType="bit" bitLength="1">false</PlcBOOL>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz1>
           </values>
         </PlcReadResponse>
@@ -2474,12 +2478,12 @@
           </PlcReadRequest>
           <values isList="true">
             <hurz1>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcBOOL dataType="bit" bitLength="1">false</PlcBOOL>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz1>
           </values>
         </PlcReadResponse>
diff --git a/plc4go/assets/testing/protocols/eip/DriverTestsuite.xml b/plc4go/assets/testing/protocols/eip/DriverTestsuite.xml
index b18faac99d..b6eca5cd50 100644
--- a/plc4go/assets/testing/protocols/eip/DriverTestsuite.xml
+++ b/plc4go/assets/testing/protocols/eip/DriverTestsuite.xml
@@ -398,11 +398,15 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <EipTag>
-                      <node dataType="string" bitLength="40" encoding="UTF-8">%rate</node>
-                      <type dataType="string" bitLength="32" encoding="UTF-8">DINT</type>
-                      <elementNb dataType="uint" bitLength="16">1</elementNb>
-                    </EipTag>
+                    <PlcTagItem>
+                      <tag>
+                        <EipTag>
+                          <node dataType="string" bitLength="40" encoding="UTF-8">%rate</node>
+                          <type dataType="string" bitLength="32" encoding="UTF-8">DINT</type>
+                          <elementNb dataType="uint" bitLength="16">1</elementNb>
+                        </EipTag>
+                      </tag>
+                    </PlcTagItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
@@ -410,12 +414,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcDINT dataType="int" bitLength="32">369229824</PlcDINT>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
diff --git a/plc4go/assets/testing/protocols/modbus/tcp/DriverTestsuite.xml b/plc4go/assets/testing/protocols/modbus/tcp/DriverTestsuite.xml
index cad5d8eb6f..b88fd463e3 100644
--- a/plc4go/assets/testing/protocols/modbus/tcp/DriverTestsuite.xml
+++ b/plc4go/assets/testing/protocols/modbus/tcp/DriverTestsuite.xml
@@ -109,12 +109,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcREAL dataType="float" bitLength="32">3.1415927410125732</PlcREAL>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -202,7 +202,7 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcList>
@@ -210,7 +210,7 @@
                     <PlcREAL dataType="float" bitLength="32">3.1415927410125732</PlcREAL>
                   </PlcList>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -357,20 +357,20 @@
           </request>
           <values isList="true">
             <hurz1>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcREAL dataType="float" bitLength="32">3.1415927410125732</PlcREAL>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz1>
             <hurz2>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcREAL dataType="float" bitLength="32">3.1415927410125732</PlcREAL>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz2>
           </values>
         </PlcReadResponse>
diff --git a/plc4go/assets/testing/protocols/modbus/tcp/DriverTestsuiteOptimized.xml b/plc4go/assets/testing/protocols/modbus/tcp/DriverTestsuiteOptimized.xml
index ebd8db3986..ac935f38be 100644
--- a/plc4go/assets/testing/protocols/modbus/tcp/DriverTestsuiteOptimized.xml
+++ b/plc4go/assets/testing/protocols/modbus/tcp/DriverTestsuiteOptimized.xml
@@ -97,11 +97,15 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">0</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">REAL</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">0</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">REAL</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                    </PlcTagItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
@@ -109,12 +113,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcREAL dataType="float" bitLength="32">3.1415927410125732</PlcREAL>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -190,11 +194,15 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">0</address>
-                      <numberOfElements dataType="uint" bitLength="16">2</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">REAL</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">0</address>
+                          <numberOfElements dataType="uint" bitLength="16">2</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">REAL</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                    </PlcTagItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
@@ -202,7 +210,7 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcList>
@@ -210,7 +218,7 @@
                     <PlcREAL dataType="float" bitLength="32">3.1415927410125732</PlcREAL>
                   </PlcList>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -290,18 +298,26 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz1>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">0</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">REAL</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">0</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">REAL</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                    </PlcTagItem>
                   </hurz1>
                   <hurz2>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">2</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">REAL</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">2</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">REAL</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                    </PlcTagItem>
                   </hurz2>
                 </tags>
               </PlcTagRequest>
@@ -309,20 +325,20 @@
           </request>
           <values isList="true">
             <hurz1>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcREAL dataType="float" bitLength="32">3.1415927410125732</PlcREAL>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz1>
             <hurz2>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcREAL dataType="float" bitLength="32">3.1415927410125732</PlcREAL>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz2>
           </values>
         </PlcReadResponse>
@@ -401,19 +417,21 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">0</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">REAL</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagValueItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">0</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">REAL</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                      <value>
+                        <PlcREAL dataType="float" bitLength="32">3.1415927410125732</PlcREAL>
+                      </value>
+                    </PlcTagValueItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
-              <values isList="true">
-                <hurz>
-                  <PlcREAL dataType="float" bitLength="32">3.1415927410125732</PlcREAL>
-                </hurz>
-              </values>
             </PlcWriteRequest>
           </request>
           <responseCodes isList="true">
@@ -498,22 +516,24 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">0</address>
-                      <numberOfElements dataType="uint" bitLength="16">2</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">REAL</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagValueItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">0</address>
+                          <numberOfElements dataType="uint" bitLength="16">2</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">REAL</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                      <value>
+                        <PlcList>
+                          <PlcREAL dataType="float" bitLength="32">3.1415927410125732</PlcREAL>
+                          <PlcREAL dataType="float" bitLength="32">3.1415927410125732</PlcREAL>
+                        </PlcList>
+                      </value>
+                    </PlcTagValueItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
-              <values isList="true">
-                <hurz>
-                  <PlcList>
-                    <PlcREAL dataType="float" bitLength="32">3.1415927410125732</PlcREAL>
-                    <PlcREAL dataType="float" bitLength="32">3.1415927410125732</PlcREAL>
-                  </PlcList>
-                </hurz>
-              </values>
             </PlcWriteRequest>
           </request>
           <responseCodes isList="true">
diff --git a/plc4go/assets/testing/protocols/modbus/tcp/Modbus-all-datatypes-little-endian.xml b/plc4go/assets/testing/protocols/modbus/tcp/Modbus-all-datatypes-little-endian.xml
index 1c01f46872..7e46dc7933 100644
--- a/plc4go/assets/testing/protocols/modbus/tcp/Modbus-all-datatypes-little-endian.xml
+++ b/plc4go/assets/testing/protocols/modbus/tcp/Modbus-all-datatypes-little-endian.xml
@@ -101,11 +101,15 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">0</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">BOOL</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">0</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">BOOL</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                    </PlcTagItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
@@ -113,12 +117,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcBOOL dataType="bit" bitLength="1">true</PlcBOOL>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -197,19 +201,21 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">0</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">BOOL</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagValueItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">0</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">BOOL</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                      <value>
+                        <PlcBOOL dataType="bit" bitLength="1">true</PlcBOOL>
+                      </value>
+                    </PlcTagValueItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
-              <values isList="true">
-                <hurz>
-                  <PlcBOOL dataType="bit" bitLength="1">true</PlcBOOL>
-                </hurz>
-              </values>
             </PlcWriteRequest>
           </request>
           <responseCodes isList="true">
@@ -290,11 +296,15 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">1</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">BYTE</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">1</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">BYTE</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                    </PlcTagItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
@@ -302,12 +312,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcBYTE dataType="int" bitLength="8">42</PlcBYTE>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -386,19 +396,21 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">1</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">BYTE</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagValueItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">1</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">BYTE</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                      <value>
+                        <PlcBYTE dataType="int" bitLength="8">42</PlcBYTE>
+                      </value>
+                    </PlcTagValueItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
-              <values isList="true">
-                <hurz>
-                  <PlcBYTE dataType="int" bitLength="8">42</PlcBYTE>
-                </hurz>
-              </values>
             </PlcWriteRequest>
           </request>
           <responseCodes isList="true">
@@ -479,11 +491,15 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">2</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">WORD</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">2</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">WORD</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                    </PlcTagItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
@@ -491,12 +507,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcWORD dataType="int" bitLength="16">42424</PlcWORD>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -575,19 +591,21 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">2</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">WORD</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagValueItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">2</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">WORD</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                      <value>
+                        <PlcWORD dataType="int" bitLength="16">42424</PlcWORD>
+                      </value>
+                    </PlcTagValueItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
-              <values isList="true">
-                <hurz>
-                  <PlcWORD dataType="int" bitLength="16">42424</PlcWORD>
-                </hurz>
-              </values>
             </PlcWriteRequest>
           </request>
           <responseCodes isList="true">
@@ -668,11 +686,15 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">3</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="40" encoding="UTF-8">DWORD</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">3</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="40" encoding="UTF-8">DWORD</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                    </PlcTagItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
@@ -680,12 +702,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcDWORD dataType="int" bitLength="32">4242442424</PlcDWORD>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -764,19 +786,21 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">3</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="40" encoding="UTF-8">DWORD</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagValueItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">3</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="40" encoding="UTF-8">DWORD</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                      <value>
+                        <PlcDWORD dataType="int" bitLength="32">4242442424</PlcDWORD>
+                      </value>
+                    </PlcTagValueItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
-              <values isList="true">
-                <hurz>
-                  <PlcDWORD dataType="int" bitLength="32">4242442424</PlcDWORD>
-                </hurz>
-              </values>
             </PlcWriteRequest>
           </request>
           <responseCodes isList="true">
@@ -857,11 +881,15 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">9</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">SINT</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">9</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">SINT</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                    </PlcTagItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
@@ -869,12 +897,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcSINT dataType="int" bitLength="8">-42</PlcSINT>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -953,19 +981,21 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">9</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">SINT</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagValueItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">9</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">SINT</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                      <value>
+                        <PlcSINT dataType="int" bitLength="8">-42</PlcSINT>
+                      </value>
+                    </PlcTagValueItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
-              <values isList="true">
-                <hurz>
-                  <PlcSINT dataType="int" bitLength="8">-42</PlcSINT>
-                </hurz>
-              </values>
             </PlcWriteRequest>
           </request>
           <responseCodes isList="true">
@@ -1046,11 +1076,15 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">10</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="40" encoding="UTF-8">USINT</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">10</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="40" encoding="UTF-8">USINT</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                    </PlcTagItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
@@ -1058,12 +1092,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcUSINT dataType="int" bitLength="8">42</PlcUSINT>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -1142,19 +1176,21 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">10</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="40" encoding="UTF-8">USINT</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagValueItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">10</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="40" encoding="UTF-8">USINT</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                      <value>
+                        <PlcUSINT dataType="int" bitLength="8">42</PlcUSINT>
+                      </value>
+                    </PlcTagValueItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
-              <values isList="true">
-                <hurz>
-                  <PlcUSINT dataType="int" bitLength="8">42</PlcUSINT>
-                </hurz>
-              </values>
             </PlcWriteRequest>
           </request>
           <responseCodes isList="true">
@@ -1235,11 +1271,15 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">11</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="24" encoding="UTF-8">INT</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">11</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="24" encoding="UTF-8">INT</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                    </PlcTagItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
@@ -1247,12 +1287,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcINT dataType="int" bitLength="16">-2424</PlcINT>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -1331,19 +1371,21 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">11</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="24" encoding="UTF-8">INT</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagValueItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">11</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="24" encoding="UTF-8">INT</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                      <value>
+                        <PlcINT dataType="int" bitLength="16">-2424</PlcINT>
+                      </value>
+                    </PlcTagValueItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
-              <values isList="true">
-                <hurz>
-                  <PlcINT dataType="int" bitLength="16">-2424</PlcINT>
-                </hurz>
-              </values>
             </PlcWriteRequest>
           </request>
           <responseCodes isList="true">
@@ -1424,11 +1466,15 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">12</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">UINT</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">12</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">UINT</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                    </PlcTagItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
@@ -1436,12 +1482,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcUINT dataType="int" bitLength="16">42424</PlcUINT>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -1520,19 +1566,21 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">12</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">UINT</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagValueItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">12</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">UINT</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                      <value>
+                        <PlcUINT dataType="int" bitLength="16">42424</PlcUINT>
+                      </value>
+                    </PlcTagValueItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
-              <values isList="true">
-                <hurz>
-                  <PlcUINT dataType="int" bitLength="16">42424</PlcUINT>
-                </hurz>
-              </values>
             </PlcWriteRequest>
           </request>
           <responseCodes isList="true">
@@ -1613,11 +1661,15 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">13</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">DINT</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">13</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">DINT</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                    </PlcTagItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
@@ -1625,12 +1677,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcDINT dataType="int" bitLength="32">-242442424</PlcDINT>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -1709,19 +1761,21 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">13</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">DINT</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagValueItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">13</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">DINT</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                      <value>
+                        <PlcDINT dataType="int" bitLength="32">-242442424</PlcDINT>
+                      </value>
+                    </PlcTagValueItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
-              <values isList="true">
-                <hurz>
-                  <PlcDINT dataType="int" bitLength="32">-242442424</PlcDINT>
-                </hurz>
-              </values>
             </PlcWriteRequest>
           </request>
           <responseCodes isList="true">
@@ -1802,11 +1856,15 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">15</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="40" encoding="UTF-8">UDINT</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">15</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="40" encoding="UTF-8">UDINT</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                    </PlcTagItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
@@ -1814,12 +1872,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcUDINT dataType="int" bitLength="32">4242442424</PlcUDINT>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -1898,19 +1956,21 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">15</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="40" encoding="UTF-8">UDINT</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagValueItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">15</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="40" encoding="UTF-8">UDINT</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                      <value>
+                        <PlcUDINT dataType="int" bitLength="32">4242442424</PlcUDINT>
+                      </value>
+                    </PlcTagValueItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
-              <values isList="true">
-                <hurz>
-                  <PlcUDINT dataType="int" bitLength="32">4242442424</PlcUDINT>
-                </hurz>
-              </values>
             </PlcWriteRequest>
           </request>
           <responseCodes isList="true">
@@ -1991,11 +2051,15 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">17</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">LINT</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">17</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">LINT</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                    </PlcTagItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
@@ -2003,12 +2067,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcLINT dataType="int" bitLength="64">-4242442424242424242</PlcLINT>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -2087,19 +2151,21 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">17</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">LINT</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagValueItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">17</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">LINT</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                      <value>
+                        <PlcLINT dataType="int" bitLength="64">-4242442424242424242</PlcLINT>
+                      </value>
+                    </PlcTagValueItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
-              <values isList="true">
-                <hurz>
-                  <PlcLINT dataType="int" bitLength="64">-4242442424242424242</PlcLINT>
-                </hurz>
-              </values>
             </PlcWriteRequest>
           </request>
           <responseCodes isList="true">
@@ -2180,11 +2246,15 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">21</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="40" encoding="UTF-8">ULINT</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">21</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="40" encoding="UTF-8">ULINT</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                    </PlcTagItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
@@ -2192,12 +2262,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcULINT dataType="int" bitLength="64">4242442424242424242</PlcULINT>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -2276,19 +2346,21 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">21</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="40" encoding="UTF-8">ULINT</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagValueItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">21</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="40" encoding="UTF-8">ULINT</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                      <value>
+                        <PlcULINT dataType="int" bitLength="64">4242442424242424242</PlcULINT>
+                      </value>
+                    </PlcTagValueItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
-              <values isList="true">
-                <hurz>
-                  <PlcULINT dataType="int" bitLength="64">4242442424242424242</PlcULINT>
-                </hurz>
-              </values>
             </PlcWriteRequest>
           </request>
           <responseCodes isList="true">
@@ -2369,11 +2441,15 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">25</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">REAL</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">25</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">REAL</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                    </PlcTagItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
@@ -2381,12 +2457,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcREAL dataType="float" bitLength="32">3.1415929794311523</PlcREAL>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -2465,19 +2541,21 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">25</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">REAL</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagValueItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">25</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">REAL</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                      <value>
+                        <PlcREAL dataType="float" bitLength="32">3.1415929794311523</PlcREAL>
+                      </value>
+                    </PlcTagValueItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
-              <values isList="true">
-                <hurz>
-                  <PlcREAL dataType="float" bitLength="32">3.1415929794311523</PlcREAL>
-                </hurz>
-              </values>
             </PlcWriteRequest>
           </request>
           <responseCodes isList="true">
@@ -2558,11 +2636,15 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">27</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="40" encoding="UTF-8">LREAL</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">27</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="40" encoding="UTF-8">LREAL</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                    </PlcTagItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
@@ -2570,12 +2652,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcLREAL dataType="float" bitLength="64">2.71828182846</PlcLREAL>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -2654,19 +2736,21 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">27</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="40" encoding="UTF-8">LREAL</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagValueItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">27</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="40" encoding="UTF-8">LREAL</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                      <value>
+                        <PlcLREAL dataType="float" bitLength="64">2.71828182846</PlcLREAL>
+                      </value>
+                    </PlcTagValueItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
-              <values isList="true">
-                <hurz>
-                  <PlcLREAL dataType="float" bitLength="64">2.71828182846</PlcLREAL>
-                </hurz>
-              </values>
             </PlcWriteRequest>
           </request>
           <responseCodes isList="true">
diff --git a/plc4go/assets/testing/protocols/modbus/tcp/Modbus-all-datatypes.xml b/plc4go/assets/testing/protocols/modbus/tcp/Modbus-all-datatypes.xml
index b3c7d9050c..938027aff6 100644
--- a/plc4go/assets/testing/protocols/modbus/tcp/Modbus-all-datatypes.xml
+++ b/plc4go/assets/testing/protocols/modbus/tcp/Modbus-all-datatypes.xml
@@ -95,11 +95,15 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">0</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">BOOL</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">0</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">BOOL</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                    </PlcTagItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
@@ -107,12 +111,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcBOOL dataType="bit" bitLength="1">true</PlcBOOL>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -191,19 +195,21 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">0</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">BOOL</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagValueItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">0</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">BOOL</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                      <value>
+                        <PlcBOOL dataType="bit" bitLength="1">true</PlcBOOL>
+                      </value>
+                    </PlcTagValueItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
-              <values isList="true">
-                <hurz>
-                  <PlcBOOL dataType="bit" bitLength="1">true</PlcBOOL>
-                </hurz>
-              </values>
             </PlcWriteRequest>
           </request>
           <responseCodes isList="true">
@@ -284,11 +290,15 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">1</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">BYTE</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">1</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">BYTE</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                    </PlcTagItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
@@ -296,12 +306,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcBYTE dataType="int" bitLength="8">42</PlcBYTE>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -380,19 +390,21 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">1</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">BYTE</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagValueItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">1</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">BYTE</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                      <value>
+                        <PlcBYTE dataType="int" bitLength="8">42</PlcBYTE>
+                      </value>
+                    </PlcTagValueItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
-              <values isList="true">
-                <hurz>
-                  <PlcBYTE dataType="int" bitLength="8">42</PlcBYTE>
-                </hurz>
-              </values>
             </PlcWriteRequest>
           </request>
           <responseCodes isList="true">
@@ -473,11 +485,15 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">2</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">WORD</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">2</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">WORD</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                    </PlcTagItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
@@ -485,12 +501,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcWORD dataType="int" bitLength="16">42424</PlcWORD>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -569,19 +585,21 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">2</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">WORD</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagValueItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">2</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">WORD</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                      <value>
+                        <PlcWORD dataType="int" bitLength="16">42424</PlcWORD>
+                      </value>
+                    </PlcTagValueItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
-              <values isList="true">
-                <hurz>
-                  <PlcWORD dataType="int" bitLength="16">42424</PlcWORD>
-                </hurz>
-              </values>
             </PlcWriteRequest>
           </request>
           <responseCodes isList="true">
@@ -662,11 +680,15 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">3</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="40" encoding="UTF-8">DWORD</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">3</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="40" encoding="UTF-8">DWORD</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                    </PlcTagItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
@@ -674,12 +696,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcDWORD dataType="int" bitLength="32">4242442424</PlcDWORD>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -758,19 +780,21 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">3</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="40" encoding="UTF-8">DWORD</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagValueItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">3</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="40" encoding="UTF-8">DWORD</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                      <value>
+                        <PlcDWORD dataType="int" bitLength="32">4242442424</PlcDWORD>
+                      </value>
+                    </PlcTagValueItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
-              <values isList="true">
-                <hurz>
-                  <PlcDWORD dataType="int" bitLength="32">4242442424</PlcDWORD>
-                </hurz>
-              </values>
             </PlcWriteRequest>
           </request>
           <responseCodes isList="true">
@@ -851,11 +875,15 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">9</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">SINT</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">9</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">SINT</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                    </PlcTagItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
@@ -863,12 +891,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcSINT dataType="int" bitLength="8">-42</PlcSINT>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -947,19 +975,21 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">9</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">SINT</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagValueItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">9</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">SINT</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                      <value>
+                        <PlcSINT dataType="int" bitLength="8">-42</PlcSINT>
+                      </value>
+                    </PlcTagValueItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
-              <values isList="true">
-                <hurz>
-                  <PlcSINT dataType="int" bitLength="8">-42</PlcSINT>
-                </hurz>
-              </values>
             </PlcWriteRequest>
           </request>
           <responseCodes isList="true">
@@ -1040,11 +1070,15 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">10</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="40" encoding="UTF-8">USINT</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">10</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="40" encoding="UTF-8">USINT</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                    </PlcTagItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
@@ -1052,12 +1086,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcUSINT dataType="int" bitLength="8">42</PlcUSINT>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -1136,19 +1170,21 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">10</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="40" encoding="UTF-8">USINT</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagValueItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">10</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="40" encoding="UTF-8">USINT</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                      <value>
+                        <PlcUSINT dataType="int" bitLength="8">42</PlcUSINT>
+                      </value>
+                    </PlcTagValueItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
-              <values isList="true">
-                <hurz>
-                  <PlcUSINT dataType="int" bitLength="8">42</PlcUSINT>
-                </hurz>
-              </values>
             </PlcWriteRequest>
           </request>
           <responseCodes isList="true">
@@ -1229,11 +1265,15 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">11</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="24" encoding="UTF-8">INT</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">11</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="24" encoding="UTF-8">INT</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                    </PlcTagItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
@@ -1241,12 +1281,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcINT dataType="int" bitLength="16">-2424</PlcINT>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -1325,19 +1365,21 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">11</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="24" encoding="UTF-8">INT</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagValueItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">11</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="24" encoding="UTF-8">INT</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                      <value>
+                        <PlcINT dataType="int" bitLength="16">-2424</PlcINT>
+                      </value>
+                    </PlcTagValueItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
-              <values isList="true">
-                <hurz>
-                  <PlcINT dataType="int" bitLength="16">-2424</PlcINT>
-                </hurz>
-              </values>
             </PlcWriteRequest>
           </request>
           <responseCodes isList="true">
@@ -1418,11 +1460,15 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">12</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">UINT</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">12</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">UINT</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                    </PlcTagItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
@@ -1430,12 +1476,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcUINT dataType="int" bitLength="16">42424</PlcUINT>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -1514,19 +1560,21 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">12</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">UINT</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagValueItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">12</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">UINT</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                      <value>
+                        <PlcUINT dataType="int" bitLength="16">42424</PlcUINT>
+                      </value>
+                    </PlcTagValueItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
-              <values isList="true">
-                <hurz>
-                  <PlcUINT dataType="int" bitLength="16">42424</PlcUINT>
-                </hurz>
-              </values>
             </PlcWriteRequest>
           </request>
           <responseCodes isList="true">
@@ -1607,11 +1655,15 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">13</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">DINT</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">13</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">DINT</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                    </PlcTagItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
@@ -1619,12 +1671,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcDINT dataType="int" bitLength="32">-242442424</PlcDINT>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -1703,19 +1755,21 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">13</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">DINT</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagValueItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">13</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">DINT</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                      <value>
+                        <PlcDINT dataType="int" bitLength="32">-242442424</PlcDINT>
+                      </value>
+                    </PlcTagValueItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
-              <values isList="true">
-                <hurz>
-                  <PlcDINT dataType="int" bitLength="32">-242442424</PlcDINT>
-                </hurz>
-              </values>
             </PlcWriteRequest>
           </request>
           <responseCodes isList="true">
@@ -1796,11 +1850,15 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">15</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="40" encoding="UTF-8">UDINT</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">15</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="40" encoding="UTF-8">UDINT</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                    </PlcTagItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
@@ -1808,12 +1866,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcUDINT dataType="int" bitLength="32">4242442424</PlcUDINT>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -1892,19 +1950,21 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">15</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="40" encoding="UTF-8">UDINT</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagValueItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">15</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="40" encoding="UTF-8">UDINT</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                      <value>
+                        <PlcUDINT dataType="int" bitLength="32">4242442424</PlcUDINT>
+                      </value>
+                    </PlcTagValueItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
-              <values isList="true">
-                <hurz>
-                  <PlcUDINT dataType="int" bitLength="32">4242442424</PlcUDINT>
-                </hurz>
-              </values>
             </PlcWriteRequest>
           </request>
           <responseCodes isList="true">
@@ -1985,11 +2045,15 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">17</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">LINT</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">17</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">LINT</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                    </PlcTagItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
@@ -1997,12 +2061,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcLINT dataType="int" bitLength="64">-4242442424242424242</PlcLINT>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -2081,19 +2145,21 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">17</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">LINT</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagValueItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">17</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">LINT</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                      <value>
+                        <PlcLINT dataType="int" bitLength="64">-4242442424242424242</PlcLINT>
+                      </value>
+                    </PlcTagValueItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
-              <values isList="true">
-                <hurz>
-                  <PlcLINT dataType="int" bitLength="64">-4242442424242424242</PlcLINT>
-                </hurz>
-              </values>
             </PlcWriteRequest>
           </request>
           <responseCodes isList="true">
@@ -2174,11 +2240,15 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">21</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="40" encoding="UTF-8">ULINT</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">21</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="40" encoding="UTF-8">ULINT</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                    </PlcTagItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
@@ -2186,12 +2256,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcULINT dataType="int" bitLength="64">4242442424242424242</PlcULINT>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -2270,19 +2340,21 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">21</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="40" encoding="UTF-8">ULINT</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagValueItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">21</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="40" encoding="UTF-8">ULINT</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                      <value>
+                        <PlcULINT dataType="int" bitLength="64">4242442424242424242</PlcULINT>
+                      </value>
+                    </PlcTagValueItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
-              <values isList="true">
-                <hurz>
-                  <PlcULINT dataType="int" bitLength="64">4242442424242424242</PlcULINT>
-                </hurz>
-              </values>
             </PlcWriteRequest>
           </request>
           <responseCodes isList="true">
@@ -2363,11 +2435,15 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">25</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">REAL</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">25</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">REAL</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                    </PlcTagItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
@@ -2375,12 +2451,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcREAL dataType="float" bitLength="32">3.1415929794311523</PlcREAL>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -2459,19 +2535,21 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">25</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="32" encoding="UTF-8">REAL</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagValueItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">25</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="32" encoding="UTF-8">REAL</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                      <value>
+                        <PlcREAL dataType="float" bitLength="32">3.1415929794311523</PlcREAL>
+                      </value>
+                    </PlcTagValueItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
-              <values isList="true">
-                <hurz>
-                  <PlcREAL dataType="float" bitLength="32">3.1415929794311523</PlcREAL>
-                </hurz>
-              </values>
             </PlcWriteRequest>
           </request>
           <responseCodes isList="true">
@@ -2552,11 +2630,15 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">27</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="40" encoding="UTF-8">LREAL</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">27</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="40" encoding="UTF-8">LREAL</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                    </PlcTagItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
@@ -2564,12 +2646,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcLREAL dataType="float" bitLength="64">2.71828182846</PlcLREAL>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -2648,19 +2730,21 @@
               <PlcTagRequest>
                 <tags isList="true">
                   <hurz>
-                    <ModbusTagHoldingRegister>
-                      <address dataType="uint" bitLength="16">27</address>
-                      <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
-                      <dataType dataType="string" bitLength="40" encoding="UTF-8">LREAL</dataType>
-                    </ModbusTagHoldingRegister>
+                    <PlcTagValueItem>
+                      <tag>
+                        <ModbusTagHoldingRegister>
+                          <address dataType="uint" bitLength="16">27</address>
+                          <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
+                          <dataType dataType="string" bitLength="40" encoding="UTF-8">LREAL</dataType>
+                        </ModbusTagHoldingRegister>
+                      </tag>
+                      <value>
+                        <PlcLREAL dataType="float" bitLength="64">2.71828182846</PlcLREAL>
+                      </value>
+                    </PlcTagValueItem>
                   </hurz>
                 </tags>
               </PlcTagRequest>
-              <values isList="true">
-                <hurz>
-                  <PlcLREAL dataType="float" bitLength="64">2.71828182846</PlcLREAL>
-                </hurz>
-              </values>
             </PlcWriteRequest>
           </request>
           <responseCodes isList="true">
diff --git a/plc4go/assets/testing/protocols/s7/DriverTestsuite.xml b/plc4go/assets/testing/protocols/s7/DriverTestsuite.xml
index d870c8b0ca..a62da14586 100644
--- a/plc4go/assets/testing/protocols/s7/DriverTestsuite.xml
+++ b/plc4go/assets/testing/protocols/s7/DriverTestsuite.xml
@@ -582,12 +582,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
                 <value>
                   <PlcBOOL dataType="bit" bitLength="1">true</PlcBOOL>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
@@ -730,12 +730,12 @@
           </request>
           <values isList="true">
             <hurz>
-              <ResponseItem>
+              <PlcResponseItem>
                 <code dataType="string" bitLength="104" encoding="UTF-8">ACCESS_DENIED</code>
                 <value>
                   <PlcNull></PlcNull>
                 </value>
-              </ResponseItem>
+              </PlcResponseItem>
             </hurz>
           </values>
         </PlcReadResponse>
diff --git a/plc4go/spi/model/DefaultPlcReadResponse.go b/plc4go/spi/model/DefaultPlcReadResponse.go
index db3172364a..23bd17b768 100644
--- a/plc4go/spi/model/DefaultPlcReadResponse.go
+++ b/plc4go/spi/model/DefaultPlcReadResponse.go
@@ -30,14 +30,14 @@ var _ apiModel.PlcReadResponse = &DefaultPlcReadResponse{}
 //go:generate plc4xGenerator -type=DefaultPlcReadResponse
 type DefaultPlcReadResponse struct {
 	request apiModel.PlcReadRequest
-	values  map[string]*ResponseItem
+	values  map[string]*PlcResponseItem
 }
 
 func NewDefaultPlcReadResponse(request apiModel.PlcReadRequest, responseCodes map[string]apiModel.PlcResponseCode, values map[string]apiValues.PlcValue) apiModel.PlcReadResponse {
-	valueMap := map[string]*ResponseItem{}
+	valueMap := map[string]*PlcResponseItem{}
 	for name, code := range responseCodes {
 		value := values[name]
-		valueMap[name] = NewResponseItem(code, value)
+		valueMap[name] = NewPlcResponseItem(code, value)
 	}
 	return &DefaultPlcReadResponse{
 		request: request,
diff --git a/plc4go/spi/model/DefaultPlcReadResponse_test.go b/plc4go/spi/model/DefaultPlcReadResponse_test.go
index 8f3cd2ae2e..693ba984c7 100644
--- a/plc4go/spi/model/DefaultPlcReadResponse_test.go
+++ b/plc4go/spi/model/DefaultPlcReadResponse_test.go
@@ -32,7 +32,7 @@ import (
 func TestDefaultPlcReadResponse_GetRequest(t *testing.T) {
 	type fields struct {
 		request apiModel.PlcReadRequest
-		values  map[string]*ResponseItem
+		values  map[string]*PlcResponseItem
 	}
 	tests := []struct {
 		name   string
@@ -57,7 +57,7 @@ func TestDefaultPlcReadResponse_GetRequest(t *testing.T) {
 func TestDefaultPlcReadResponse_GetResponseCode(t *testing.T) {
 	type fields struct {
 		request apiModel.PlcReadRequest
-		values  map[string]*ResponseItem
+		values  map[string]*PlcResponseItem
 	}
 	type args struct {
 		name string
@@ -75,7 +75,7 @@ func TestDefaultPlcReadResponse_GetResponseCode(t *testing.T) {
 		{
 			name: "get it",
 			fields: fields{
-				values: map[string]*ResponseItem{
+				values: map[string]*PlcResponseItem{
 					"something": {
 						code: apiModel.PlcResponseCode_OK,
 					},
@@ -101,7 +101,7 @@ func TestDefaultPlcReadResponse_GetResponseCode(t *testing.T) {
 func TestDefaultPlcReadResponse_GetTagNames(t *testing.T) {
 	type fields struct {
 		request apiModel.PlcReadRequest
-		values  map[string]*ResponseItem
+		values  map[string]*PlcResponseItem
 	}
 	tests := []struct {
 		name   string
@@ -112,7 +112,7 @@ func TestDefaultPlcReadResponse_GetTagNames(t *testing.T) {
 			name: "get it",
 			fields: fields{
 				request: NewDefaultPlcReadRequest(nil, []string{"tag1", "tag2"}, nil, nil),
-				values: map[string]*ResponseItem{
+				values: map[string]*PlcResponseItem{
 					"tag1": nil,
 					"tag2": nil,
 				},
@@ -134,7 +134,7 @@ func TestDefaultPlcReadResponse_GetTagNames(t *testing.T) {
 func TestDefaultPlcReadResponse_GetValue(t *testing.T) {
 	type fields struct {
 		request apiModel.PlcReadRequest
-		values  map[string]*ResponseItem
+		values  map[string]*PlcResponseItem
 	}
 	type args struct {
 		name string
@@ -152,7 +152,7 @@ func TestDefaultPlcReadResponse_GetValue(t *testing.T) {
 		{
 			name: "get it",
 			fields: fields{
-				values: map[string]*ResponseItem{
+				values: map[string]*PlcResponseItem{
 					"something": {
 						code:  apiModel.PlcResponseCode_OK,
 						value: spiValues.NewPlcSTRING("yes"),
@@ -179,7 +179,7 @@ func TestDefaultPlcReadResponse_GetValue(t *testing.T) {
 func TestDefaultPlcReadResponse_IsAPlcMessage(t *testing.T) {
 	type fields struct {
 		request apiModel.PlcReadRequest
-		values  map[string]*ResponseItem
+		values  map[string]*PlcResponseItem
 	}
 	tests := []struct {
 		name   string
@@ -215,7 +215,7 @@ func TestNewDefaultPlcReadResponse(t *testing.T) {
 	}{
 		{
 			name: "create it",
-			want: &DefaultPlcReadResponse{values: map[string]*ResponseItem{}},
+			want: &DefaultPlcReadResponse{values: map[string]*PlcResponseItem{}},
 		},
 	}
 	for _, tt := range tests {
diff --git a/plc4go/spi/model/ResponseItem.go b/plc4go/spi/model/PlcResponseItem.go
similarity index 77%
rename from plc4go/spi/model/ResponseItem.go
rename to plc4go/spi/model/PlcResponseItem.go
index 4a08cfc3e4..92217cca62 100644
--- a/plc4go/spi/model/ResponseItem.go
+++ b/plc4go/spi/model/PlcResponseItem.go
@@ -24,23 +24,23 @@ import (
 	"github.com/apache/plc4x/plc4go/pkg/api/values"
 )
 
-//go:generate plc4xGenerator -type=ResponseItem
-type ResponseItem struct {
+//go:generate plc4xGenerator -type=PlcResponseItem
+type PlcResponseItem struct {
 	code  apiModel.PlcResponseCode `stringer:"true"`
 	value values.PlcValue
 }
 
-func NewResponseItem(code apiModel.PlcResponseCode, value values.PlcValue) *ResponseItem {
-	return &ResponseItem{
+func NewPlcResponseItem(code apiModel.PlcResponseCode, value values.PlcValue) *PlcResponseItem {
+	return &PlcResponseItem{
 		code:  code,
 		value: value,
 	}
 }
 
-func (r *ResponseItem) GetCode() apiModel.PlcResponseCode {
+func (r *PlcResponseItem) GetCode() apiModel.PlcResponseCode {
 	return r.code
 }
 
-func (r *ResponseItem) GetValue() values.PlcValue {
+func (r *PlcResponseItem) GetValue() values.PlcValue {
 	return r.value
 }
diff --git a/plc4go/spi/model/ResponseItem_plc4xgen.go b/plc4go/spi/model/PlcResponseItem_plc4xgen.go
similarity index 85%
rename from plc4go/spi/model/ResponseItem_plc4xgen.go
rename to plc4go/spi/model/PlcResponseItem_plc4xgen.go
index 636f712936..de9d217a61 100644
--- a/plc4go/spi/model/ResponseItem_plc4xgen.go
+++ b/plc4go/spi/model/PlcResponseItem_plc4xgen.go
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-// Code generated by "plc4xGenerator -type=ResponseItem"; DO NOT EDIT.
+// Code generated by "plc4xGenerator -type=PlcResponseItem"; DO NOT EDIT.
 
 package model
 
@@ -30,7 +30,7 @@ import (
 
 var _ = fmt.Printf
 
-func (d *ResponseItem) Serialize() ([]byte, error) {
+func (d *PlcResponseItem) Serialize() ([]byte, error) {
 	if d == nil {
 		return nil, fmt.Errorf("(*DeviceInfoCache)(nil)")
 	}
@@ -41,11 +41,11 @@ func (d *ResponseItem) Serialize() ([]byte, error) {
 	return wb.GetBytes(), nil
 }
 
-func (d *ResponseItem) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
+func (d *PlcResponseItem) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
 	if d == nil {
 		return fmt.Errorf("(*DeviceInfoCache)(nil)")
 	}
-	if err := writeBuffer.PushContext("ResponseItem"); err != nil {
+	if err := writeBuffer.PushContext("PlcResponseItem"); err != nil {
 		return err
 	}
 
@@ -71,13 +71,13 @@ func (d *ResponseItem) SerializeWithWriteBuffer(ctx context.Context, writeBuffer
 			}
 		}
 	}
-	if err := writeBuffer.PopContext("ResponseItem"); err != nil {
+	if err := writeBuffer.PopContext("PlcResponseItem"); err != nil {
 		return err
 	}
 	return nil
 }
 
-func (d *ResponseItem) String() string {
+func (d *PlcResponseItem) String() string {
 	if alternateStringer, ok := any(d).(utils.AlternateStringer); ok {
 		if alternateString, use := alternateStringer.AlternateString(); use {
 			return alternateString
diff --git a/plc4go/spi/model/render_test.go b/plc4go/spi/model/render_test.go
index a20556995b..84e45c1f27 100644
--- a/plc4go/spi/model/render_test.go
+++ b/plc4go/spi/model/render_test.go
@@ -67,7 +67,7 @@ func TestRenderTest(t *testing.T) {
 		&DefaultPlcWriteRequest{DefaultPlcTagRequest: NewDefaultPlcTagRequest(nil, nil)},
 		&DefaultPlcWriteRequestResult{},
 		&DefaultPlcWriteResponse{},
-		&ResponseItem{},
+		&PlcResponseItem{},
 	}
 	for _, sut := range suts {
 		t.Run(fmt.Sprintf("%T", sut), func(t *testing.T) {
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/PlcConnection.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/PlcConnection.java
index 560e29c939..54cde7c211 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/PlcConnection.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/PlcConnection.java
@@ -22,6 +22,7 @@ import org.apache.plc4x.java.api.exceptions.*;
 import org.apache.plc4x.java.api.messages.*;
 import org.apache.plc4x.java.api.metadata.PlcConnectionMetadata;
 import org.apache.plc4x.java.api.model.PlcTag;
+import org.apache.plc4x.java.api.value.PlcValue;
 
 import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
@@ -63,6 +64,8 @@ public interface PlcConnection extends AutoCloseable {
      */
     Optional<PlcTag> parseTagAddress(String tagAddress);
 
+    Optional<PlcValue> parseTagValue(PlcTag tag, Object... values);
+
     /**
      * Provides connection metadata.
      */
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/TagValueItem.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/exceptions/PlcTagNotFoundException.java
similarity index 56%
copy from plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/TagValueItem.java
copy to plc4j/api/src/main/java/org/apache/plc4x/java/api/exceptions/PlcTagNotFoundException.java
index 14c9540af1..e417d18b9c 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/TagValueItem.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/exceptions/PlcTagNotFoundException.java
@@ -16,27 +16,28 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.plc4x.java.spi.messages.utils;
+package org.apache.plc4x.java.api.exceptions;
 
-import org.apache.plc4x.java.api.model.PlcTag;
-import org.apache.plc4x.java.api.value.PlcValue;
-
-public class TagValueItem {
+/**
+ * Indicates an invalid tag address.
+ */
+public class PlcTagNotFoundException extends PlcRuntimeException {
 
-    private final PlcTag tag;
-    private final PlcValue value;
+    private static final long serialVersionUID = 1L;
+    private final String tagToBeParsed;
 
-    public TagValueItem(PlcTag tag, PlcValue value) {
-        this.tag = tag;
-        this.value = value;
+    public PlcTagNotFoundException(String tagToBeParsed) {
+        super(tagToBeParsed + " not found");
+        this.tagToBeParsed = tagToBeParsed;
     }
 
-    public PlcTag getTag() {
-        return tag;
+    public PlcTagNotFoundException(String tagToBeParsed, Throwable cause) {
+        super(tagToBeParsed + " not found", cause);
+        this.tagToBeParsed = tagToBeParsed;
     }
 
-    public PlcValue getValue() {
-        return value;
+    public String getTagToBeParsed() {
+        return tagToBeParsed;
     }
 
 }
diff --git a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcTagRequest.java b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcTagRequest.java
index 3b98fdd01a..b6a9f08e0e 100644
--- a/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcTagRequest.java
+++ b/plc4j/api/src/main/java/org/apache/plc4x/java/api/messages/PlcTagRequest.java
@@ -19,6 +19,7 @@
 package org.apache.plc4x.java.api.messages;
 
 import org.apache.plc4x.java.api.model.PlcTag;
+import org.apache.plc4x.java.api.types.PlcResponseCode;
 
 import java.util.LinkedHashSet;
 import java.util.List;
@@ -33,7 +34,9 @@ public interface PlcTagRequest extends PlcRequest {
 
     LinkedHashSet<String> getTagNames();
 
-    PlcTag getTag(String name);
+    PlcResponseCode getTagResponseCode(String tagName);
+
+    PlcTag getTag(String tagName);
 
     List<PlcTag> getTags();
 
diff --git a/plc4j/drivers/ab-eth/src/main/java/org/apache/plc4x/java/abeth/AbEthDriver.java b/plc4j/drivers/ab-eth/src/main/java/org/apache/plc4x/java/abeth/AbEthDriver.java
index c088dc7410..877d8b8274 100644
--- a/plc4j/drivers/ab-eth/src/main/java/org/apache/plc4x/java/abeth/AbEthDriver.java
+++ b/plc4j/drivers/ab-eth/src/main/java/org/apache/plc4x/java/abeth/AbEthDriver.java
@@ -22,13 +22,11 @@ import io.netty.buffer.ByteBuf;
 import org.apache.plc4x.java.abeth.configuration.AbEthConfiguration;
 import org.apache.plc4x.java.abeth.configuration.AbEthTcpTransportConfiguration;
 import org.apache.plc4x.java.abeth.tag.AbEthTag;
-import org.apache.plc4x.java.abeth.tag.AbEthTagHandler;
 import org.apache.plc4x.java.abeth.protocol.AbEthProtocolLogic;
 import org.apache.plc4x.java.abeth.readwrite.CIPEncapsulationPacket;
 import org.apache.plc4x.java.spi.configuration.PlcConnectionConfiguration;
 import org.apache.plc4x.java.spi.configuration.PlcTransportConfiguration;
 import org.apache.plc4x.java.api.model.PlcTag;
-import org.apache.plc4x.java.spi.values.PlcValueHandler;
 import org.apache.plc4x.java.spi.connection.GeneratedDriverBase;
 import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer;
 import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer;
@@ -77,16 +75,6 @@ public class AbEthDriver extends GeneratedDriverBase<CIPEncapsulationPacket> {
         return Collections.singletonList("tcp");
     }
 
-    @Override
-    protected AbEthTagHandler getTagHandler() {
-        return new AbEthTagHandler();
-    }
-
-    @Override
-    protected org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() {
-        return new PlcValueHandler();
-    }
-
     /**
      * This protocol doesn't have a disconnect procedure, so there is no need to wait for a login to finish.
      * @return false
diff --git a/plc4j/drivers/ab-eth/src/main/java/org/apache/plc4x/java/abeth/protocol/AbEthProtocolLogic.java b/plc4j/drivers/ab-eth/src/main/java/org/apache/plc4x/java/abeth/protocol/AbEthProtocolLogic.java
index 35e0d93aa3..d5c25986a2 100644
--- a/plc4j/drivers/ab-eth/src/main/java/org/apache/plc4x/java/abeth/protocol/AbEthProtocolLogic.java
+++ b/plc4j/drivers/ab-eth/src/main/java/org/apache/plc4x/java/abeth/protocol/AbEthProtocolLogic.java
@@ -21,6 +21,7 @@ package org.apache.plc4x.java.abeth.protocol;
 import org.apache.plc4x.java.abeth.configuration.AbEthConfiguration;
 import org.apache.plc4x.java.abeth.readwrite.*;
 import org.apache.plc4x.java.abeth.tag.AbEthTag;
+import org.apache.plc4x.java.abeth.tag.AbEthTagHandler;
 import org.apache.plc4x.java.api.messages.PlcReadRequest;
 import org.apache.plc4x.java.api.messages.PlcReadResponse;
 import org.apache.plc4x.java.api.messages.PlcResponse;
@@ -30,11 +31,13 @@ import org.apache.plc4x.java.api.value.PlcValue;
 import org.apache.plc4x.java.spi.ConversationContext;
 import org.apache.plc4x.java.spi.Plc4xProtocolBase;
 import org.apache.plc4x.java.spi.configuration.HasConfiguration;
+import org.apache.plc4x.java.spi.connection.PlcTagHandler;
 import org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem;
 import org.apache.plc4x.java.spi.transaction.RequestTransactionManager;
+import org.apache.plc4x.java.spi.values.DefaultPlcValueHandler;
 import org.apache.plc4x.java.spi.values.PlcINT;
-import org.apache.plc4x.java.spi.values.PlcValueHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -67,6 +70,11 @@ public class AbEthProtocolLogic extends Plc4xProtocolBase<CIPEncapsulationPacket
         this.tm = new RequestTransactionManager(1);
     }
 
+    @Override
+    public PlcTagHandler getTagHandler() {
+        return new AbEthTagHandler();
+    }
+
     @Override
     public void close(ConversationContext<CIPEncapsulationPacket> context) {
         tm.shutdown();
@@ -74,7 +82,7 @@ public class AbEthProtocolLogic extends Plc4xProtocolBase<CIPEncapsulationPacket
 
     @Override
     public void onConnect(ConversationContext<CIPEncapsulationPacket> context) {
-        logger.debug("Sending COTP Connection Request");
+        logger.debug("Sending Connection Request");
         CIPEncapsulationConnectionRequest connectionRequest =
             new CIPEncapsulationConnectionRequest(0L, 0L, emptySenderContext, 0L);
         context.sendRequest(connectionRequest)
@@ -89,7 +97,7 @@ public class AbEthProtocolLogic extends Plc4xProtocolBase<CIPEncapsulationPacket
 
     @Override
     public CompletableFuture<PlcReadResponse> read(PlcReadRequest readRequest) {
-        // TODO: Warning ... we are senging one request per tag ... the result has to be merged back together ...
+        // TODO: Warning ... we are sending one request per tag ... the result has to be merged back together ...
         for (String tagName : readRequest.getTagNames()) {
             PlcTag tag = readRequest.getTag(tagName);
             if (!(tag instanceof AbEthTag)) {
@@ -115,7 +123,7 @@ public class AbEthProtocolLogic extends Plc4xProtocolBase<CIPEncapsulationPacket
 
             CompletableFuture<PlcReadResponse> future = new CompletableFuture<>();
             RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
-            transaction.submit(() -> context.sendRequest(read)
+            transaction.submit(() -> conversationContext.sendRequest(read)
                 .expectResponse(CIPEncapsulationPacket.class, REQUEST_TIMEOUT)
                 .onTimeout(future::completeExceptionally)
                 .onError((p, e) -> future.completeExceptionally(e))
@@ -141,7 +149,7 @@ public class AbEthProtocolLogic extends Plc4xProtocolBase<CIPEncapsulationPacket
 
     private PlcResponse decodeReadResponse(
         CIPEncapsulationReadResponse plcReadResponse, PlcReadRequest plcReadRequest) {
-        Map<String, ResponseItem<PlcValue>> values = new HashMap<>();
+        Map<String, PlcResponseItem<PlcValue>> values = new HashMap<>();
         for (String tagName : plcReadRequest.getTagNames()) {
             AbEthTag tag = (AbEthTag) plcReadRequest.getTag(tagName);
             PlcResponseCode responseCode = decodeResponseCode(plcReadResponse.getResponse().getStatus());
@@ -157,7 +165,7 @@ public class AbEthProtocolLogic extends Plc4xProtocolBase<CIPEncapsulationPacket
                                 if (data.size() == 1) {
                                     plcValue = new PlcINT(data.get(0));
                                 } else {
-                                    plcValue = PlcValueHandler.of(data);
+                                    plcValue = DefaultPlcValueHandler.of(tag, data);
                                 }
                             }
                             break;
@@ -166,9 +174,9 @@ public class AbEthProtocolLogic extends Plc4xProtocolBase<CIPEncapsulationPacket
                                 DF1CommandResponseMessageProtectedTypedLogicalRead df1PTLR = (DF1CommandResponseMessageProtectedTypedLogicalRead) plcReadResponse.getResponse();
                                 List<Short> data = df1PTLR.getData();
                                 if (((data.get(1) >> 7) & 1) == 0) {
-                                    plcValue = PlcValueHandler.of((data.get(1) << 8) + data.get(0));  // positive number
+                                    plcValue = DefaultPlcValueHandler.of(tag, (data.get(1) << 8) + data.get(0));  // positive number
                                 } else {
-                                    plcValue = PlcValueHandler.of((((~data.get(1) & 0b01111111) << 8) + (-data.get(0) & 0b11111111)) * -1);  // negative number
+                                    plcValue = DefaultPlcValueHandler.of(tag, (((~data.get(1) & 0b01111111) << 8) + (-data.get(0) & 0b11111111)) * -1);  // negative number
                                 }
                             }
                             break;
@@ -177,9 +185,9 @@ public class AbEthProtocolLogic extends Plc4xProtocolBase<CIPEncapsulationPacket
                                 DF1CommandResponseMessageProtectedTypedLogicalRead df1PTLR = (DF1CommandResponseMessageProtectedTypedLogicalRead) plcReadResponse.getResponse();
                                 List<Short> data = df1PTLR.getData();
                                 if (((data.get(3) >> 7) & 1) == 0) {
-                                    plcValue = PlcValueHandler.of((data.get(3) << 24) + (data.get(2) << 16) + (data.get(1) << 8) + data.get(0));  // positive number
+                                    plcValue = DefaultPlcValueHandler.of(tag, (data.get(3) << 24) + (data.get(2) << 16) + (data.get(1) << 8) + data.get(0));  // positive number
                                 } else {
-                                    plcValue = PlcValueHandler.of((((~data.get(3) & 0b01111111) << 24) + ((-data.get(2) & 0b11111111) << 16) + ((-data.get(1) & 0b11111111) << 8) + (-data.get(0) & 0b11111111)) * -1);  // negative number
+                                    plcValue = DefaultPlcValueHandler.of(tag, (((~data.get(3) & 0b01111111) << 24) + ((-data.get(2) & 0b11111111) << 16) + ((-data.get(1) & 0b11111111) << 8) + (-data.get(0) & 0b11111111)) * -1);  // negative number
                                 }
                             }
                             break;
@@ -188,9 +196,9 @@ public class AbEthProtocolLogic extends Plc4xProtocolBase<CIPEncapsulationPacket
                                 DF1CommandResponseMessageProtectedTypedLogicalRead df1PTLR = (DF1CommandResponseMessageProtectedTypedLogicalRead) plcReadResponse.getResponse();
                                 List<Short> data = df1PTLR.getData();
                                 if (tag.getBitNumber() < 8) {
-                                    plcValue = PlcValueHandler.of((data.get(0) & (1 << tag.getBitNumber())) != 0);         // read from first byte
+                                    plcValue = DefaultPlcValueHandler.of(tag, (data.get(0) & (1 << tag.getBitNumber())) != 0);         // read from first byte
                                 } else {
-                                    plcValue = PlcValueHandler.of((data.get(1) & (1 << (tag.getBitNumber() - 8))) != 0);   // read from second byte
+                                    plcValue = DefaultPlcValueHandler.of(tag, (data.get(1) & (1 << (tag.getBitNumber() - 8))) != 0);   // read from second byte
                                 }
                             }
                             break;
@@ -202,7 +210,7 @@ public class AbEthProtocolLogic extends Plc4xProtocolBase<CIPEncapsulationPacket
                     logger.warn("Some other error occurred casting tag {}, TagInformation: {}", tagName, tag, e);
                 }
             }
-            ResponseItem<PlcValue> result = new ResponseItem<>(responseCode, plcValue);
+            PlcResponseItem<PlcValue> result = new DefaultPlcResponseItem<>(responseCode, plcValue);
             values.put(tagName, result);
         }
 
diff --git a/plc4j/drivers/ab-eth/src/main/java/org/apache/plc4x/java/abeth/protocol/Plc4xAbEthProtocol.java b/plc4j/drivers/ab-eth/src/main/java/org/apache/plc4x/java/abeth/protocol/Plc4xAbEthProtocol.java
index 6c00ce572f..0d1b1e85b5 100644
--- a/plc4j/drivers/ab-eth/src/main/java/org/apache/plc4x/java/abeth/protocol/Plc4xAbEthProtocol.java
+++ b/plc4j/drivers/ab-eth/src/main/java/org/apache/plc4x/java/abeth/protocol/Plc4xAbEthProtocol.java
@@ -34,9 +34,9 @@ import org.apache.plc4x.java.spi.events.ConnectEvent;
 import org.apache.plc4x.java.spi.events.ConnectedEvent;
 import org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse;
 import org.apache.plc4x.java.spi.messages.PlcRequestContainer;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem;
 import org.apache.plc4x.java.spi.values.*;
-import org.apache.plc4x.java.spi.values.PlcValueHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -163,7 +163,7 @@ public class Plc4xAbEthProtocol extends PlcMessageToMessageCodec<CIPEncapsulatio
 
         PlcReadRequest plcReadRequest = (PlcReadRequest) requestContainer.getRequest();
 
-        Map<String, ResponseItem<PlcValue>> values = new HashMap<>();
+        Map<String, PlcResponseItem<PlcValue>> values = new HashMap<>();
         for (String tagName : plcReadRequest.getTagNames()) {
             AbEthTag tag = (AbEthTag) plcReadRequest.getTag(tagName);
             PlcResponseCode responseCode = decodeResponseCode(plcReadResponse.getResponse().getStatus());
@@ -179,7 +179,7 @@ public class Plc4xAbEthProtocol extends PlcMessageToMessageCodec<CIPEncapsulatio
                                 if(data.size() == 1) {
                                     plcValue = new PlcINT(data.get(0));
                                 } else {
-                                    plcValue = PlcValueHandler.of(data);
+                                    plcValue = DefaultPlcValueHandler.of(tag, data);
                                 }
                             }
                             break;
@@ -188,9 +188,9 @@ public class Plc4xAbEthProtocol extends PlcMessageToMessageCodec<CIPEncapsulatio
                                 DF1CommandResponseMessageProtectedTypedLogicalRead df1PTLR = (DF1CommandResponseMessageProtectedTypedLogicalRead) plcReadResponse.getResponse();
                                 List<Short> data = df1PTLR.getData();
                                 if (((data.get(1)>> 7) & 1) == 0)  {
-                                    plcValue = PlcValueHandler.of((data.get(1) << 8) + data.get(0));  // positive number
+                                    plcValue = DefaultPlcValueHandler.of(tag, (data.get(1) << 8) + data.get(0));  // positive number
                                 } else {
-                                    plcValue = PlcValueHandler.of((((~data.get(1) & 0b01111111) << 8) + (-data.get(0) & 0b11111111))  * -1);  // negative number
+                                    plcValue = DefaultPlcValueHandler.of(tag, (((~data.get(1) & 0b01111111) << 8) + (-data.get(0) & 0b11111111))  * -1);  // negative number
                                 }
                             }
                             break;
@@ -199,9 +199,9 @@ public class Plc4xAbEthProtocol extends PlcMessageToMessageCodec<CIPEncapsulatio
                                 DF1CommandResponseMessageProtectedTypedLogicalRead df1PTLR = (DF1CommandResponseMessageProtectedTypedLogicalRead) plcReadResponse.getResponse();
                                 List<Short> data = df1PTLR.getData();
                                 if (((data.get(3)>> 7) & 1) == 0)  {
-                                    plcValue = PlcValueHandler.of((data.get(3) << 24) + (data.get(2) << 16) + (data.get(1) << 8) + data.get(0));  // positive number
+                                    plcValue = DefaultPlcValueHandler.of(tag, (data.get(3) << 24) + (data.get(2) << 16) + (data.get(1) << 8) + data.get(0));  // positive number
                                 } else {
-                                    plcValue = PlcValueHandler.of((((~data.get(3) & 0b01111111) << 24) + ((-data.get(2) & 0b11111111) << 16)+ ((-data.get(1) & 0b11111111) << 8) + (-data.get(0) & 0b11111111))  * -1);  // negative number
+                                    plcValue = DefaultPlcValueHandler.of(tag, (((~data.get(3) & 0b01111111) << 24) + ((-data.get(2) & 0b11111111) << 16)+ ((-data.get(1) & 0b11111111) << 8) + (-data.get(0) & 0b11111111))  * -1);  // negative number
                                 }
                             }
                             break;
@@ -210,9 +210,9 @@ public class Plc4xAbEthProtocol extends PlcMessageToMessageCodec<CIPEncapsulatio
                                 DF1CommandResponseMessageProtectedTypedLogicalRead df1PTLR = (DF1CommandResponseMessageProtectedTypedLogicalRead) plcReadResponse.getResponse();
                                 List<Short> data = df1PTLR.getData();
                                 if (tag.getBitNumber() < 8) {
-                                    plcValue = PlcValueHandler.of((data.get(0) & (1 <<  tag.getBitNumber())) != 0);         // read from first byte
+                                    plcValue = DefaultPlcValueHandler.of(tag, (data.get(0) & (1 <<  tag.getBitNumber())) != 0);         // read from first byte
                                 } else {
-                                    plcValue = PlcValueHandler.of((data.get(1) & (1 << (tag.getBitNumber() - 8) )) != 0);   // read from second byte
+                                    plcValue = DefaultPlcValueHandler.of(tag, (data.get(1) & (1 << (tag.getBitNumber() - 8) )) != 0);   // read from second byte
                                 }
                             }
                             break;
@@ -225,7 +225,7 @@ public class Plc4xAbEthProtocol extends PlcMessageToMessageCodec<CIPEncapsulatio
                     logger.warn("Some other error occurred casting field {}, TagInformation: {}",tagName, tag,e);
                 }
             }
-            ResponseItem<PlcValue> result = new ResponseItem<>(responseCode, plcValue);
+            PlcResponseItem<PlcValue> result = new DefaultPlcResponseItem<>(responseCode, plcValue);
             values.put(tagName, result);
         }
 
diff --git a/plc4j/drivers/ab-eth/src/test/resources/logback-test.xml b/plc4j/drivers/ab-eth/src/test/resources/logback-test.xml
index 2b9cea25dc..941f1546f8 100644
--- a/plc4j/drivers/ab-eth/src/test/resources/logback-test.xml
+++ b/plc4j/drivers/ab-eth/src/test/resources/logback-test.xml
@@ -29,7 +29,7 @@
     </encoder>
   </appender>
 
-  <root level="error">
+  <root level="warn">
     <appender-ref ref="STDOUT" />
   </root>
 
diff --git a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/AdsPlcDriver.java b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/AdsPlcDriver.java
index 5ea4543367..641bc781af 100644
--- a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/AdsPlcDriver.java
+++ b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/AdsPlcDriver.java
@@ -22,14 +22,12 @@ import io.netty.buffer.ByteBuf;
 import org.apache.plc4x.java.ads.configuration.AdsConfiguration;
 import org.apache.plc4x.java.ads.configuration.AdsTcpTransportConfiguration;
 import org.apache.plc4x.java.ads.discovery.AdsPlcDiscoverer;
-import org.apache.plc4x.java.ads.tag.AdsTagHandler;
 import org.apache.plc4x.java.ads.protocol.AdsProtocolLogic;
 import org.apache.plc4x.java.ads.readwrite.AmsTCPPacket;
 import org.apache.plc4x.java.spi.configuration.PlcConnectionConfiguration;
 import org.apache.plc4x.java.spi.configuration.PlcTransportConfiguration;
 import org.apache.plc4x.java.api.messages.PlcDiscoveryRequest;
 import org.apache.plc4x.java.spi.messages.DefaultPlcDiscoveryRequest;
-import org.apache.plc4x.java.spi.values.PlcValueHandler;
 import org.apache.plc4x.java.spi.connection.GeneratedDriverBase;
 import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer;
 import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer;
@@ -116,16 +114,6 @@ public class AdsPlcDriver extends GeneratedDriverBase<AmsTCPPacket> {
         return Collections.singletonList("tcp");
     }
 
-    @Override
-    protected AdsTagHandler getTagHandler() {
-        return new AdsTagHandler();
-    }
-
-    @Override
-    protected org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() {
-        return new PlcValueHandler();
-    }
-
     /**
      * This protocol doesn't have a disconnect procedure, so there is no need to wait for a login to finish.
      * @return false
diff --git a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/protocol/AdsProtocolLogic.java b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/protocol/AdsProtocolLogic.java
index bc4e308928..5a7e9e47bc 100644
--- a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/protocol/AdsProtocolLogic.java
+++ b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/protocol/AdsProtocolLogic.java
@@ -24,6 +24,7 @@ import org.apache.plc4x.java.ads.discovery.readwrite.*;
 import org.apache.plc4x.java.ads.model.AdsSubscriptionHandle;
 import org.apache.plc4x.java.ads.readwrite.*;
 import org.apache.plc4x.java.ads.tag.AdsTag;
+import org.apache.plc4x.java.ads.tag.AdsTagHandler;
 import org.apache.plc4x.java.ads.tag.DirectAdsStringTag;
 import org.apache.plc4x.java.ads.tag.DirectAdsTag;
 import org.apache.plc4x.java.ads.tag.SymbolicAdsTag;
@@ -40,9 +41,11 @@ import org.apache.plc4x.java.api.value.PlcValue;
 import org.apache.plc4x.java.spi.ConversationContext;
 import org.apache.plc4x.java.spi.Plc4xProtocolBase;
 import org.apache.plc4x.java.spi.configuration.HasConfiguration;
+import org.apache.plc4x.java.spi.connection.PlcTagHandler;
 import org.apache.plc4x.java.spi.generation.*;
 import org.apache.plc4x.java.spi.messages.*;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem;
 import org.apache.plc4x.java.spi.model.DefaultArrayInfo;
 import org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration;
 import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionTag;
@@ -112,6 +115,11 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
         this.configuration = configuration;
     }
 
+    @Override
+    public PlcTagHandler getTagHandler() {
+        return new AdsTagHandler();
+    }
+
     @Override
     public void onConnect(ConversationContext<AmsTCPPacket> context) {
 
@@ -247,7 +255,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
 
         new Thread(() -> {
             LOGGER.debug("Setting up remote AMS routes.");
-            SocketAddress localSocketAddress = context.getChannel().localAddress();
+            SocketAddress localSocketAddress = conversationContext.getChannel().localAddress();
             InetAddress localAddress = ((InetSocketAddress) localSocketAddress).getAddress();
 
             // Prepare the request message.
@@ -274,7 +282,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
                 addOrUpdateRouteRequest.serialize(writeBuffer);
 
                 // Get the target IP from the connection
-                SocketAddress remoteSocketAddress = context.getChannel().remoteAddress();
+                SocketAddress remoteSocketAddress = conversationContext.getChannel().remoteAddress();
                 InetAddress remoteAddress = ((InetSocketAddress) remoteSocketAddress).getAddress();
 
                 // Create the UDP packet to the broadcast address.
@@ -513,7 +521,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
                     itemArrayInfo.add(new DefaultPlcBrowseItemArrayInfo(
                         adsDataTypeArrayInfo.getLowerBound(), adsDataTypeArrayInfo.getUpperBound()));
                 }
-                DefaultListPlcBrowseItem item = new DefaultListPlcBrowseItem(new SymbolicAdsTag(symbol.getName(), plc4xPlcValueType, arrayInfo), symbol.getName(),
+                DefaultPlcBrowseItemList item = new DefaultPlcBrowseItemList(new SymbolicAdsTag(symbol.getName(), plc4xPlcValueType, arrayInfo), symbol.getName(),
                     true, !symbol.getFlagReadOnly(), true, false, childMap, options, itemArrayInfo);
 
                 // Check if this item should be added to the result
@@ -576,7 +584,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
                     adsDataTypeArrayInfo.getLowerBound(), adsDataTypeArrayInfo.getUpperBound()));
             }
             // Add the type itself.
-            values.add(new DefaultListPlcBrowseItem(new SymbolicAdsTag(
+            values.add(new DefaultPlcBrowseItemList(new SymbolicAdsTag(
                 basePath + "." + child.getPropertyName(), plc4xPlcValueType, arrayInfo), child.getPropertyName(),
                 true, parentWritable, true, false, childMap, options, itemArrayInfo));
         }
@@ -592,10 +600,10 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
             configuration.getSourceAmsNetId(), 800, 0, getInvokeId());
 
         RequestTransactionManager.RequestTransaction readDeviceInfoTx = tm.startRequest();
-        readDeviceInfoTx.submit(() -> context.sendRequest(new AmsTCPPacket(readDeviceInfoRequest))
+        readDeviceInfoTx.submit(() -> conversationContext.sendRequest(new AmsTCPPacket(readDeviceInfoRequest))
             .expectResponse(AmsTCPPacket.class, Duration.ofMillis(configuration.getTimeoutRequest()))
-            .onTimeout(e -> context.getChannel().pipeline().fireExceptionCaught(e))
-            .onError((p, e) -> context.getChannel().pipeline().fireExceptionCaught(e))
+            .onTimeout(e -> conversationContext.getChannel().pipeline().fireExceptionCaught(e))
+            .onError((p, e) -> conversationContext.getChannel().pipeline().fireExceptionCaught(e))
             .unwrap(AmsTCPPacket::getUserdata)
             .check(userdata -> userdata.getInvokeId() == readDeviceInfoRequest.getInvokeId())
             .only(AdsReadDeviceInfoResponse.class)
@@ -672,7 +680,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
         if(directAdsTag == null) {
             return CompletableFuture.completedFuture(new DefaultPlcReadResponse(readRequest, Collections.singletonMap(
                 readRequest.getTagNames().stream().findFirst().orElseThrow(),
-                new ResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null))));
+                new DefaultPlcResponseItem<>(PlcResponseCode.NOT_FOUND, null))));
         }
 
         CompletableFuture<PlcReadResponse> future = new CompletableFuture<>();
@@ -693,7 +701,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
 
         // Start a new request-transaction (Is ended in the response-handler)
         RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
-        transaction.submit(() -> context.sendRequest(amsTCPPacket)
+        transaction.submit(() -> conversationContext.sendRequest(amsTCPPacket)
             .expectResponse(AmsTCPPacket.class, Duration.ofMillis(configuration.getTimeoutRequest()))
             .onTimeout(future::completeExceptionally)
             .onError((p, e) -> future.completeExceptionally(e))
@@ -766,7 +774,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
 
         // Start a new request-transaction (Is ended in the response-handler)
         RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
-        transaction.submit(() -> context.sendRequest(amsTCPPacket)
+        transaction.submit(() -> conversationContext.sendRequest(amsTCPPacket)
             .expectResponse(AmsTCPPacket.class, Duration.ofMillis(configuration.getTimeoutRequest()))
             .onTimeout(future::completeExceptionally)
             .onError((p, e) -> future.completeExceptionally(e))
@@ -822,11 +830,11 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
 
         // Read the values next
         if (readBuffer != null) {
-            Map<String, ResponseItem<PlcValue>> values = new HashMap<>();
+            Map<String, PlcResponseItem<PlcValue>> values = new HashMap<>();
             for (String tagName : readRequest.getTagNames()) {
                 // If the response-code was anything but OK, we don't need to parse the payload.
                 if(responseCodes.get(tagName) != PlcResponseCode.OK) {
-                    values.put(tagName, new ResponseItem<>(responseCodes.get(tagName), null));
+                    values.put(tagName, new DefaultPlcResponseItem<>(responseCodes.get(tagName), null));
                 }
                 // If the response-code was ok, parse the data returned.
                 else {
@@ -849,7 +857,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
         }
     }
 
-    private ResponseItem<PlcValue> parseResponseItem(DirectAdsTag tag, ReadBuffer readBuffer) {
+    private PlcResponseItem<PlcValue> parseResponseItem(DirectAdsTag tag, ReadBuffer readBuffer) {
         try {
             String dataTypeName = tag.getPlcDataType();
             AdsDataTypeTableEntry adsDataTypeTableEntry;
@@ -872,7 +880,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
                 // Sometimes the ADS device just sends shorter strings than we asked for.
                 int remainingBytes = readBufferByteBased.getTotalBytes() - readBufferByteBased.getPos();
                 final int singleStringLength = Math.min(remainingBytes - 1, stringLength);
-                return new ResponseItem<>(PlcResponseCode.OK, parsePlcValue(plcValueType, adsDataTypeTableEntry, singleStringLength, readBuffer));
+                return new DefaultPlcResponseItem<>(PlcResponseCode.OK, parsePlcValue(plcValueType, adsDataTypeTableEntry, singleStringLength, readBuffer));
             } else {
                 // Fetch all
                 final PlcValue[] resultItems = IntStream.range(0, tag.getNumberOfElements()).mapToObj(i -> {
@@ -883,11 +891,11 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
                     }
                     return null;
                 }).toArray(PlcValue[]::new);
-                return new ResponseItem<>(PlcResponseCode.OK, PlcValueHandler.of(resultItems));
+                return new DefaultPlcResponseItem<>(PlcResponseCode.OK, DefaultPlcValueHandler.of(tag, resultItems));
             }
         } catch (Exception e) {
             LOGGER.warn(String.format("Error parsing tag item of type: '%s'", tag.getPlcDataType()), e);
-            return new ResponseItem<>(PlcResponseCode.INTERNAL_ERROR, null);
+            return new DefaultPlcResponseItem<>(PlcResponseCode.INTERNAL_ERROR, null);
         }
     }
 
@@ -1046,7 +1054,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
 
         // Start a new request-transaction (Is ended in the response-handler)
         RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
-        transaction.submit(() -> context.sendRequest(amsTCPPacket)
+        transaction.submit(() -> conversationContext.sendRequest(amsTCPPacket)
             .expectResponse(AmsTCPPacket.class, Duration.ofMillis(configuration.getTimeoutRequest()))
             .onTimeout(future::completeExceptionally)
             .onError((p, e) -> future.completeExceptionally(e))
@@ -1124,7 +1132,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
 
         // Start a new request-transaction (Is ended in the response-handler)
         RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
-        transaction.submit(() -> context.sendRequest(amsTCPPacket)
+        transaction.submit(() -> conversationContext.sendRequest(amsTCPPacket)
             .expectResponse(AmsTCPPacket.class, Duration.ofMillis(configuration.getTimeoutRequest()))
             .onTimeout(future::completeExceptionally)
             .onError((p, e) -> future.completeExceptionally(e))
@@ -1329,7 +1337,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
             })
             .collect(Collectors.toList());
 
-        Map<String, ResponseItem<PlcSubscriptionHandle>> responses = new HashMap<>();
+        Map<String, PlcResponseItem<PlcSubscriptionHandle>> responses = new HashMap<>();
 
         // Start the first request-transaction (it is ended in the response-handler).
         RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
@@ -1347,7 +1355,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
     private Runnable subscribeRecursively(PlcSubscriptionRequest subscriptionRequest,
                                           Iterator<String> tagNames,
                                           Map<AdsTag, DirectAdsTag> resolvedTags,
-                                          Map<String, ResponseItem<PlcSubscriptionHandle>> responses,
+                                          Map<String, PlcResponseItem<PlcSubscriptionHandle>> responses,
                                           CompletableFuture<PlcSubscriptionResponse> future,
                                           Iterator<AmsTCPPacket> amsTCPPackets,
                                           RequestTransactionManager.RequestTransaction transaction) {
@@ -1355,7 +1363,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
             AmsTCPPacket packet = amsTCPPackets.next();
             boolean hasMorePackets = amsTCPPackets.hasNext();
             String tagName = tagNames.next();
-            context.sendRequest(packet)
+            conversationContext.sendRequest(packet)
                 .expectResponse(AmsTCPPacket.class, Duration.ofMillis(configuration.getTimeoutRequest()))
                 .onTimeout(future::completeExceptionally)
                 .onError((p, e) -> future.completeExceptionally(e))
@@ -1368,7 +1376,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
                         AdsDataTypeTableEntry adsDataTypeTableEntry = dataTypeTable.get((resolvedTags.get((AdsTag) subscriptionTag.getTag())).getPlcDataType());
 
                         // Collect notification handle from individual response.
-                        responses.put(tagName, new ResponseItem<>(
+                        responses.put(tagName, new DefaultPlcResponseItem<>(
                             parsePlcResponseCode(response.getResult()),
                             new AdsSubscriptionHandle(this,
                                 tagName,
@@ -1436,7 +1444,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
         return () -> {
             AmsTCPPacket packet = amsTCPPackets.next();
             boolean hasMorePackets = amsTCPPackets.hasNext();
-            context.sendRequest(packet)
+            conversationContext.sendRequest(packet)
                 .expectResponse(AmsTCPPacket.class, Duration.ofMillis(configuration.getTimeoutRequest()))
                 .onTimeout(future::completeExceptionally)
                 .onError((p, e) -> future.completeExceptionally(e))
@@ -1498,11 +1506,11 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
         }
     }
 
-    private Map<String, ResponseItem<PlcValue>> convertSampleToPlc4XResult(AdsSubscriptionHandle subscriptionHandle, byte[] data) throws
+    private Map<String, PlcResponseItem<PlcValue>> convertSampleToPlc4XResult(AdsSubscriptionHandle subscriptionHandle, byte[] data) throws
         ParseException {
-        Map<String, ResponseItem<PlcValue>> values = new HashMap<>();
+        Map<String, PlcResponseItem<PlcValue>> values = new HashMap<>();
         ReadBufferByteBased readBuffer = new ReadBufferByteBased(data, ByteOrder.LITTLE_ENDIAN);
-        values.put(subscriptionHandle.getTagName(), new ResponseItem<>(PlcResponseCode.OK,
+        values.put(subscriptionHandle.getTagName(), new DefaultPlcResponseItem<>(PlcResponseCode.OK,
             DataItem.staticParse(readBuffer, getPlcValueTypeForAdsDataType(subscriptionHandle.getAdsDataType()), data.length)));
         return values;
     }
@@ -1614,7 +1622,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
 
         // Start a new request-transaction (Is ended in the response-handler)
         RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
-        transaction.submit(() -> context.sendRequest(amsTCPPacket)
+        transaction.submit(() -> conversationContext.sendRequest(amsTCPPacket)
             .expectResponse(AmsTCPPacket.class, Duration.ofMillis(configuration.getTimeoutRequest()))
             .onTimeout(future::completeExceptionally)
             .onError((p, e) -> future.completeExceptionally(e))
@@ -1665,7 +1673,7 @@ public class AdsProtocolLogic extends Plc4xProtocolBase<AmsTCPPacket> implements
 
         // Start a new request-transaction (Is ended in the response-handler)
         RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
-        transaction.submit(() -> context.sendRequest(amsTCPPacket)
+        transaction.submit(() -> conversationContext.sendRequest(amsTCPPacket)
             .expectResponse(AmsTCPPacket.class, Duration.ofMillis(configuration.getTimeoutRequest()))
             .onTimeout(future::completeExceptionally)
             .onError((p, e) -> future.completeExceptionally(e))
diff --git a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/tag/SymbolicAdsTag.java b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/tag/SymbolicAdsTag.java
index 8aa5c41cde..a708ee97a9 100644
--- a/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/tag/SymbolicAdsTag.java
+++ b/plc4j/drivers/ads/src/main/java/org/apache/plc4x/java/ads/tag/SymbolicAdsTag.java
@@ -37,8 +37,7 @@ import java.util.regex.Pattern;
  */
 public class SymbolicAdsTag implements AdsTag {
 
-    // TODO: Model the end of this address to allow usage of multi-dimensional arrays.
-    private static final Pattern SYMBOLIC_ADDRESS_PATTERN = Pattern.compile("^(?<symbolicAddress>.+)");
+    private static final Pattern SYMBOLIC_ADDRESS_PATTERN = Pattern.compile("^([\\w_]+)(\"[\"\\d*]\")*(\\.(\\w+)(\"[\"\\d*]\")*)*");
 
     private final String symbolicAddress;
 
@@ -57,9 +56,7 @@ public class SymbolicAdsTag implements AdsTag {
         if (!matcher.matches()) {
             throw new PlcInvalidTagException(address, SYMBOLIC_ADDRESS_PATTERN, "{address}");
         }
-        String symbolicAddress = matcher.group("symbolicAddress");
-
-        return new SymbolicAdsTag(symbolicAddress, null, Collections.emptyList());
+        return new SymbolicAdsTag(address, null, Collections.emptyList());
     }
 
     public static boolean matches(String address) {
@@ -120,4 +117,5 @@ public class SymbolicAdsTag implements AdsTag {
 
         writeBuffer.popContext(getClass().getSimpleName());
     }
+
 }
diff --git a/plc4j/drivers/eip/src/test/java/org/apache/plc4x/java/eip/base/EIPDriverIT.java b/plc4j/drivers/ads/src/test/java/org/apache/plc4x/java/ads/tag/SymbolicAdsTagTest.java
similarity index 77%
copy from plc4j/drivers/eip/src/test/java/org/apache/plc4x/java/eip/base/EIPDriverIT.java
copy to plc4j/drivers/ads/src/test/java/org/apache/plc4x/java/ads/tag/SymbolicAdsTagTest.java
index dd18cc6859..8ec9bc0038 100644
--- a/plc4j/drivers/eip/src/test/java/org/apache/plc4x/java/eip/base/EIPDriverIT.java
+++ b/plc4j/drivers/ads/src/test/java/org/apache/plc4x/java/ads/tag/SymbolicAdsTagTest.java
@@ -16,14 +16,19 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.plc4x.java.eip.base;
 
-import org.apache.plc4x.test.driver.DriverTestsuiteRunner;
+package org.apache.plc4x.java.ads.tag;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class SymbolicAdsTagTest {
+
+    @Test
+    void of() {
 
-public class EIPDriverIT extends DriverTestsuiteRunner {
 
-    public EIPDriverIT() {
-        super("/protocols/eip/DriverTestsuite.xml");
     }
 
-}
+}
\ No newline at end of file
diff --git a/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/AdsDriverIT.java b/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/AdsDriverIT.java
index 15a827b81f..6f1f5c2c7d 100644
--- a/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/AdsDriverIT.java
+++ b/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/AdsDriverIT.java
@@ -24,7 +24,7 @@ import org.junit.jupiter.api.Disabled;
 public class AdsDriverIT extends DriverTestsuiteRunner {
 
     public AdsDriverIT() {
-        super("/protocols/ads/DriverTestsuite.xml");
+        super("/protocols/ads/DriverTestsuite.xml", true);
     }
 
 }
diff --git a/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/ManualAdsBrowse.java b/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/ManualAdsBrowse.java
index f9240a3c87..5c850d372e 100644
--- a/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/ManualAdsBrowse.java
+++ b/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/ManualAdsBrowse.java
@@ -21,14 +21,15 @@ package org.apache.plc4x.protocol.ads;
 
 import org.apache.plc4x.java.api.PlcConnection;
 import org.apache.plc4x.java.api.PlcDriverManager;
-import org.apache.plc4x.java.api.messages.PlcBrowseResponse;
 
 public class ManualAdsBrowse {
 
     public static void main(String[] args) throws Exception {
         try (PlcConnection connection = PlcDriverManager.getDefault().getConnectionManager().getConnection("ads:tcp://192.168.23.20:48898?target-ams-port=851&source-ams-port=65534&source-ams-net-id=192.168.23.220.1.1&target-ams-net-id=192.168.23.20.1.1")){
-            PlcBrowseResponse browseResponse = connection.browseRequestBuilder().addQuery("all", "*").build().execute().get();
-            System.out.println(browseResponse);
+            connection.browseRequestBuilder().addQuery("all", "*").build().executeWithInterceptor(item -> {
+                System.out.printf("- %s%n", item.getTag().getAddressString());
+                return true;
+            }).get();
         }
     }
 }
diff --git a/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/ManualAdsDriverTest.java b/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/ManualAdsDriverTest.java
index b04acbbdf5..d623a701c0 100644
--- a/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/ManualAdsDriverTest.java
+++ b/plc4j/drivers/ads/src/test/java/org/apache/plc4x/protocol/ads/ManualAdsDriverTest.java
@@ -26,6 +26,7 @@ import java.time.Duration;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
+import java.time.OffsetDateTime;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -129,8 +130,12 @@ public class ManualAdsDriverTest extends ManualTest {
         children.put("hurz_LTIME", new PlcLTIME(Duration.parse("PT24015H23M12.034002044S")));
         children.put("hurz_DATE", new PlcDATE(LocalDate.parse("1978-03-28")));
         children.put("hurz_TIME_OF_DAY", new PlcTIME_OF_DAY(LocalTime.parse("15:36:30.123")));
-        children.put("hurz_DATE_AND_TIME", new PlcDATE_AND_TIME(LocalDateTime.parse("1996-05-06T15:36:30")));
+        children.put("hurz_DATE_AND_TIME", new PlcDATE_AND_TIME(LocalDateTime.parse("1996-05-06T15:36:30").atOffset(OffsetDateTime.now().getOffset()).toLocalDateTime()));
         test.addTestCase("MAIN.hurz_Struct", new PlcStruct(children));
+        //test.addTestCase("MAIN.thisVariableDoesntExist", PlcResponseCode.NOT_FOUND);
+        // TODO: Add some complex array path
+        //test.addTestCase("...3323(/987", PlcResponseCode.INVALID_ADDRESS);
+        //test.addTestCase("MAIN.hurz_UDT_array[4].hurz_INT_array[2].someProperty", PlcResponseCode.NOT_FOUND);
         test.run();
     }
 
diff --git a/plc4j/drivers/bacnet/src/main/java/org/apache/plc4x/java/bacnetip/BacNetIpDriver.java b/plc4j/drivers/bacnet/src/main/java/org/apache/plc4x/java/bacnetip/BacNetIpDriver.java
index 28d1e9a2f1..ccffd6ddf5 100644
--- a/plc4j/drivers/bacnet/src/main/java/org/apache/plc4x/java/bacnetip/BacNetIpDriver.java
+++ b/plc4j/drivers/bacnet/src/main/java/org/apache/plc4x/java/bacnetip/BacNetIpDriver.java
@@ -25,13 +25,11 @@ import org.apache.plc4x.java.bacnetip.configuration.BacNetIpConfiguration;
 import org.apache.plc4x.java.bacnetip.configuration.BacNetPcapReplayTransportConfiguration;
 import org.apache.plc4x.java.bacnetip.configuration.BacNetRawSocketTransportConfiguration;
 import org.apache.plc4x.java.bacnetip.configuration.BacNetUdpTransportConfiguration;
-import org.apache.plc4x.java.bacnetip.tag.BacNetIpTagHandler;
 import org.apache.plc4x.java.bacnetip.protocol.BacNetIpProtocolLogic;
 import org.apache.plc4x.java.bacnetip.readwrite.BVLC;
 import org.apache.plc4x.java.spi.connection.GeneratedDriverBase;
 import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer;
 import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer;
-import org.apache.plc4x.java.spi.values.PlcValueHandler;
 
 import java.util.Arrays;
 import java.util.List;
@@ -94,16 +92,6 @@ public class BacNetIpDriver extends GeneratedDriverBase<BVLC> {
         return true;
     }
 
-    @Override
-    protected BacNetIpTagHandler getTagHandler() {
-        return new BacNetIpTagHandler();
-    }
-
-    @Override
-    protected org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() {
-        return new PlcValueHandler();
-    }
-
     @Override
     protected ProtocolStackConfigurer<BVLC> getStackConfigurer() {
         return SingleProtocolStackConfigurer.builder(BVLC.class, BVLC::staticParse)
diff --git a/plc4j/drivers/bacnet/src/main/java/org/apache/plc4x/java/bacnetip/protocol/BacNetIpProtocolLogic.java b/plc4j/drivers/bacnet/src/main/java/org/apache/plc4x/java/bacnetip/protocol/BacNetIpProtocolLogic.java
index 2eddb897e5..ecf8b79d40 100644
--- a/plc4j/drivers/bacnet/src/main/java/org/apache/plc4x/java/bacnetip/protocol/BacNetIpProtocolLogic.java
+++ b/plc4j/drivers/bacnet/src/main/java/org/apache/plc4x/java/bacnetip/protocol/BacNetIpProtocolLogic.java
@@ -32,17 +32,19 @@ import org.apache.plc4x.java.bacnetip.ede.model.Datapoint;
 import org.apache.plc4x.java.bacnetip.ede.model.EdeModel;
 import org.apache.plc4x.java.bacnetip.tag.BacNetIpTag;
 import org.apache.plc4x.java.bacnetip.readwrite.*;
+import org.apache.plc4x.java.bacnetip.tag.BacNetIpTagHandler;
 import org.apache.plc4x.java.spi.ConversationContext;
 import org.apache.plc4x.java.spi.Plc4xProtocolBase;
 import org.apache.plc4x.java.spi.configuration.HasConfiguration;
+import org.apache.plc4x.java.spi.connection.PlcTagHandler;
 import org.apache.plc4x.java.spi.messages.DefaultPlcSubscriptionEvent;
 import org.apache.plc4x.java.spi.messages.DefaultPlcSubscriptionResponse;
 import org.apache.plc4x.java.spi.messages.PlcSubscriber;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem;
 import org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration;
 import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionHandle;
 import org.apache.plc4x.java.spi.values.*;
-import org.apache.plc4x.java.spi.values.PlcValueHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -85,6 +87,11 @@ public class BacNetIpProtocolLogic extends Plc4xProtocolBase<BVLC> implements Ha
         }
     }
 
+    @Override
+    public PlcTagHandler getTagHandler() {
+        return new BacNetIpTagHandler();
+    }
+
     @Override
     public void onConnect(ConversationContext<BVLC> context) {
         if (context.isPassive()) {
@@ -163,8 +170,8 @@ public class BacNetIpProtocolLogic extends Plc4xProtocolBase<BVLC> implements Ha
                     enrichedPlcValue.put("address", new PlcSTRING(toString(curTag)));
 
                     // From the original BACNet tag
-                    enrichedPlcValue.put("tagNumber", PlcValueHandler.of(propertyValue.getPeekedTagHeader().getActualTagNumber()));
-                    enrichedPlcValue.put("lengthValueType", PlcValueHandler.of(propertyValue.getPeekedTagHeader().getActualLength()));
+                    enrichedPlcValue.put("tagNumber", new PlcUSINT(propertyValue.getPeekedTagHeader().getActualTagNumber()));
+                    enrichedPlcValue.put("lengthValueType", new PlcUSINT(propertyValue.getPeekedTagHeader().getActualLength()));
 
                     // Use the information in the edeModel to enrich the information.
                     if (edeModel != null) {
@@ -214,8 +221,8 @@ public class BacNetIpProtocolLogic extends Plc4xProtocolBase<BVLC> implements Ha
                     enrichedPlcValue.put("address", new PlcSTRING(toString(curTag)));
 
                     // From the original BACNet tag
-                    enrichedPlcValue.put("tagNumber", PlcValueHandler.of(baCnetTag.getActualTagNumber()));
-                    enrichedPlcValue.put("lengthValueType", PlcValueHandler.of(baCnetTag.getActualLength()));
+                    enrichedPlcValue.put("tagNumber", new PlcUSINT(baCnetTag.getActualTagNumber()));
+                    enrichedPlcValue.put("lengthValueType", new PlcUSINT(baCnetTag.getActualLength()));
 
                     // Use the information in the edeModel to enrich the information.
                     if (edeModel != null) {
@@ -244,9 +251,9 @@ public class BacNetIpProtocolLogic extends Plc4xProtocolBase<BVLC> implements Ha
 
     @Override
     public CompletableFuture<PlcSubscriptionResponse> subscribe(PlcSubscriptionRequest subscriptionRequest) {
-        Map<String, ResponseItem<PlcSubscriptionHandle>> values = new HashMap<>();
+        Map<String, PlcResponseItem<PlcSubscriptionHandle>> values = new HashMap<>();
         for (String tagName : subscriptionRequest.getTagNames()) {
-            values.put(tagName, new ResponseItem<>(PlcResponseCode.OK, new DefaultPlcSubscriptionHandle(this)));
+            values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, new DefaultPlcSubscriptionHandle(this)));
         }
         return CompletableFuture.completedFuture(new DefaultPlcSubscriptionResponse(subscriptionRequest, values));
     }
@@ -268,7 +275,7 @@ public class BacNetIpProtocolLogic extends Plc4xProtocolBase<BVLC> implements Ha
     protected void publishEvent(BacNetIpTag tag, PlcValue plcValue) {
         // Create a subscription event from the input.
         final PlcSubscriptionEvent event = new DefaultPlcSubscriptionEvent(Instant.now(),
-            Collections.singletonMap("event", new ResponseItem<>(PlcResponseCode.OK, plcValue)));
+            Collections.singletonMap("event", new DefaultPlcResponseItem<>(PlcResponseCode.OK, plcValue)));
 
         // Send the subscription event to all listeners.
         for (Consumer<PlcSubscriptionEvent> consumer : consumerIdMap.values()) {
diff --git a/plc4j/drivers/bacnet/src/test/resources/logback-test.xml b/plc4j/drivers/bacnet/src/test/resources/logback-test.xml
index ad561b1796..898c2820e6 100644
--- a/plc4j/drivers/bacnet/src/test/resources/logback-test.xml
+++ b/plc4j/drivers/bacnet/src/test/resources/logback-test.xml
@@ -28,7 +28,7 @@
   <!-- TODO: why doesn't this work? log won't be switched off-->
   <logger name="org.apache.plc4x.java.bacnetip.RandomPackagesTest" level="OFF"/>
 
-  <root level="error">
+  <root level="warn">
     <appender-ref ref="STDOUT" />
   </root>
 
diff --git a/plc4j/drivers/c-bus/src/main/java/org/apache/plc4x/java/cbus/CBusDriver.java b/plc4j/drivers/c-bus/src/main/java/org/apache/plc4x/java/cbus/CBusDriver.java
index 300ffa9450..1065a50c1b 100644
--- a/plc4j/drivers/c-bus/src/main/java/org/apache/plc4x/java/cbus/CBusDriver.java
+++ b/plc4j/drivers/c-bus/src/main/java/org/apache/plc4x/java/cbus/CBusDriver.java
@@ -19,19 +19,15 @@
 package org.apache.plc4x.java.cbus;
 
 import io.netty.buffer.ByteBuf;
-import org.apache.plc4x.java.cbus.readwrite.CBusMessage;
 import org.apache.plc4x.java.cbus.readwrite.CBusOptions;
-import org.apache.plc4x.java.cbus.readwrite.RequestContext;
 import org.apache.plc4x.java.spi.configuration.PlcConnectionConfiguration;
 import org.apache.plc4x.java.spi.configuration.PlcTransportConfiguration;
-import org.apache.plc4x.java.api.value.PlcValueHandler;
 import org.apache.plc4x.java.cbus.configuration.CBusConfiguration;
 import org.apache.plc4x.java.cbus.configuration.CBusTcpTransportConfiguration;
 import org.apache.plc4x.java.cbus.context.CBusDriverContext;
 import org.apache.plc4x.java.cbus.protocol.CBusProtocolLogic;
 import org.apache.plc4x.java.cbus.readwrite.CBusCommand;
 import org.apache.plc4x.java.spi.connection.GeneratedDriverBase;
-import org.apache.plc4x.java.spi.connection.PlcTagHandler;
 import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer;
 import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer;
 
@@ -83,16 +79,6 @@ public class CBusDriver extends GeneratedDriverBase<CBusCommand> {
         return Collections.singletonList("tcp");
     }
 
-    @Override
-    protected PlcTagHandler getTagHandler() {
-        return null;
-    }
-
-    @Override
-    protected PlcValueHandler getValueHandler() {
-        return null;
-    }
-
     @Override
     protected ProtocolStackConfigurer<CBusCommand> getStackConfigurer() {
         return SingleProtocolStackConfigurer.builder(CBusCommand.class, io ->
diff --git a/plc4j/drivers/c-bus/src/main/java/org/apache/plc4x/java/cbus/protocol/CBusProtocolLogic.java b/plc4j/drivers/c-bus/src/main/java/org/apache/plc4x/java/cbus/protocol/CBusProtocolLogic.java
index 7bed821a08..41d27fe5a6 100644
--- a/plc4j/drivers/c-bus/src/main/java/org/apache/plc4x/java/cbus/protocol/CBusProtocolLogic.java
+++ b/plc4j/drivers/c-bus/src/main/java/org/apache/plc4x/java/cbus/protocol/CBusProtocolLogic.java
@@ -22,6 +22,7 @@ import org.apache.plc4x.java.api.messages.*;
 import org.apache.plc4x.java.cbus.readwrite.CBusCommand;
 import org.apache.plc4x.java.spi.ConversationContext;
 import org.apache.plc4x.java.spi.Plc4xProtocolBase;
+import org.apache.plc4x.java.spi.connection.PlcTagHandler;
 import org.apache.plc4x.java.spi.context.DriverContext;
 import org.apache.plc4x.java.spi.messages.*;
 import org.apache.plc4x.java.spi.transaction.RequestTransactionManager;
@@ -48,6 +49,11 @@ public class CBusProtocolLogic extends Plc4xProtocolBase<CBusCommand> {
         this.tm = new RequestTransactionManager(1);
     }
 
+    @Override
+    public PlcTagHandler getTagHandler() {
+        return null;
+    }
+
     @Override
     public void close(ConversationContext<CBusCommand> context) {
         tm.shutdown();
diff --git a/plc4j/drivers/c-bus/src/test/resources/logback-test.xml b/plc4j/drivers/c-bus/src/test/resources/logback-test.xml
index 264277d573..37b5020ad5 100644
--- a/plc4j/drivers/c-bus/src/test/resources/logback-test.xml
+++ b/plc4j/drivers/c-bus/src/test/resources/logback-test.xml
@@ -25,7 +25,7 @@
     </encoder>
   </appender>
 
-  <root level="error">
+  <root level="warn">
     <appender-ref ref="STDOUT" />
   </root>
 
diff --git a/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/adapter/CANDriverAdapter.java b/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/adapter/CANDriverAdapter.java
index 13eecb8453..bbffecdb60 100644
--- a/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/adapter/CANDriverAdapter.java
+++ b/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/adapter/CANDriverAdapter.java
@@ -32,6 +32,7 @@ import org.apache.plc4x.java.api.messages.PlcWriteResponse;
 import org.apache.plc4x.java.can.adapter.conversation.ConversationContextWrapper;
 import org.apache.plc4x.java.spi.ConversationContext;
 import org.apache.plc4x.java.spi.Plc4xProtocolBase;
+import org.apache.plc4x.java.spi.connection.PlcTagHandler;
 import org.apache.plc4x.java.spi.context.DriverContext;
 import org.apache.plc4x.java.transport.can.CANTransport.FrameHandler;
 import org.apache.plc4x.java.transport.can.FrameData;
@@ -42,12 +43,14 @@ public class CANDriverAdapter<C, T> extends Plc4xProtocolBase<C> {
     private final Class<C> wireType;
     private final Function<C, FrameData> adapter;
     private final FrameHandler<C, T> frameHandler;
+    private final PlcTagHandler tagHandler;
 
-    public CANDriverAdapter(Plc4xCANProtocolBase<T> delegate, Class<C> wireType, Function<C, FrameData> adapter, FrameHandler<C, T> frameHandler) {
+    public CANDriverAdapter(Plc4xCANProtocolBase<T> delegate, Class<C> wireType, Function<C, FrameData> adapter, FrameHandler<C, T> frameHandler, PlcTagHandler tagHandler) {
         this.delegate = delegate;
         this.wireType = wireType;
         this.adapter = adapter;
         this.frameHandler = frameHandler;
+        this.tagHandler = tagHandler;
     }
 
     @Override
@@ -61,8 +64,13 @@ public class CANDriverAdapter<C, T> extends Plc4xProtocolBase<C> {
     }
 
     @Override
-    public void setContext(ConversationContext<C> context) {
-        delegate.setContext(new ConversationContextWrapper<>(context, wireType, adapter, frameHandler, context.getAuthentication()));
+    public void setConversationContext(ConversationContext<C> conversationContext) {
+        delegate.setConversationContext(new ConversationContextWrapper<>(conversationContext, wireType, adapter, frameHandler, conversationContext.getAuthentication()));
+    }
+
+    @Override
+    public PlcTagHandler getTagHandler() {
+        return tagHandler;
     }
 
     @Override
diff --git a/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/adapter/conversation/DeferredRequestContextWrapper.java b/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/adapter/conversation/DeferredRequestContextWrapper.java
index 0f75fd407a..c7c3175426 100644
--- a/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/adapter/conversation/DeferredRequestContextWrapper.java
+++ b/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/adapter/conversation/DeferredRequestContextWrapper.java
@@ -19,6 +19,7 @@
 package org.apache.plc4x.java.can.adapter.conversation;
 
 import java.time.Duration;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.TimeoutException;
 import java.util.function.BiConsumer;
 import java.util.function.Consumer;
@@ -67,6 +68,13 @@ public class DeferredRequestContextWrapper<T> implements SendRequestContext<T> {
         return delegate.handle(packetConsumer);
     }
 
+    @Override
+    public CompletableFuture<T> toFuture() {
+        CompletableFuture<T> future = new CompletableFuture<>();
+        handle(future::complete);
+        return future;
+    }
+
     @Override
     public SendRequestContext<T> onTimeout(Consumer<TimeoutException> packetConsumer) {
         return new DeferredRequestContextWrapper<>(name, delegate, completer, packetConsumer, errorConsumer);
diff --git a/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/adapter/conversation/ResolvedSendRequestContextWrapper.java b/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/adapter/conversation/ResolvedSendRequestContextWrapper.java
index fa2d7d6053..5fe07e3342 100644
--- a/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/adapter/conversation/ResolvedSendRequestContextWrapper.java
+++ b/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/adapter/conversation/ResolvedSendRequestContextWrapper.java
@@ -19,6 +19,7 @@
 package org.apache.plc4x.java.can.adapter.conversation;
 
 import java.time.Duration;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.TimeoutException;
 import java.util.function.BiConsumer;
 import java.util.function.Consumer;
@@ -65,6 +66,13 @@ public class ResolvedSendRequestContextWrapper<T> implements SendRequestContext<
         return delegate.handle(packetConsumer);
     }
 
+    @Override
+    public CompletableFuture<T> toFuture() {
+        CompletableFuture<T> future = new CompletableFuture<>();
+        handle(future::complete);
+        return future;
+    }
+
     @Override
     public SendRequestContext<T> onTimeout(Consumer<TimeoutException> packetConsumer) {
         timeoutHandler.setHandler(packetConsumer);
diff --git a/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/adapter/conversation/SendRequestContextWrapper.java b/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/adapter/conversation/SendRequestContextWrapper.java
index d17e2c0f74..bba458ddab 100644
--- a/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/adapter/conversation/SendRequestContextWrapper.java
+++ b/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/adapter/conversation/SendRequestContextWrapper.java
@@ -19,6 +19,7 @@
 package org.apache.plc4x.java.can.adapter.conversation;
 
 import java.time.Duration;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.TimeoutException;
 import java.util.function.BiConsumer;
 import java.util.function.Consumer;
@@ -77,6 +78,13 @@ public class SendRequestContextWrapper<C, T> implements SendRequestContext<T> {
         throw new IllegalStateException("Not implemented");
     }
 
+    @Override
+    public CompletableFuture<T> toFuture() {
+        CompletableFuture<T> future = new CompletableFuture<>();
+        handle(future::complete);
+        return future;
+    }
+
     @Override
     public SendRequestContext<T> onTimeout(Consumer<TimeoutException> packetConsumer) {
         throw new IllegalStateException("Not implemented");
diff --git a/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/generic/GenericCANDriver.java b/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/generic/GenericCANDriver.java
index 4d31b799a0..2c7c1413f9 100644
--- a/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/generic/GenericCANDriver.java
+++ b/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/generic/GenericCANDriver.java
@@ -18,12 +18,12 @@
  */
 package org.apache.plc4x.java.can.generic;
 
+import org.apache.plc4x.java.can.generic.tag.GenericCANTagHandler;
 import org.apache.plc4x.java.spi.configuration.PlcConnectionConfiguration;
 import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
 import org.apache.plc4x.java.can.adapter.CANDriverAdapter;
 import org.apache.plc4x.java.can.generic.configuration.GenericCANConfiguration;
 import org.apache.plc4x.java.can.generic.context.GenericCANDriverContext;
-import org.apache.plc4x.java.can.generic.tag.GenericCANTagHandler;
 import org.apache.plc4x.java.can.generic.protocol.GenericCANProtocolLogic;
 import org.apache.plc4x.java.can.generic.transport.GenericCANFrameDataHandler;
 import org.apache.plc4x.java.spi.configuration.ConfigurationFactory;
@@ -33,7 +33,6 @@ import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer;
 import org.apache.plc4x.java.spi.generation.Message;
 import org.apache.plc4x.java.spi.optimizer.BaseOptimizer;
 import org.apache.plc4x.java.spi.transport.Transport;
-import org.apache.plc4x.java.spi.values.PlcValueHandler;
 import org.apache.plc4x.java.transport.can.CANTransport;
 
 import java.util.Optional;
@@ -80,16 +79,6 @@ public class GenericCANDriver extends GeneratedDriverBase<Message> {
         return true;
     }
 
-    @Override
-    protected GenericCANTagHandler getTagHandler() {
-        return new GenericCANTagHandler();
-    }
-
-    @Override
-    protected org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() {
-        return new PlcValueHandler();
-    }
-
     /**
      * This protocol doesn't have a disconnect procedure, so there is no need to wait for a login to finish.
      * @return false
@@ -122,7 +111,8 @@ public class GenericCANDriver extends GeneratedDriverBase<Message> {
                 ConfigurationFactory.configure(cfg, protocolLogic);
                 return new CANDriverAdapter<>(protocolLogic,
                     canTransport.getMessageType(), canTransport.adapter(),
-                    new GenericCANFrameDataHandler(canTransport::getTransportFrameBuilder)
+                    new GenericCANFrameDataHandler(canTransport::getTransportFrameBuilder),
+                    new GenericCANTagHandler()
                 );
             })
             .withDriverContext(cfg -> new GenericCANDriverContext())
diff --git a/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/generic/protocol/GenericCANProtocolLogic.java b/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/generic/protocol/GenericCANProtocolLogic.java
index 6d36b2d7b2..f5704b3b6b 100644
--- a/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/generic/protocol/GenericCANProtocolLogic.java
+++ b/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/generic/protocol/GenericCANProtocolLogic.java
@@ -29,16 +29,18 @@ import org.apache.plc4x.java.api.types.PlcSubscriptionType;
 import org.apache.plc4x.java.api.value.PlcValue;
 import org.apache.plc4x.java.can.adapter.Plc4xCANProtocolBase;
 import org.apache.plc4x.java.can.generic.tag.GenericCANTag;
+import org.apache.plc4x.java.can.generic.tag.GenericCANTagHandler;
 import org.apache.plc4x.java.can.generic.transport.GenericFrame;
 import org.apache.plc4x.java.genericcan.readwrite.DataItem;
 import org.apache.plc4x.java.spi.ConversationContext;
+import org.apache.plc4x.java.spi.connection.PlcTagHandler;
 import org.apache.plc4x.java.spi.context.DriverContext;
 import org.apache.plc4x.java.spi.generation.*;
 import org.apache.plc4x.java.spi.messages.*;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem;
 import org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration;
 import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionTag;
-import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionHandle;
 import org.apache.plc4x.java.spi.transaction.RequestTransactionManager;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -68,8 +70,13 @@ public class GenericCANProtocolLogic extends Plc4xCANProtocolBase<GenericFrame>
     }
 
     @Override
-    public void setContext(ConversationContext<GenericFrame> context) {
-        super.setContext(context);
+    public void setConversationContext(ConversationContext<GenericFrame> conversationContext) {
+        super.setConversationContext(conversationContext);
+    }
+
+    @Override
+    public PlcTagHandler getTagHandler() {
+        return new GenericCANTagHandler();
     }
 
     @Override
@@ -89,7 +96,7 @@ public class GenericCANProtocolLogic extends Plc4xCANProtocolBase<GenericFrame>
             Consumer<PlcSubscriptionEvent> consumer = entry.getValue();
             for (PlcSubscriptionHandle handle : registration.getSubscriptionHandles()) {
                 GenericCANSubscriptionHandle subscription = (GenericCANSubscriptionHandle) handle;
-                Map<String, ResponseItem<PlcValue>> tags = new LinkedHashMap<>();
+                Map<String, PlcResponseItem<PlcValue>> tags = new LinkedHashMap<>();
                 ReadBuffer buffer = new ReadBufferByteBased(msg.getData(), ByteOrder.LITTLE_ENDIAN);
                 buffer.pullContext("readTags");
                 if (subscription.matches(msg.getNodeId())) {
@@ -99,12 +106,12 @@ public class GenericCANProtocolLogic extends Plc4xCANProtocolBase<GenericFrame>
                         try {
                             PlcValue value = read(readBuffer, tag.getValue(), data.length);
                             if (value == null) {
-                                tags.put(tag.getKey(), new ResponseItem<>(PlcResponseCode.INTERNAL_ERROR, null));
+                                tags.put(tag.getKey(), new DefaultPlcResponseItem<>(PlcResponseCode.INTERNAL_ERROR, null));
                             } else {
-                                tags.put(tag.getKey(), new ResponseItem<>(PlcResponseCode.OK, value));
+                                tags.put(tag.getKey(), new DefaultPlcResponseItem<>(PlcResponseCode.OK, value));
                             }
                         } catch (ParseException e) {
-                            tags.put(tag.getKey(), new ResponseItem<>(PlcResponseCode.INVALID_DATA, null));
+                            tags.put(tag.getKey(), new DefaultPlcResponseItem<>(PlcResponseCode.INVALID_DATA, null));
                         }
                     }
                     consumer.accept(new DefaultPlcSubscriptionEvent(Instant.now(), tags));
@@ -177,7 +184,7 @@ public class GenericCANProtocolLogic extends Plc4xCANProtocolBase<GenericFrame>
                 if (!discarded) {
                     byte[] data = message.getValue().getBytes();
                     logger.debug("Writing message with id {} and {} bytes of data", message.getKey(), data.length);
-                    context.sendToWire(new GenericFrame(message.getKey(), data));
+                    conversationContext.sendToWire(new GenericFrame(message.getKey(), data));
                 }
             }
 
@@ -192,23 +199,23 @@ public class GenericCANProtocolLogic extends Plc4xCANProtocolBase<GenericFrame>
     public CompletableFuture<PlcSubscriptionResponse> subscribe(PlcSubscriptionRequest request) {
         DefaultPlcSubscriptionRequest rq = (DefaultPlcSubscriptionRequest) request;
 
-        Map<String, ResponseItem<PlcSubscriptionHandle>> answers = new LinkedHashMap<>();
+        Map<String, PlcResponseItem<PlcSubscriptionHandle>> answers = new LinkedHashMap<>();
         DefaultPlcSubscriptionResponse response = new DefaultPlcSubscriptionResponse(rq, answers);
 
         Map<Integer, GenericCANSubscriptionHandle> handles = new LinkedHashMap<>();
         for (String key : rq.getTagNames()) {
             DefaultPlcSubscriptionTag subscription = (DefaultPlcSubscriptionTag) rq.getTag(key);
             if (subscription.getPlcSubscriptionType() != PlcSubscriptionType.EVENT) {
-                answers.put(key, new ResponseItem<>(PlcResponseCode.UNSUPPORTED, null));
+                answers.put(key, new DefaultPlcResponseItem<>(PlcResponseCode.UNSUPPORTED, null));
             } else if (subscription.getTag() instanceof GenericCANTag) {
                 GenericCANTag canTag = (GenericCANTag) subscription.getTag();
                 GenericCANSubscriptionHandle subscriptionHandle = handles.computeIfAbsent(canTag.getNodeId(),
                     node -> new GenericCANSubscriptionHandle(this, node)
                 );
-                answers.put(key, new ResponseItem<>(PlcResponseCode.OK, subscriptionHandle));
+                answers.put(key, new DefaultPlcResponseItem<>(PlcResponseCode.OK, subscriptionHandle));
                 subscriptionHandle.add(key, canTag);
             } else {
-                answers.put(key, new ResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null));
+                answers.put(key, new DefaultPlcResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null));
             }
         }
 
diff --git a/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/generic/tag/GenericCANTag.java b/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/generic/tag/GenericCANTag.java
index c21db4dfe1..ea8a2d34fe 100644
--- a/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/generic/tag/GenericCANTag.java
+++ b/plc4j/drivers/can/src/main/java/org/apache/plc4x/java/can/generic/tag/GenericCANTag.java
@@ -65,7 +65,7 @@ public class GenericCANTag implements PlcTag {
 
     @Override
     public List<ArrayInfo> getArrayInfo() {
-        if(arraySize != 1) {
+        if(arraySize > 1) {
             return Collections.singletonList(new DefaultArrayInfo(0, arraySize));
         }
         return Collections.emptyList();
diff --git a/plc4j/drivers/can/src/test/java/org/apache/plc4x/java/can/generic/GenericCANDriverTest.java b/plc4j/drivers/can/src/test/java/org/apache/plc4x/java/can/generic/GenericCANDriverTest.java
index 9ac60d6d3a..7abd581efe 100644
--- a/plc4j/drivers/can/src/test/java/org/apache/plc4x/java/can/generic/GenericCANDriverTest.java
+++ b/plc4j/drivers/can/src/test/java/org/apache/plc4x/java/can/generic/GenericCANDriverTest.java
@@ -19,23 +19,11 @@
 package org.apache.plc4x.java.can.generic;
 
 import io.netty.buffer.ByteBuf;
-import io.netty.buffer.ByteBufAllocator;
-import io.netty.buffer.ByteBufUtil;
-import io.netty.buffer.Unpooled;
-import io.netty.buffer.UnpooledDirectByteBuf;
 import io.netty.channel.Channel;
-import io.netty.channel.ChannelHandlerAdapter;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInboundHandlerAdapter;
-import io.netty.channel.ChannelOutboundHandlerAdapter;
-import io.netty.channel.ChannelPromise;
-import io.netty.channel.embedded.EmbeddedChannel;
 import io.netty.channel.embedded.Plc4xEmbeddedChannel;
 import java.lang.reflect.Array;
-import java.util.Arrays;
 import java.util.Map;
 import java.util.Map.Entry;
-import java.util.Optional;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.atomic.AtomicReference;
 
@@ -43,14 +31,12 @@ import org.apache.plc4x.java.DefaultPlcDriverManager;
 import org.apache.plc4x.java.api.PlcConnection;
 import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
 import org.apache.plc4x.java.api.messages.PlcSubscriptionEvent;
+import org.apache.plc4x.java.api.messages.PlcSubscriptionRequest;
 import org.apache.plc4x.java.api.messages.PlcSubscriptionRequest.Builder;
 import org.apache.plc4x.java.api.messages.PlcWriteRequest;
-import org.apache.plc4x.java.api.model.PlcTag;
 import org.apache.plc4x.java.spi.connection.ChannelExposingConnection;
-import org.apache.plc4x.java.spi.values.PlcBYTE;
 import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
-import org.mockito.internal.util.Primitives;
 
 import static java.util.Map.entry;
 import static org.junit.jupiter.api.Assertions.*;
@@ -134,7 +120,8 @@ public class GenericCANDriverTest {
             subscriptionRequestBuilder.addEventTagAddress(k, v.getKey());
         });
 
-        subscriptionRequestBuilder.build().execute().whenComplete((reply, error) -> {
+        PlcSubscriptionRequest subscriptionRequest = subscriptionRequestBuilder.build();
+        subscriptionRequest.execute().whenComplete((reply, error) -> {
             if (error != null) {
                 fail(error);
                 return;
@@ -150,7 +137,8 @@ public class GenericCANDriverTest {
         entries.forEach((k, v) -> {
             writeRequestBuilder.addTagAddress(k, v.getKey(), v.getValue());
         });
-        writeRequestBuilder.build().execute().whenComplete((reply, error) -> {
+        PlcWriteRequest writeRequest = writeRequestBuilder.build();
+        writeRequest.execute().whenComplete((reply, error) -> {
             if (error != null) {
                 fail(error);
             }
diff --git a/plc4j/drivers/can/src/test/resources/logback-test.xml b/plc4j/drivers/can/src/test/resources/logback-test.xml
index 2b9cea25dc..941f1546f8 100644
--- a/plc4j/drivers/can/src/test/resources/logback-test.xml
+++ b/plc4j/drivers/can/src/test/resources/logback-test.xml
@@ -29,7 +29,7 @@
     </encoder>
   </appender>
 
-  <root level="error">
+  <root level="warn">
     <appender-ref ref="STDOUT" />
   </root>
 
diff --git a/plc4j/drivers/canopen/src/main/java/org/apache/plc4x/java/canopen/CANOpenPlcDriver.java b/plc4j/drivers/canopen/src/main/java/org/apache/plc4x/java/canopen/CANOpenPlcDriver.java
index 39dce5bd6f..6d7d6f08de 100644
--- a/plc4j/drivers/canopen/src/main/java/org/apache/plc4x/java/canopen/CANOpenPlcDriver.java
+++ b/plc4j/drivers/canopen/src/main/java/org/apache/plc4x/java/canopen/CANOpenPlcDriver.java
@@ -18,6 +18,7 @@
  */
 package org.apache.plc4x.java.canopen;
 
+import org.apache.plc4x.java.canopen.tag.CANOpenTagHandler;
 import org.apache.plc4x.java.spi.configuration.PlcConnectionConfiguration;
 import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
 import org.apache.plc4x.java.api.model.PlcTag;
@@ -25,7 +26,6 @@ import org.apache.plc4x.java.api.value.PlcValue;
 import org.apache.plc4x.java.can.adapter.CANDriverAdapter;
 import org.apache.plc4x.java.canopen.configuration.CANOpenConfiguration;
 import org.apache.plc4x.java.canopen.context.CANOpenDriverContext;
-import org.apache.plc4x.java.canopen.tag.CANOpenTagHandler;
 import org.apache.plc4x.java.canopen.protocol.CANOpenProtocolLogic;
 import org.apache.plc4x.java.canopen.transport.CANOpenFrameDataHandler;
 import org.apache.plc4x.java.spi.configuration.ConfigurationFactory;
@@ -36,6 +36,7 @@ import org.apache.plc4x.java.spi.generation.Message;
 import org.apache.plc4x.java.spi.optimizer.BaseOptimizer;
 import org.apache.plc4x.java.spi.optimizer.SingleTagOptimizer;
 import org.apache.plc4x.java.spi.transport.Transport;
+import org.apache.plc4x.java.spi.values.DefaultPlcValueHandler;
 import org.apache.plc4x.java.spi.values.PlcValueHandler;
 import org.apache.plc4x.java.spi.values.PlcList;
 import org.apache.plc4x.java.transport.can.CANTransport;
@@ -82,13 +83,8 @@ public class CANOpenPlcDriver extends GeneratedDriverBase<Message> {
     }
 
     @Override
-    protected CANOpenTagHandler getTagHandler() {
-        return new CANOpenTagHandler();
-    }
-
-    @Override
-    protected org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() {
-        return new PlcValueHandler() {
+    protected PlcValueHandler getValueHandler() {
+        return new DefaultPlcValueHandler() {
             @Override
             public PlcValue newPlcValue(PlcTag tag, Object[] values) {
                 if (values[0] instanceof PlcList) {
@@ -131,7 +127,8 @@ public class CANOpenPlcDriver extends GeneratedDriverBase<Message> {
                 ConfigurationFactory.configure(cfg, protocolLogic);
                 return new CANDriverAdapter<>(protocolLogic,
                     canTransport.getMessageType(), canTransport.adapter(),
-                    new CANOpenFrameDataHandler(canTransport::getTransportFrameBuilder)
+                    new CANOpenFrameDataHandler(canTransport::getTransportFrameBuilder),
+                    new CANOpenTagHandler()
                 );
             })
             .withDriverContext(cfg -> new CANOpenDriverContext())
diff --git a/plc4j/drivers/canopen/src/main/java/org/apache/plc4x/java/canopen/protocol/CANOpenProtocolLogic.java b/plc4j/drivers/canopen/src/main/java/org/apache/plc4x/java/canopen/protocol/CANOpenProtocolLogic.java
index 5caa22a3b5..9124cab003 100644
--- a/plc4j/drivers/canopen/src/main/java/org/apache/plc4x/java/canopen/protocol/CANOpenProtocolLogic.java
+++ b/plc4j/drivers/canopen/src/main/java/org/apache/plc4x/java/canopen/protocol/CANOpenProtocolLogic.java
@@ -56,6 +56,7 @@ import org.apache.plc4x.java.canopen.readwrite.NMTState;
 import org.apache.plc4x.java.canopen.readwrite.NMTStateRequest;
 import org.apache.plc4x.java.spi.ConversationContext;
 import org.apache.plc4x.java.spi.configuration.HasConfiguration;
+import org.apache.plc4x.java.spi.connection.PlcTagHandler;
 import org.apache.plc4x.java.spi.context.DriverContext;
 import org.apache.plc4x.java.spi.generation.*;
 import org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse;
@@ -66,7 +67,8 @@ import org.apache.plc4x.java.spi.messages.DefaultPlcUnsubscriptionResponse;
 import org.apache.plc4x.java.spi.messages.DefaultPlcWriteRequest;
 import org.apache.plc4x.java.spi.messages.DefaultPlcWriteResponse;
 import org.apache.plc4x.java.spi.messages.PlcSubscriber;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem;
 import org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration;
 import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionTag;
 import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionHandle;
@@ -124,6 +126,11 @@ public class CANOpenProtocolLogic extends Plc4xCANProtocolBase<CANOpenFrame>
         this.tm = new RequestTransactionManager(1);
     }
 
+    @Override
+    public PlcTagHandler getTagHandler() {
+        return new CANOpenTagHandler();
+    }
+
     @Override
     public void close(ConversationContext<CANOpenFrame> context) {
         tm.shutdown();
@@ -154,9 +161,9 @@ public class CANOpenProtocolLogic extends Plc4xCANProtocolBase<CANOpenFrame>
     }
 
     @Override
-    public void setContext(ConversationContext<CANOpenFrame> context) {
-        super.setContext(context);
-        this.conversation = new CANTransportConversation(configuration.getNodeId(), context, configuration.getRequestTimeout());
+    public void setConversationContext(ConversationContext<CANOpenFrame> conversationContext) {
+        super.setConversationContext(conversationContext);
+        this.conversation = new CANTransportConversation(configuration.getNodeId(), conversationContext, configuration.getRequestTimeout());
     }
 
     private CANOpenFrame createFrame(CANOpenHeartbeatPayload state) throws ParseException {
@@ -224,7 +231,7 @@ public class CANOpenProtocolLogic extends Plc4xCANProtocolBase<CANOpenFrame>
             WriteBufferByteBased writeBuffer = new WriteBufferByteBased(DataItem.getLengthInBytes(writeValue, tag.getCanOpenDataType(), writeValue.getLength()), ByteOrder.LITTLE_ENDIAN);
             DataItem.staticSerialize(writeBuffer, writeValue, tag.getCanOpenDataType(), writeValue.getLength(), ByteOrder.LITTLE_ENDIAN);
             final CANOpenPDOPayload payload = new CANOpenPDOPayload(new CANOpenPDO(writeBuffer.getBytes()));
-            context.sendToWire(new CANOpenFrame((short) tag.getNodeId(), tag.getService(), payload));
+            conversationContext.sendToWire(new CANOpenFrame((short) tag.getNodeId(), tag.getService(), payload));
             response.complete(new DefaultPlcWriteResponse(writeRequest, Collections.singletonMap(tagName, PlcResponseCode.OK)));
         } catch (Exception e) {
             response.completeExceptionally(e);
@@ -257,27 +264,27 @@ public class CANOpenProtocolLogic extends Plc4xCANProtocolBase<CANOpenFrame>
     public CompletableFuture<PlcSubscriptionResponse> subscribe(PlcSubscriptionRequest request) {
         DefaultPlcSubscriptionRequest rq = (DefaultPlcSubscriptionRequest) request;
 
-        Map<String, ResponseItem<PlcSubscriptionHandle>> answers = new LinkedHashMap<>();
+        Map<String, PlcResponseItem<PlcSubscriptionHandle>> answers = new LinkedHashMap<>();
         DefaultPlcSubscriptionResponse response = new DefaultPlcSubscriptionResponse(rq, answers);
 
         for (String key : rq.getTagNames()) {
             DefaultPlcSubscriptionTag subscription = (DefaultPlcSubscriptionTag) rq.getTag(key);
             if (subscription.getPlcSubscriptionType() != PlcSubscriptionType.EVENT) {
-                answers.put(key, new ResponseItem<>(PlcResponseCode.UNSUPPORTED, null));
+                answers.put(key, new DefaultPlcResponseItem<>(PlcResponseCode.UNSUPPORTED, null));
             } else if ((subscription.getTag() instanceof CANOpenPDOTag)) {
-                answers.put(key, new ResponseItem<>(PlcResponseCode.OK,
+                answers.put(key, new DefaultPlcResponseItem<>(PlcResponseCode.OK,
                     new CANOpenSubscriptionHandle(this, key, (CANOpenPDOTag) subscription.getTag())
                 ));
             } else if ((subscription.getTag() instanceof CANOpenNMTTag)) {
-                answers.put(key, new ResponseItem<>(PlcResponseCode.OK,
+                answers.put(key, new DefaultPlcResponseItem<>(PlcResponseCode.OK,
                     new CANOpenSubscriptionHandle(this, key, (CANOpenNMTTag) subscription.getTag())
                 ));
             } else if ((subscription.getTag() instanceof CANOpenHeartbeatTag)) {
-                answers.put(key, new ResponseItem<>(PlcResponseCode.OK,
+                answers.put(key, new DefaultPlcResponseItem<>(PlcResponseCode.OK,
                     new CANOpenSubscriptionHandle(this, key, (CANOpenHeartbeatTag) subscription.getTag())
                 ));
             } else {
-                answers.put(key, new ResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null));
+                answers.put(key, new DefaultPlcResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null));
             }
         }
 
@@ -302,11 +309,11 @@ public class CANOpenProtocolLogic extends Plc4xCANProtocolBase<CANOpenFrame>
         CompletableFuture<PlcValue> callback = new CompletableFuture<>();
         callback.whenComplete((value, error) -> {
             if (error != null) {
-                Map<String, ResponseItem<PlcValue>> tags = new HashMap<>();
+                Map<String, PlcResponseItem<PlcValue>> tags = new HashMap<>();
                 if (error instanceof CANOpenAbortException) {
-                    tags.put(tagName, new ResponseItem<>(PlcResponseCode.REMOTE_ERROR, new PlcLINT(((CANOpenAbortException) error).getAbortCode())));
+                    tags.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.REMOTE_ERROR, new PlcLINT(((CANOpenAbortException) error).getAbortCode())));
                 } else {
-                    tags.put(tagName, new ResponseItem<>(PlcResponseCode.REMOTE_ERROR, null));
+                    tags.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.REMOTE_ERROR, null));
                 }
                 response.complete(new DefaultPlcReadResponse(readRequest, tags));
                 transaction.endRequest();
@@ -314,8 +321,8 @@ public class CANOpenProtocolLogic extends Plc4xCANProtocolBase<CANOpenFrame>
                 return;
             }
 
-            Map<String, ResponseItem<PlcValue>> tags = new HashMap<>();
-            tags.put(tagName, new ResponseItem<>(PlcResponseCode.OK, value));
+            Map<String, PlcResponseItem<PlcValue>> tags = new HashMap<>();
+            tags.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, value));
             response.complete(new DefaultPlcReadResponse(readRequest, tags));
             transaction.endRequest();
         });
@@ -363,7 +370,7 @@ public class CANOpenProtocolLogic extends Plc4xCANProtocolBase<CANOpenFrame>
                                 Instant.now(),
                                 Collections.singletonMap(
                                     handle.getName(),
-                                    new ResponseItem<>(PlcResponseCode.OK, value)
+                                    new DefaultPlcResponseItem<>(PlcResponseCode.OK, value)
                                 )
                             );
                             consumer.accept(event);
@@ -373,7 +380,7 @@ public class CANOpenProtocolLogic extends Plc4xCANProtocolBase<CANOpenFrame>
                                 Instant.now(),
                                 Collections.singletonMap(
                                     handle.getName(),
-                                    new ResponseItem<>(PlcResponseCode.INVALID_DATA, new PlcNull())
+                                    new DefaultPlcResponseItem<>(PlcResponseCode.INVALID_DATA, new PlcNull())
                                 )
                             );
                             consumer.accept(event);
@@ -393,7 +400,7 @@ public class CANOpenProtocolLogic extends Plc4xCANProtocolBase<CANOpenFrame>
                             Instant.now(),
                             Collections.singletonMap(
                                 handle.getName(),
-                                new ResponseItem<>(PlcResponseCode.OK, struct)
+                                new DefaultPlcResponseItem<>(PlcResponseCode.OK, struct)
                             )
                         );
                         consumer.accept(event);
@@ -412,7 +419,7 @@ public class CANOpenProtocolLogic extends Plc4xCANProtocolBase<CANOpenFrame>
                             Instant.now(),
                             Collections.singletonMap(
                                 handle.getName(),
-                                new ResponseItem<>(PlcResponseCode.OK, struct)
+                                new DefaultPlcResponseItem<>(PlcResponseCode.OK, struct)
                             )
                         );
                         consumer.accept(event);
diff --git a/plc4j/drivers/canopen/src/test/resources/logback-test.xml b/plc4j/drivers/canopen/src/test/resources/logback-test.xml
index 2b9cea25dc..941f1546f8 100644
--- a/plc4j/drivers/canopen/src/test/resources/logback-test.xml
+++ b/plc4j/drivers/canopen/src/test/resources/logback-test.xml
@@ -29,7 +29,7 @@
     </encoder>
   </appender>
 
-  <root level="error">
+  <root level="warn">
     <appender-ref ref="STDOUT" />
   </root>
 
diff --git a/plc4j/drivers/ctrlx/src/main/java/org/apache/plc4x/java/ctrlx/readwrite/connection/CtrlXConnection.java b/plc4j/drivers/ctrlx/src/main/java/org/apache/plc4x/java/ctrlx/readwrite/connection/CtrlXConnection.java
index df09c0bb75..dfff73c39b 100644
--- a/plc4j/drivers/ctrlx/src/main/java/org/apache/plc4x/java/ctrlx/readwrite/connection/CtrlXConnection.java
+++ b/plc4j/drivers/ctrlx/src/main/java/org/apache/plc4x/java/ctrlx/readwrite/connection/CtrlXConnection.java
@@ -19,18 +19,19 @@
 
 package org.apache.plc4x.java.ctrlx.readwrite.connection;
 
-import com.hrakaroo.glob.GlobPattern;
 import com.hrakaroo.glob.MatchingEngine;
 import org.apache.plc4x.java.api.PlcConnection;
 import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
 import org.apache.plc4x.java.api.exceptions.PlcInvalidTagException;
 import org.apache.plc4x.java.api.exceptions.PlcProtocolException;
+import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
 import org.apache.plc4x.java.api.messages.*;
 import org.apache.plc4x.java.api.metadata.PlcConnectionMetadata;
 import org.apache.plc4x.java.api.model.PlcQuery;
 import org.apache.plc4x.java.api.model.PlcTag;
 import org.apache.plc4x.java.api.types.PlcResponseCode;
 import org.apache.plc4x.java.api.types.PlcValueType;
+import org.apache.plc4x.java.api.value.PlcValue;
 import org.apache.plc4x.java.ctrlx.readwrite.rest.datalayer.ApiClient;
 import org.apache.plc4x.java.ctrlx.readwrite.rest.datalayer.ApiException;
 import org.apache.plc4x.java.ctrlx.readwrite.rest.datalayer.api.DataLayerInformationAndSettingsApi;
@@ -42,6 +43,8 @@ import org.apache.plc4x.java.ctrlx.readwrite.tag.CtrlXTag;
 import org.apache.plc4x.java.ctrlx.readwrite.tag.CtrlXTagHandler;
 import org.apache.plc4x.java.ctrlx.readwrite.utils.ApiClientFactory;
 import org.apache.plc4x.java.spi.messages.*;
+import org.apache.plc4x.java.spi.values.DefaultPlcValueHandler;
+import org.apache.plc4x.java.spi.values.PlcValueHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -60,6 +63,7 @@ public class CtrlXConnection implements PlcConnection, PlcPinger, PlcBrowser {
     private final String password;
 
     private final ExecutorService executorService;
+    private PlcValueHandler valueHandler;
 
     private ApiClient apiClient;
     private NodesApi nodesApi;
@@ -72,6 +76,18 @@ public class CtrlXConnection implements PlcConnection, PlcPinger, PlcBrowser {
         this.username = username;
         this.password = password;
         this.executorService = Executors.newFixedThreadPool(10);
+        this.valueHandler = new DefaultPlcValueHandler();
+    }
+
+    @Override
+    public Optional<PlcValue> parseTagValue(PlcTag tag, Object... values) {
+        PlcValue plcValue;
+        try {
+            plcValue = valueHandler.newPlcValue(tag, values);
+        } catch (Exception e) {
+            throw new PlcRuntimeException("Error parsing tag value " + tag, e);
+        }
+        return Optional.of(plcValue);
     }
 
     @Override
@@ -258,7 +274,7 @@ public class CtrlXConnection implements PlcConnection, PlcPinger, PlcBrowser {
                                 e.printStackTrace();
                             }*/
                             matchingQueryNames.forEach(queryName -> responseItems.get(queryName).add(
-                                new DefaultListPlcBrowseItem(
+                                new DefaultPlcBrowseItemList(
                                     new CtrlXTag(curNode, PlcValueType.BOOL, Collections.emptyList()),
                                     curNode, true, true, true, false,
                                     Collections.emptyMap(), Collections.emptyMap(), Collections.emptyList())));
diff --git a/plc4j/drivers/eip/src/main/java/org/apache/plc4x/java/eip/base/EIPDriver.java b/plc4j/drivers/eip/src/main/java/org/apache/plc4x/java/eip/base/EIPDriver.java
index a6d731526b..02f4be1d48 100644
--- a/plc4j/drivers/eip/src/main/java/org/apache/plc4x/java/eip/base/EIPDriver.java
+++ b/plc4j/drivers/eip/src/main/java/org/apache/plc4x/java/eip/base/EIPDriver.java
@@ -29,7 +29,6 @@ import org.apache.plc4x.java.eip.base.configuration.EIPConfiguration;
 import org.apache.plc4x.java.eip.base.configuration.EipTcpTransportConfiguration;
 import org.apache.plc4x.java.eip.base.tag.EipTag;
 import org.apache.plc4x.java.eip.base.protocol.EipProtocolLogic;
-import org.apache.plc4x.java.eip.base.tag.EipTagHandler;
 import org.apache.plc4x.java.eip.readwrite.EipPacket;
 import org.apache.plc4x.java.spi.configuration.ConfigurationFactory;
 import org.apache.plc4x.java.spi.configuration.HasConfiguration;
@@ -38,8 +37,6 @@ import org.apache.plc4x.java.spi.generation.ByteOrder;
 import org.apache.plc4x.java.spi.messages.DefaultPlcDiscoveryRequest;
 import org.apache.plc4x.java.spi.transport.Transport;
 
-import org.apache.plc4x.java.api.value.PlcValueHandler;
-
 import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
@@ -92,16 +89,6 @@ public class EIPDriver extends GeneratedDriverBase<EipPacket> {
         return Collections.singletonList("tcp");
     }
 
-    @Override
-    protected PlcTagHandler getTagHandler() {
-        return new EipTagHandler();
-    }
-
-    @Override
-    protected PlcValueHandler getValueHandler() {
-        return new org.apache.plc4x.java.spi.values.PlcValueHandler();
-    }
-
     @Override
     public PlcDiscoveryRequest.Builder discoveryRequestBuilder() {
         return new DefaultPlcDiscoveryRequest.Builder(new EipPlcDiscoverer());
@@ -222,7 +209,6 @@ public class EIPDriver extends GeneratedDriverBase<EipPacket> {
 
         return new DefaultNettyPlcConnection(
             canPing(), canRead(), canWrite(), canSubscribe(), canBrowse(),
-            getTagHandler(),
             getValueHandler(),
             configuration,
             channelFactory,
diff --git a/plc4j/drivers/eip/src/main/java/org/apache/plc4x/java/eip/base/protocol/EipProtocolLogic.java b/plc4j/drivers/eip/src/main/java/org/apache/plc4x/java/eip/base/protocol/EipProtocolLogic.java
index 1e75cf460e..14b26360e7 100644
--- a/plc4j/drivers/eip/src/main/java/org/apache/plc4x/java/eip/base/protocol/EipProtocolLogic.java
+++ b/plc4j/drivers/eip/src/main/java/org/apache/plc4x/java/eip/base/protocol/EipProtocolLogic.java
@@ -30,11 +30,13 @@ import org.apache.plc4x.java.api.types.PlcResponseCode;
 import org.apache.plc4x.java.api.value.PlcValue;
 import org.apache.plc4x.java.eip.base.configuration.EIPConfiguration;
 import org.apache.plc4x.java.eip.base.tag.EipTag;
+import org.apache.plc4x.java.eip.base.tag.EipTagHandler;
 import org.apache.plc4x.java.eip.logix.configuration.LogixConfiguration;
 import org.apache.plc4x.java.eip.readwrite.*;
 import org.apache.plc4x.java.spi.ConversationContext;
 import org.apache.plc4x.java.spi.Plc4xProtocolBase;
 import org.apache.plc4x.java.spi.configuration.HasConfiguration;
+import org.apache.plc4x.java.spi.connection.PlcTagHandler;
 import org.apache.plc4x.java.spi.generation.ParseException;
 import org.apache.plc4x.java.spi.generation.ReadBufferByteBased;
 import org.apache.plc4x.java.spi.generation.SerializationException;
@@ -43,7 +45,8 @@ import org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest;
 import org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse;
 import org.apache.plc4x.java.spi.messages.DefaultPlcWriteRequest;
 import org.apache.plc4x.java.spi.messages.DefaultPlcWriteResponse;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem;
 import org.apache.plc4x.java.spi.transaction.RequestTransactionManager;
 import org.apache.plc4x.java.spi.values.*;
 import org.slf4j.Logger;
@@ -146,6 +149,11 @@ public class EipProtocolLogic extends Plc4xProtocolBase<EipPacket> implements Ha
         this.tm = new RequestTransactionManager(1);
     }
 
+    @Override
+    public PlcTagHandler getTagHandler() {
+        return new EipTagHandler();
+    }
+
     @Override
     public void close(ConversationContext<EipPacket> context) {
         tm.shutdown();
@@ -445,7 +453,7 @@ public class EipProtocolLogic extends Plc4xProtocolBase<EipPacket> implements Ha
 
     private CompletableFuture<PlcReadResponse> readWithoutMessageRouter(PlcReadRequest readRequest) {
         CompletableFuture<PlcReadResponse> future = new CompletableFuture<>();
-        Map<String, ResponseItem<PlcValue>> values = new HashMap<>();
+        Map<String, PlcResponseItem<PlcValue>> values = new HashMap<>();
         List<CompletableFuture<Void>> internalFutures = new ArrayList<>();
         PathSegment classSegment = new LogicalSegment(new ClassID((byte) 0, (short) 6));
         PathSegment instanceSegment = new LogicalSegment(new InstanceID((byte) 0, (short) 1));
@@ -482,7 +490,7 @@ public class EipProtocolLogic extends Plc4xProtocolBase<EipPacket> implements Ha
                     typeIds);
 
                 RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
-                transaction.submit(() -> context.sendRequest(rrdata)
+                transaction.submit(() -> conversationContext.sendRequest(rrdata)
                     .expectResponse(EipPacket.class, REQUEST_TIMEOUT)
                     .onTimeout(internalFuture::completeExceptionally)
                     .onError((p, e) -> internalFuture.completeExceptionally(e))
@@ -494,11 +502,11 @@ public class EipProtocolLogic extends Plc4xProtocolBase<EipPacket> implements Ha
                         UnConnectedDataItem dataItem = (UnConnectedDataItem) responseTypeIds.get(1);
                         // If the response indicates an error, handle this.
                         if((dataItem.getService() instanceof CipConnectedResponse) && (((CipConnectedResponse) dataItem.getService()).getStatus() == 0x03)) {
-                            values.put(tagName, new ResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null));
+                            values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null));
                         }
                         // Otherwise process the response.
                         else {
-                            Map<String, ResponseItem<PlcValue>> readResponse = decodeSingleReadResponse(dataItem.getService(), tagName, eipTag);
+                            Map<String, PlcResponseItem<PlcValue>> readResponse = decodeSingleReadResponse(dataItem.getService(), tagName, eipTag);
                             values.putAll(readResponse);
                         }
                         internalFuture.complete(null);
@@ -585,7 +593,7 @@ public class EipProtocolLogic extends Plc4xProtocolBase<EipPacket> implements Ha
             typeIds
         );
 
-        transaction.submit(() -> context.sendRequest(pkt)
+        transaction.submit(() -> conversationContext.sendRequest(pkt)
             .expectResponse(EipPacket.class, REQUEST_TIMEOUT)
             .onTimeout(future::completeExceptionally)
             .onError((p, e) -> future.completeExceptionally(e))
@@ -662,7 +670,7 @@ public class EipProtocolLogic extends Plc4xProtocolBase<EipPacket> implements Ha
 
         this.sequenceCount += 1;
 
-        transaction.submit(() -> context.sendRequest(pkt)
+        transaction.submit(() -> conversationContext.sendRequest(pkt)
             .expectResponse(EipPacket.class, REQUEST_TIMEOUT)
             .onTimeout(future::completeExceptionally)
             .onError((p, e) -> future.completeExceptionally(e))
@@ -732,7 +740,7 @@ public class EipProtocolLogic extends Plc4xProtocolBase<EipPacket> implements Ha
     }
 
     private PlcReadResponse decodeReadResponse(CipService p, PlcReadRequest readRequest) {
-        Map<String, ResponseItem<PlcValue>> values = new HashMap<>();
+        Map<String, PlcResponseItem<PlcValue>> values = new HashMap<>();
         // only 1 field
         if (p instanceof CipReadResponse) {
             CipReadResponse resp = (CipReadResponse) p;
@@ -745,7 +753,7 @@ public class EipProtocolLogic extends Plc4xProtocolBase<EipPacket> implements Ha
             if (code == PlcResponseCode.OK) {
                 plcValue = parsePlcValue(tag, data, type);
             }
-            ResponseItem<PlcValue> result = new ResponseItem<>(code, plcValue);
+            PlcResponseItem<PlcValue> result = new DefaultPlcResponseItem<>(code, plcValue);
             values.put(fieldName, result);
         }
         //Multiple response
@@ -790,7 +798,7 @@ public class EipProtocolLogic extends Plc4xProtocolBase<EipPacket> implements Ha
                     if (code == PlcResponseCode.OK) {
                         plcValue = parsePlcValue(tag, data, type);
                     }
-                    ResponseItem<PlcValue> result = new ResponseItem<>(code, plcValue);
+                    PlcResponseItem<PlcValue> result = new DefaultPlcResponseItem<>(code, plcValue);
                     values.put(fieldName, result);
                 }
             }
@@ -798,8 +806,8 @@ public class EipProtocolLogic extends Plc4xProtocolBase<EipPacket> implements Ha
         return new DefaultPlcReadResponse(readRequest, values);
     }
 
-    private Map<String, ResponseItem<PlcValue>> decodeSingleReadResponse(CipService p, String tagName, PlcTag tag) {
-        Map<String, ResponseItem<PlcValue>> values = new HashMap<>();
+    private Map<String, PlcResponseItem<PlcValue>> decodeSingleReadResponse(CipService p, String tagName, PlcTag tag) {
+        Map<String, PlcResponseItem<PlcValue>> values = new HashMap<>();
         CipReadResponse resp = (CipReadResponse) p;
         PlcResponseCode code = decodeResponseCode(resp.getStatus());
         PlcValue plcValue = null;
@@ -808,7 +816,7 @@ public class EipProtocolLogic extends Plc4xProtocolBase<EipPacket> implements Ha
         if (code == PlcResponseCode.OK) {
             plcValue = parsePlcValue((EipTag) tag, data, type);
         }
-        ResponseItem<PlcValue> result = new ResponseItem<>(code, plcValue);
+        PlcResponseItem<PlcValue> result = new DefaultPlcResponseItem<>(code, plcValue);
         values.put(tagName, result);
         return values;
     }
@@ -967,7 +975,7 @@ public class EipProtocolLogic extends Plc4xProtocolBase<EipPacket> implements Ha
                     typeIds);
 
                 RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
-                transaction.submit(() -> context.sendRequest(rrdata)
+                transaction.submit(() -> conversationContext.sendRequest(rrdata)
                     .expectResponse(EipPacket.class, REQUEST_TIMEOUT)
                     .onTimeout(internalFuture::completeExceptionally)
                     .onError((p, e) -> internalFuture.completeExceptionally(e))
@@ -1049,7 +1057,7 @@ public class EipProtocolLogic extends Plc4xProtocolBase<EipPacket> implements Ha
                 0,
                 typeIds);
 
-            transaction.submit(() -> context.sendRequest(rrdata)
+            transaction.submit(() -> conversationContext.sendRequest(rrdata)
                 .expectResponse(EipPacket.class, REQUEST_TIMEOUT)
                 .onTimeout(future::completeExceptionally)
                 .onError((p, e) -> future.completeExceptionally(e))
@@ -1104,7 +1112,7 @@ public class EipProtocolLogic extends Plc4xProtocolBase<EipPacket> implements Ha
                 0,
                 typeIds);
 
-            transaction.submit(() -> context.sendRequest(pkt)
+            transaction.submit(() -> conversationContext.sendRequest(pkt)
                 .expectResponse(EipPacket.class, REQUEST_TIMEOUT)
                 .onTimeout(future::completeExceptionally)
                 .onError((p, e) -> future.completeExceptionally(e))
@@ -1168,7 +1176,7 @@ public class EipProtocolLogic extends Plc4xProtocolBase<EipPacket> implements Ha
                 0,
                 typeIds);
 
-            transaction.submit(() -> context.sendRequest(rrdata)
+            transaction.submit(() -> conversationContext.sendRequest(rrdata)
                 .expectResponse(EipPacket.class, REQUEST_TIMEOUT)
                 .onTimeout(future::completeExceptionally)
                 .onError((p, e) -> future.completeExceptionally(e))
@@ -1214,7 +1222,7 @@ public class EipProtocolLogic extends Plc4xProtocolBase<EipPacket> implements Ha
                 0,
                 typeIds);
 
-            transaction.submit(() -> context.sendRequest(pkt)
+            transaction.submit(() -> conversationContext.sendRequest(pkt)
                 .expectResponse(EipPacket.class, REQUEST_TIMEOUT)
                 .onTimeout(future::completeExceptionally)
                 .onError((p, e) -> future.completeExceptionally(e))
diff --git a/plc4j/drivers/eip/src/main/java/org/apache/plc4x/java/eip/logix/LogixDriver.java b/plc4j/drivers/eip/src/main/java/org/apache/plc4x/java/eip/logix/LogixDriver.java
index b8bb251d2a..3a1d971cc1 100644
--- a/plc4j/drivers/eip/src/main/java/org/apache/plc4x/java/eip/logix/LogixDriver.java
+++ b/plc4j/drivers/eip/src/main/java/org/apache/plc4x/java/eip/logix/LogixDriver.java
@@ -21,13 +21,11 @@ package org.apache.plc4x.java.eip.logix;
 import io.netty.buffer.ByteBuf;
 import org.apache.plc4x.java.spi.configuration.PlcConnectionConfiguration;
 import org.apache.plc4x.java.spi.configuration.PlcTransportConfiguration;
-import org.apache.plc4x.java.api.value.PlcValueHandler;
 import org.apache.plc4x.java.eip.base.tag.EipTag;
 import org.apache.plc4x.java.eip.base.protocol.EipProtocolLogic;
 import org.apache.plc4x.java.eip.logix.configuration.LogixConfiguration;
 import org.apache.plc4x.java.eip.logix.configuration.LogixTcpTransportConfiguration;
 import org.apache.plc4x.java.eip.readwrite.EipPacket;
-import org.apache.plc4x.java.eip.base.tag.EipTagHandler;
 import org.apache.plc4x.java.spi.connection.*;
 
 import java.util.Collections;
@@ -72,16 +70,6 @@ public class LogixDriver extends GeneratedDriverBase<EipPacket> {
         return Collections.singletonList("tcp");
     }
 
-    @Override
-    protected PlcTagHandler getTagHandler() {
-        return new EipTagHandler();
-    }
-
-    @Override
-    protected PlcValueHandler getValueHandler() {
-        return new org.apache.plc4x.java.spi.values.PlcValueHandler();
-    }
-
     @Override
     protected boolean awaitDisconnectComplete() {
         return true;
diff --git a/plc4j/drivers/eip/src/test/java/org/apache/plc4x/java/eip/base/EIPDriverIT.java b/plc4j/drivers/eip/src/test/java/org/apache/plc4x/java/eip/base/EIPDriverIT.java
index dd18cc6859..0502fbba9b 100644
--- a/plc4j/drivers/eip/src/test/java/org/apache/plc4x/java/eip/base/EIPDriverIT.java
+++ b/plc4j/drivers/eip/src/test/java/org/apache/plc4x/java/eip/base/EIPDriverIT.java
@@ -23,7 +23,7 @@ import org.apache.plc4x.test.driver.DriverTestsuiteRunner;
 public class EIPDriverIT extends DriverTestsuiteRunner {
 
     public EIPDriverIT() {
-        super("/protocols/eip/DriverTestsuite.xml");
+        super("/protocols/eip/DriverTestsuite.xml", false);
     }
 
 }
diff --git a/plc4j/drivers/eip/src/test/resources/logback-test.xml b/plc4j/drivers/eip/src/test/resources/logback-test.xml
index 2b9cea25dc..941f1546f8 100644
--- a/plc4j/drivers/eip/src/test/resources/logback-test.xml
+++ b/plc4j/drivers/eip/src/test/resources/logback-test.xml
@@ -29,7 +29,7 @@
     </encoder>
   </appender>
 
-  <root level="error">
+  <root level="warn">
     <appender-ref ref="STDOUT" />
   </root>
 
diff --git a/plc4j/drivers/firmata/src/main/java/org/apache/plc4x/java/firmata/readwrite/FirmataDriver.java b/plc4j/drivers/firmata/src/main/java/org/apache/plc4x/java/firmata/readwrite/FirmataDriver.java
index de49415040..8c38c2d818 100644
--- a/plc4j/drivers/firmata/src/main/java/org/apache/plc4x/java/firmata/readwrite/FirmataDriver.java
+++ b/plc4j/drivers/firmata/src/main/java/org/apache/plc4x/java/firmata/readwrite/FirmataDriver.java
@@ -24,11 +24,8 @@ import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
 import org.apache.plc4x.java.firmata.readwrite.configuration.FirmataConfiguration;
 import org.apache.plc4x.java.firmata.readwrite.context.FirmataDriverContext;
 import org.apache.plc4x.java.firmata.readwrite.tag.FirmataTag;
-import org.apache.plc4x.java.firmata.readwrite.tag.FirmataTagHandler;
 import org.apache.plc4x.java.firmata.readwrite.protocol.FirmataProtocolLogic;
-import org.apache.plc4x.java.spi.values.PlcValueHandler;
 import org.apache.plc4x.java.spi.connection.GeneratedDriverBase;
-import org.apache.plc4x.java.spi.connection.PlcTagHandler;
 import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer;
 import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer;
 
@@ -75,16 +72,6 @@ public class FirmataDriver extends GeneratedDriverBase<FirmataMessage> {
         return true;
     }
 
-    @Override
-    protected PlcTagHandler getTagHandler() {
-        return new FirmataTagHandler();
-    }
-
-    @Override
-    protected org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() {
-        return new PlcValueHandler();
-    }
-
     /**
      * This protocol doesn't have a disconnect procedure, so there is no need to wait for a login to finish.
      * @return false
diff --git a/plc4j/drivers/firmata/src/main/java/org/apache/plc4x/java/firmata/readwrite/protocol/FirmataProtocolLogic.java b/plc4j/drivers/firmata/src/main/java/org/apache/plc4x/java/firmata/readwrite/protocol/FirmataProtocolLogic.java
index 946414fd14..53179a5fef 100644
--- a/plc4j/drivers/firmata/src/main/java/org/apache/plc4x/java/firmata/readwrite/protocol/FirmataProtocolLogic.java
+++ b/plc4j/drivers/firmata/src/main/java/org/apache/plc4x/java/firmata/readwrite/protocol/FirmataProtocolLogic.java
@@ -31,13 +31,16 @@ import org.apache.plc4x.java.firmata.readwrite.model.FirmataSubscriptionHandle;
 import org.apache.plc4x.java.firmata.readwrite.tag.FirmataTag;
 import org.apache.plc4x.java.firmata.readwrite.tag.FirmataTagAnalog;
 import org.apache.plc4x.java.firmata.readwrite.tag.FirmataTagDigital;
+import org.apache.plc4x.java.firmata.readwrite.tag.FirmataTagHandler;
 import org.apache.plc4x.java.spi.ConversationContext;
 import org.apache.plc4x.java.spi.Plc4xProtocolBase;
+import org.apache.plc4x.java.spi.connection.PlcTagHandler;
 import org.apache.plc4x.java.spi.messages.DefaultPlcSubscriptionEvent;
 import org.apache.plc4x.java.spi.messages.DefaultPlcSubscriptionResponse;
 import org.apache.plc4x.java.spi.messages.DefaultPlcWriteResponse;
 import org.apache.plc4x.java.spi.messages.PlcSubscriber;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem;
 import org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration;
 import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionTag;
 import org.apache.plc4x.java.spi.values.PlcBOOL;
@@ -69,6 +72,11 @@ public class FirmataProtocolLogic extends Plc4xProtocolBase<FirmataMessage> impl
 
     private final Map<DefaultPlcConsumerRegistration, Consumer<PlcSubscriptionEvent>> consumers = new ConcurrentHashMap<>();
 
+    @Override
+    public PlcTagHandler getTagHandler() {
+        return new FirmataTagHandler();
+    }
+
     @Override
     public void onConnect(ConversationContext<FirmataMessage> context) {
         LOGGER.debug("Sending Firmata Reset Command");
@@ -106,7 +114,7 @@ public class FirmataProtocolLogic extends Plc4xProtocolBase<FirmataMessage> impl
             final List<FirmataMessage> firmataMessages =
                 ((FirmataDriverContext) getDriverContext()).processWriteRequest(writeRequest);
             for (FirmataMessage firmataMessage : firmataMessages) {
-                context.sendToWire(firmataMessage);
+                conversationContext.sendToWire(firmataMessage);
             }
             // There's unfortunately no ack response :-(
             Map<String, PlcResponseCode> result = new HashMap<>();
@@ -127,14 +135,14 @@ public class FirmataProtocolLogic extends Plc4xProtocolBase<FirmataMessage> impl
             final List<FirmataMessage> firmataMessages =
                 ((FirmataDriverContext) getDriverContext()).processSubscriptionRequest(subscriptionRequest);
             for (FirmataMessage firmataMessage : firmataMessages) {
-                context.sendToWire(firmataMessage);
+                conversationContext.sendToWire(firmataMessage);
             }
-            Map<String, ResponseItem<PlcSubscriptionHandle>> result = new HashMap<>();
+            Map<String, PlcResponseItem<PlcSubscriptionHandle>> result = new HashMap<>();
             for (String tagName : subscriptionRequest.getTagNames()) {
                 DefaultPlcSubscriptionTag subscriptionTag =
                     (DefaultPlcSubscriptionTag) subscriptionRequest.getTag(tagName);
                 FirmataTag tag = (FirmataTag) subscriptionTag.getTag();
-                result.put(tagName, new ResponseItem<>(PlcResponseCode.OK,
+                result.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK,
                     new FirmataSubscriptionHandle(this, tagName, tag)));
             }
             future.complete(new DefaultPlcSubscriptionResponse(subscriptionRequest, result));
@@ -279,13 +287,13 @@ public class FirmataProtocolLogic extends Plc4xProtocolBase<FirmataMessage> impl
         // If it's just one element, return this as a direct PlcValue
         if (values.size() == 1) {
             final PlcSubscriptionEvent event = new DefaultPlcSubscriptionEvent(Instant.now(),
-                Collections.singletonMap(tagName, new ResponseItem<>(PlcResponseCode.OK, values.get(0))));
+                Collections.singletonMap(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, values.get(0))));
             consumer.accept(event);
         }
         // If it's more, return a PlcList instead.
         else {
             final PlcSubscriptionEvent event = new DefaultPlcSubscriptionEvent(Instant.now(),
-                Collections.singletonMap(tagName, new ResponseItem<>(PlcResponseCode.OK, new PlcList(values))));
+                Collections.singletonMap(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, new PlcList(values))));
             consumer.accept(event);
         }
     }
diff --git a/plc4j/drivers/iec-60870/src/main/java/org/apache/plc4x/java/iec608705104/readwrite/Iec60870514PlcDriver.java b/plc4j/drivers/iec-60870/src/main/java/org/apache/plc4x/java/iec608705104/readwrite/Iec60870514PlcDriver.java
index 559dde0316..bd0e5c8045 100644
--- a/plc4j/drivers/iec-60870/src/main/java/org/apache/plc4x/java/iec608705104/readwrite/Iec60870514PlcDriver.java
+++ b/plc4j/drivers/iec-60870/src/main/java/org/apache/plc4x/java/iec608705104/readwrite/Iec60870514PlcDriver.java
@@ -24,11 +24,9 @@ import org.apache.plc4x.java.spi.configuration.PlcTransportConfiguration;
 import org.apache.plc4x.java.iec608705104.readwrite.configuration.Iec608705014Configuration;
 import org.apache.plc4x.java.iec608705104.readwrite.configuration.Iec608705014TcpTransportConfiguration;
 import org.apache.plc4x.java.iec608705104.readwrite.protocol.Iec608705104Protocol;
-import org.apache.plc4x.java.iec608705104.readwrite.tag.Iec608705104TagHandler;
 import org.apache.plc4x.java.spi.connection.GeneratedDriverBase;
 import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer;
 import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer;
-import org.apache.plc4x.java.spi.values.PlcValueHandler;
 
 import java.util.Collections;
 import java.util.List;
@@ -83,16 +81,6 @@ public class Iec60870514PlcDriver extends GeneratedDriverBase<APDU> {
         return Collections.singletonList("tcp");
     }
 
-    @Override
-    protected Iec608705104TagHandler getTagHandler() {
-        return new Iec608705104TagHandler();
-    }
-
-    @Override
-    protected org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() {
-        return new PlcValueHandler();
-    }
-
     /**
      * This protocol doesn't have a disconnect procedure, so there is no need to wait for a login to finish.
      * @return false
diff --git a/plc4j/drivers/iec-60870/src/main/java/org/apache/plc4x/java/iec608705104/readwrite/messages/Iec608705104PlcSubscriptionEvent.java b/plc4j/drivers/iec-60870/src/main/java/org/apache/plc4x/java/iec608705104/readwrite/messages/Iec608705104PlcSubscriptionEvent.java
index 25e732f982..9c336c99ce 100644
--- a/plc4j/drivers/iec-60870/src/main/java/org/apache/plc4x/java/iec608705104/readwrite/messages/Iec608705104PlcSubscriptionEvent.java
+++ b/plc4j/drivers/iec-60870/src/main/java/org/apache/plc4x/java/iec608705104/readwrite/messages/Iec608705104PlcSubscriptionEvent.java
@@ -22,7 +22,7 @@ package org.apache.plc4x.java.iec608705104.readwrite.messages;
 import org.apache.plc4x.java.api.model.PlcTag;
 import org.apache.plc4x.java.api.value.PlcValue;
 import org.apache.plc4x.java.spi.messages.DefaultPlcSubscriptionEvent;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem;
 
 import java.time.Instant;
 import java.util.Map;
@@ -30,7 +30,7 @@ import java.util.Map;
 public class Iec608705104PlcSubscriptionEvent extends DefaultPlcSubscriptionEvent {
 
     private final Map<String, PlcTag> tags;
-    public Iec608705104PlcSubscriptionEvent(Instant timestamp, Map<String, PlcTag> tags, Map<String, ResponseItem<PlcValue>> values) {
+    public Iec608705104PlcSubscriptionEvent(Instant timestamp, Map<String, PlcTag> tags, Map<String, PlcResponseItem<PlcValue>> values) {
         super(timestamp, values);
         this.tags = tags;
     }
diff --git a/plc4j/drivers/iec-60870/src/main/java/org/apache/plc4x/java/iec608705104/readwrite/protocol/Iec608705104Protocol.java b/plc4j/drivers/iec-60870/src/main/java/org/apache/plc4x/java/iec608705104/readwrite/protocol/Iec608705104Protocol.java
index 1252249481..61e4a41e2c 100644
--- a/plc4j/drivers/iec-60870/src/main/java/org/apache/plc4x/java/iec608705104/readwrite/protocol/Iec608705104Protocol.java
+++ b/plc4j/drivers/iec-60870/src/main/java/org/apache/plc4x/java/iec608705104/readwrite/protocol/Iec608705104Protocol.java
@@ -31,13 +31,16 @@ import org.apache.plc4x.java.iec608705104.readwrite.configuration.Iec608705014Co
 import org.apache.plc4x.java.iec608705104.readwrite.messages.Iec608705104PlcSubscriptionEvent;
 import org.apache.plc4x.java.iec608705104.readwrite.model.Iec608705104SubscriptionHandle;
 import org.apache.plc4x.java.iec608705104.readwrite.tag.Iec608705104Tag;
+import org.apache.plc4x.java.iec608705104.readwrite.tag.Iec608705104TagHandler;
 import org.apache.plc4x.java.spi.ConversationContext;
 import org.apache.plc4x.java.spi.Plc4xProtocolBase;
 import org.apache.plc4x.java.spi.configuration.HasConfiguration;
+import org.apache.plc4x.java.spi.connection.PlcTagHandler;
 import org.apache.plc4x.java.spi.messages.DefaultPlcSubscriptionResponse;
 import org.apache.plc4x.java.spi.messages.PlcBrowser;
 import org.apache.plc4x.java.spi.messages.PlcSubscriber;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem;
 import org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration;
 import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionTag;
 import org.apache.plc4x.java.spi.transaction.RequestTransactionManager;
@@ -70,6 +73,11 @@ public class Iec608705104Protocol extends Plc4xProtocolBase<APDU> implements Has
         this.configuration = configuration;
     }
 
+    @Override
+    public PlcTagHandler getTagHandler() {
+        return new Iec608705104TagHandler();
+    }
+
     @Override
     public void close(ConversationContext<APDU> context) {
         tm.shutdown();
@@ -130,13 +138,13 @@ public class Iec608705104Protocol extends Plc4xProtocolBase<APDU> implements Has
 
     @Override
     public CompletableFuture<PlcSubscriptionResponse> subscribe(PlcSubscriptionRequest subscriptionRequest) {
-        Map<String, ResponseItem<PlcSubscriptionHandle>> values = new HashMap<>();
+        Map<String, PlcResponseItem<PlcSubscriptionHandle>> values = new HashMap<>();
         for (String tagName : subscriptionRequest.getTagNames()) {
             final DefaultPlcSubscriptionTag tag = (DefaultPlcSubscriptionTag) subscriptionRequest.getTag(tagName);
             if (!(tag.getTag() instanceof Iec608705104Tag)) {
-                values.put(tagName, new ResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null));
+                values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null));
             } else {
-                values.put(tagName, new ResponseItem<>(PlcResponseCode.OK,
+                values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK,
                     new Iec608705104SubscriptionHandle(this, (Iec608705104Tag) tag.getTag())));
             }
         }
@@ -208,7 +216,7 @@ public class Iec608705104Protocol extends Plc4xProtocolBase<APDU> implements Has
             timeStamp.atZone(ZoneId.systemDefault()).toInstant(),
             Collections.singletonMap(tag.toString(), tag),
             Collections.singletonMap(tag.toString(),
-                new ResponseItem<>(PlcResponseCode.OK, plcValue)));
+                new DefaultPlcResponseItem<>(PlcResponseCode.OK, plcValue)));
 
         // Try sending the subscription event to all listeners.
         for (Map.Entry<DefaultPlcConsumerRegistration, Consumer<PlcSubscriptionEvent>> entry : consumers.entrySet()) {
diff --git a/plc4j/drivers/knxnetip/src/main/java/org/apache/plc4x/java/knxnetip/KnxNetIpDriver.java b/plc4j/drivers/knxnetip/src/main/java/org/apache/plc4x/java/knxnetip/KnxNetIpDriver.java
index fda82f4442..5718f34b8c 100644
--- a/plc4j/drivers/knxnetip/src/main/java/org/apache/plc4x/java/knxnetip/KnxNetIpDriver.java
+++ b/plc4j/drivers/knxnetip/src/main/java/org/apache/plc4x/java/knxnetip/KnxNetIpDriver.java
@@ -30,12 +30,9 @@ import org.apache.plc4x.java.knxnetip.configuration.KnxNetIpUdpTransportConfigur
 import org.apache.plc4x.java.knxnetip.context.KnxNetIpDriverContext;
 import org.apache.plc4x.java.knxnetip.tag.KnxNetIpTag;
 import org.apache.plc4x.java.knxnetip.readwrite.KnxNetIpMessage;
-import org.apache.plc4x.java.knxnetip.tag.KnxNetIpTagHandler;
 import org.apache.plc4x.java.knxnetip.protocol.KnxNetIpProtocolLogic;
 import org.apache.plc4x.java.spi.messages.DefaultPlcDiscoveryRequest;
-import org.apache.plc4x.java.spi.values.PlcValueHandler;
 import org.apache.plc4x.java.spi.connection.GeneratedDriverBase;
-import org.apache.plc4x.java.spi.connection.PlcTagHandler;
 import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer;
 import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer;
 import org.apache.plc4x.java.spi.optimizer.BaseOptimizer;
@@ -123,16 +120,6 @@ public class KnxNetIpDriver extends GeneratedDriverBase<KnxNetIpMessage> {
         return new SingleTagOptimizer();
     }
 
-    @Override
-    protected PlcTagHandler getTagHandler() {
-        return new KnxNetIpTagHandler();
-    }
-
-    @Override
-    protected org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() {
-        return new PlcValueHandler();
-    }
-
     @Override
     protected boolean awaitDisconnectComplete() { return true; }
 
diff --git a/plc4j/drivers/knxnetip/src/main/java/org/apache/plc4x/java/knxnetip/protocol/KnxNetIpProtocolLogic.java b/plc4j/drivers/knxnetip/src/main/java/org/apache/plc4x/java/knxnetip/protocol/KnxNetIpProtocolLogic.java
index 962cbeb06d..7b258a86ec 100644
--- a/plc4j/drivers/knxnetip/src/main/java/org/apache/plc4x/java/knxnetip/protocol/KnxNetIpProtocolLogic.java
+++ b/plc4j/drivers/knxnetip/src/main/java/org/apache/plc4x/java/knxnetip/protocol/KnxNetIpProtocolLogic.java
@@ -32,12 +32,15 @@ import org.apache.plc4x.java.knxnetip.ets.model.GroupAddress;
 import org.apache.plc4x.java.knxnetip.model.KnxNetIpSubscriptionHandle;
 import org.apache.plc4x.java.knxnetip.readwrite.*;
 import org.apache.plc4x.java.knxnetip.tag.KnxNetIpTag;
+import org.apache.plc4x.java.knxnetip.tag.KnxNetIpTagHandler;
 import org.apache.plc4x.java.spi.ConversationContext;
 import org.apache.plc4x.java.spi.Plc4xProtocolBase;
+import org.apache.plc4x.java.spi.connection.PlcTagHandler;
 import org.apache.plc4x.java.spi.context.DriverContext;
 import org.apache.plc4x.java.spi.generation.*;
 import org.apache.plc4x.java.spi.messages.*;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem;
 import org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration;
 import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionTag;
 import org.apache.plc4x.java.spi.transaction.RequestTransactionManager;
@@ -80,6 +83,11 @@ public class KnxNetIpProtocolLogic extends Plc4xProtocolBase<KnxNetIpMessage> im
         this.tm = new RequestTransactionManager(1);
     }
 
+    @Override
+    public PlcTagHandler getTagHandler() {
+        return new KnxNetIpTagHandler();
+    }
+
     @Override
     public void close(ConversationContext<KnxNetIpMessage> context) {
         tm.shutdown();
@@ -258,7 +266,7 @@ public class KnxNetIpProtocolLogic extends Plc4xProtocolBase<KnxNetIpMessage> im
                 new HPAIControlEndpoint(HostProtocolCode.IPV4_UDP,
                     knxNetIpDriverContext.getLocalIPAddress(),
                     knxNetIpDriverContext.getLocalPort()));
-        context.sendRequest(connectionStateRequest)
+        conversationContext.sendRequest(connectionStateRequest)
             .expectResponse(KnxNetIpMessage.class, Duration.ofMillis(1000))
             .only(ConnectionStateResponse.class)
             .handle(connectionStateResponse -> {
@@ -374,7 +382,7 @@ public class KnxNetIpProtocolLogic extends Plc4xProtocolBase<KnxNetIpMessage> im
             // Start a new request-transaction (Is ended in the response-handler)
             RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
             // Start a new request-transaction (Is ended in the response-handler)
-            transaction.submit(() -> context.sendRequest(knxRequest)
+            transaction.submit(() -> conversationContext.sendRequest(knxRequest)
                 .expectResponse(KnxNetIpMessage.class, REQUEST_TIMEOUT)
                 .onTimeout(future::completeExceptionally)
                 .onError((tr, e) -> future.completeExceptionally(e))
@@ -540,13 +548,13 @@ public class KnxNetIpProtocolLogic extends Plc4xProtocolBase<KnxNetIpMessage> im
 
     @Override
     public CompletableFuture<PlcSubscriptionResponse> subscribe(PlcSubscriptionRequest subscriptionRequest) {
-        Map<String, ResponseItem<PlcSubscriptionHandle>> values = new HashMap<>();
+        Map<String, PlcResponseItem<PlcSubscriptionHandle>> values = new HashMap<>();
         for (String tagName : subscriptionRequest.getTagNames()) {
             final DefaultPlcSubscriptionTag tag = (DefaultPlcSubscriptionTag) subscriptionRequest.getTag(tagName);
             if (!(tag.getTag() instanceof KnxNetIpTag)) {
-                values.put(tagName, new ResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null));
+                values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null));
             } else {
-                values.put(tagName, new ResponseItem<>(PlcResponseCode.OK,
+                values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK,
                     new KnxNetIpSubscriptionHandle(this, (KnxNetIpTag) tag.getTag())));
             }
         }
@@ -572,7 +580,7 @@ public class KnxNetIpProtocolLogic extends Plc4xProtocolBase<KnxNetIpMessage> im
         // Create a subscription event from the input.
         // TODO: Check this ... this is sort of not really right ...
         final PlcSubscriptionEvent event = new DefaultPlcSubscriptionEvent(Instant.now(),
-            Collections.singletonMap("knxData", new ResponseItem<>(PlcResponseCode.OK, plcValue)));
+            Collections.singletonMap("knxData", new DefaultPlcResponseItem<>(PlcResponseCode.OK, plcValue)));
 
         // Try sending the subscription event to all listeners.
         for (Map.Entry<DefaultPlcConsumerRegistration, Consumer<PlcSubscriptionEvent>> entry : consumers.entrySet()) {
diff --git a/plc4j/drivers/knxnetip/src/test/java/org/apache/plc4x/java/knxnetip/ManualKnxNetIp.java b/plc4j/drivers/knxnetip/src/test/java/org/apache/plc4x/java/knxnetip/ManualKnxNetIp.java
index 7e3a1b32ea..9cadd0191d 100644
--- a/plc4j/drivers/knxnetip/src/test/java/org/apache/plc4x/java/knxnetip/ManualKnxNetIp.java
+++ b/plc4j/drivers/knxnetip/src/test/java/org/apache/plc4x/java/knxnetip/ManualKnxNetIp.java
@@ -38,8 +38,8 @@ public class ManualKnxNetIp {
     // */*/101: Power Line 1
 
     public static void main(String[] args) throws Exception {
-        //final PlcConnection connection = new PlcDriverManager().getConnection("knxnet-ip://192.168.42.11?knxproj-file-path=/Users/christofer.dutz/Projects/Apache/PLC4X-Documents/KNX/Stettiner%20Str.%2013/StettinerStr-Soll-Ist-Temperatur.knxproj");
-        final PlcConnection connection = new DefaultPlcDriverManager().getConnection("knxnet-ip:pcap:///Users/christofer.dutz/Projects/Apache/PLC4X-Documents/KNX/Recording-01.03.2020-2.pcapng?knxproj-file-path=/Users/christofer.dutz/Projects/Apache/PLC4X-Documents/KNX/Stettiner%20Str.%2013/StettinerStr-Soll-Ist-Temperatur.knxproj");
+        final PlcConnection connection = new DefaultPlcDriverManager().getConnection("knxnet-ip://192.168.42.11?knxproj-file-path=/Users/christofer.dutz/Projects/Apache/PLC4X-Documents/KNX/Stettiner%20Str.%2013/StettinerStr-Soll-Ist-Temperatur.knxproj");
+        //final PlcConnection connection = new DefaultPlcDriverManager().getConnection("knxnet-ip:pcap:///Users/christofer.dutz/Projects/Apache/PLC4X-Documents/KNX/Recording-01.03.2020-2.pcapng?knxproj-file-path=/Users/christofer.dutz/Projects/Apache/PLC4X-Documents/KNX/Stettiner%20Str.%2013/StettinerStr-Soll-Ist-Temperatur.knxproj");
         // Make sure we hang up correctly when terminating.
         Runtime.getRuntime().addShutdownHook(new Thread(() -> {
             try {
diff --git a/plc4j/drivers/knxnetip/src/test/resources/logback-test.xml b/plc4j/drivers/knxnetip/src/test/resources/logback-test.xml
index 33ae65561c..16b83b4882 100644
--- a/plc4j/drivers/knxnetip/src/test/resources/logback-test.xml
+++ b/plc4j/drivers/knxnetip/src/test/resources/logback-test.xml
@@ -27,7 +27,7 @@
     </encoder>
   </appender>
 
-  <root level="error">
+  <root level="warn">
     <appender-ref ref="STDOUT" />
   </root>
 
diff --git a/plc4j/drivers/mock/src/main/java/org/apache/plc4x/java/mock/connection/MockConnection.java b/plc4j/drivers/mock/src/main/java/org/apache/plc4x/java/mock/connection/MockConnection.java
index 0ad98b39e6..b3c4d3a371 100644
--- a/plc4j/drivers/mock/src/main/java/org/apache/plc4x/java/mock/connection/MockConnection.java
+++ b/plc4j/drivers/mock/src/main/java/org/apache/plc4x/java/mock/connection/MockConnection.java
@@ -21,6 +21,7 @@ package org.apache.plc4x.java.mock.connection;
 import org.apache.commons.lang3.Validate;
 import org.apache.plc4x.java.api.PlcConnection;
 import org.apache.plc4x.java.api.authentication.PlcAuthentication;
+import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
 import org.apache.plc4x.java.api.messages.*;
 import org.apache.plc4x.java.api.metadata.PlcConnectionMetadata;
 import org.apache.plc4x.java.api.model.PlcConsumerRegistration;
@@ -30,7 +31,8 @@ import org.apache.plc4x.java.api.types.PlcResponseCode;
 import org.apache.plc4x.java.api.value.PlcValue;
 import org.apache.plc4x.java.mock.tag.MockTagHandler;
 import org.apache.plc4x.java.spi.messages.*;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem;
+import org.apache.plc4x.java.spi.values.DefaultPlcValueHandler;
 import org.apache.plc4x.java.spi.values.PlcValueHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -48,6 +50,8 @@ public class MockConnection implements PlcConnection, PlcReader, PlcWriter, PlcS
 
     private static final Logger LOGGER = LoggerFactory.getLogger(MockConnection.class);
 
+    private PlcValueHandler valueHandler;
+
     private final PlcAuthentication authentication;
 
     private MockDevice device;
@@ -63,9 +67,21 @@ public class MockConnection implements PlcConnection, PlcReader, PlcWriter, PlcS
     private final MockTagHandler mockTagHandler = new MockTagHandler();
     public void setDevice(MockDevice device) {
         LOGGER.info("Set Mock Device on Mock Connection {} with device {}", this, device);
+        this.valueHandler = new DefaultPlcValueHandler();
         this.device = device;
     }
 
+    @Override
+    public Optional<PlcValue> parseTagValue(PlcTag tag, Object... values) {
+        PlcValue plcValue;
+        try {
+            plcValue = valueHandler.newPlcValue(tag, values);
+        } catch (Exception e) {
+            throw new PlcRuntimeException("Error parsing tag value " + tag, e);
+        }
+        return Optional.of(plcValue);
+    }
+
     @Override
     public void connect() {
         // do nothing
@@ -145,7 +161,7 @@ public class MockConnection implements PlcConnection, PlcReader, PlcWriter, PlcS
         return CompletableFuture.supplyAsync(() -> {
             Validate.notNull(device, "No device is set in the mock connection!");
             LOGGER.debug("Sending read request to MockDevice");
-            Map<String, ResponseItem<PlcValue>> response = readRequest.getTagNames().stream()
+            Map<String, PlcResponseItem<PlcValue>> response = readRequest.getTagNames().stream()
                 .collect(Collectors.toMap(
                         Function.identity(),
                         name -> device.read(readRequest.getTag(name).getAddressString())
@@ -175,7 +191,7 @@ public class MockConnection implements PlcConnection, PlcReader, PlcWriter, PlcS
         return CompletableFuture.supplyAsync(() -> {
             Validate.notNull(device, "No device is set in the mock connection!");
             LOGGER.debug("Sending subsribe request to MockDevice");
-            Map<String, ResponseItem<PlcSubscriptionHandle>> response = subscriptionRequest.getTagNames().stream()
+            Map<String, PlcResponseItem<PlcSubscriptionHandle>> response = subscriptionRequest.getTagNames().stream()
                 .collect(Collectors.toMap(
                         Function.identity(),
                         name -> device.subscribe(subscriptionRequest.getTag(name).getAddressString())
@@ -207,7 +223,7 @@ public class MockConnection implements PlcConnection, PlcReader, PlcWriter, PlcS
 
     @Override
     public PlcWriteRequest.Builder writeRequestBuilder() {
-        return new DefaultPlcWriteRequest.Builder(this, mockTagHandler, new PlcValueHandler());
+        return new DefaultPlcWriteRequest.Builder(this, mockTagHandler, new DefaultPlcValueHandler());
     }
 
     @Override
diff --git a/plc4j/drivers/mock/src/main/java/org/apache/plc4x/java/mock/connection/MockDevice.java b/plc4j/drivers/mock/src/main/java/org/apache/plc4x/java/mock/connection/MockDevice.java
index 7537a60fc2..da61603742 100644
--- a/plc4j/drivers/mock/src/main/java/org/apache/plc4x/java/mock/connection/MockDevice.java
+++ b/plc4j/drivers/mock/src/main/java/org/apache/plc4x/java/mock/connection/MockDevice.java
@@ -18,13 +18,12 @@
  */
 package org.apache.plc4x.java.mock.connection;
 
-import org.apache.commons.lang3.tuple.Pair;
 import org.apache.plc4x.java.api.messages.PlcSubscriptionEvent;
 import org.apache.plc4x.java.api.model.PlcConsumerRegistration;
 import org.apache.plc4x.java.api.model.PlcSubscriptionHandle;
 import org.apache.plc4x.java.api.types.PlcResponseCode;
 import org.apache.plc4x.java.api.value.PlcValue;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem;
 
 import java.util.Collection;
 import java.util.function.Consumer;
@@ -34,11 +33,11 @@ import java.util.function.Consumer;
  */
 public interface MockDevice {
 
-    ResponseItem<PlcValue> read(String tagQuery);
+    PlcResponseItem<PlcValue> read(String tagQuery);
 
     PlcResponseCode write(String tagQuery, Object value);
 
-    ResponseItem<PlcSubscriptionHandle> subscribe(String tagQuery);
+    PlcResponseItem<PlcSubscriptionHandle> subscribe(String tagQuery);
 
     void unsubscribe();
 
diff --git a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/ascii/ModbusAsciiDriver.java b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/ascii/ModbusAsciiDriver.java
index c698b342ff..20006d99fc 100644
--- a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/ascii/ModbusAsciiDriver.java
+++ b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/ascii/ModbusAsciiDriver.java
@@ -22,14 +22,11 @@ import io.netty.buffer.ByteBuf;
 import org.apache.commons.codec.DecoderException;
 import org.apache.commons.codec.binary.Hex;
 import org.apache.plc4x.java.modbus.ascii.context.ModbusAsciiContext;
-import org.apache.plc4x.java.modbus.readwrite.ModbusADU;
-import org.apache.plc4x.java.modbus.readwrite.ModbusRtuADU;
 import org.apache.plc4x.java.spi.configuration.PlcConnectionConfiguration;
 import org.apache.plc4x.java.spi.configuration.PlcTransportConfiguration;
 import org.apache.plc4x.java.modbus.ascii.config.ModbusAsciiConfiguration;
 import org.apache.plc4x.java.modbus.ascii.protocol.ModbusAsciiProtocolLogic;
 import org.apache.plc4x.java.modbus.base.tag.ModbusTag;
-import org.apache.plc4x.java.modbus.base.tag.ModbusTagHandler;
 import org.apache.plc4x.java.modbus.readwrite.DriverType;
 import org.apache.plc4x.java.modbus.readwrite.ModbusAsciiADU;
 import org.apache.plc4x.java.modbus.tcp.config.ModbusTcpTransportConfiguration;
@@ -39,7 +36,6 @@ import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer;
 import org.apache.plc4x.java.spi.generation.*;
 import org.apache.plc4x.java.spi.optimizer.BaseOptimizer;
 import org.apache.plc4x.java.spi.optimizer.SingleTagOptimizer;
-import org.apache.plc4x.java.spi.values.PlcValueHandler;
 
 import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
@@ -122,16 +118,6 @@ public class ModbusAsciiDriver extends GeneratedDriverBase<ModbusAsciiADU> {
         return new SingleTagOptimizer();
     }
 
-    @Override
-    protected ModbusTagHandler getTagHandler() {
-        return new ModbusTagHandler();
-    }
-
-    @Override
-    protected org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() {
-        return new PlcValueHandler();
-    }
-
     @Override
     protected ProtocolStackConfigurer<ModbusAsciiADU> getStackConfigurer() {
         return SingleProtocolStackConfigurer.builder(ModbusAsciiADU.class, new ModbusAsciiInput(), new ModbusAsciiOutput())
diff --git a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/ascii/protocol/ModbusAsciiProtocolLogic.java b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/ascii/protocol/ModbusAsciiProtocolLogic.java
index 47b5a86da6..f3f9084eae 100644
--- a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/ascii/protocol/ModbusAsciiProtocolLogic.java
+++ b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/ascii/protocol/ModbusAsciiProtocolLogic.java
@@ -26,13 +26,15 @@ import org.apache.plc4x.java.api.value.PlcValue;
 import org.apache.plc4x.java.modbus.ascii.config.ModbusAsciiConfiguration;
 import org.apache.plc4x.java.modbus.base.tag.ModbusTag;
 import org.apache.plc4x.java.modbus.base.protocol.ModbusProtocolLogic;
+import org.apache.plc4x.java.modbus.base.tag.ModbusTagHandler;
 import org.apache.plc4x.java.modbus.readwrite.*;
 import org.apache.plc4x.java.modbus.types.ModbusByteOrder;
 import org.apache.plc4x.java.spi.ConversationContext;
 import org.apache.plc4x.java.spi.configuration.HasConfiguration;
+import org.apache.plc4x.java.spi.connection.PlcTagHandler;
 import org.apache.plc4x.java.spi.generation.ParseException;
 import org.apache.plc4x.java.spi.messages.*;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem;
 import org.apache.plc4x.java.spi.transaction.RequestTransactionManager;
 
 import java.time.Duration;
@@ -53,6 +55,11 @@ public class ModbusAsciiProtocolLogic extends ModbusProtocolLogic<ModbusAsciiADU
         this.tm = new RequestTransactionManager(1);
     }
 
+    @Override
+    public PlcTagHandler getTagHandler() {
+        return new ModbusTagHandler();
+    }
+
     @Override
     public void close(ConversationContext<ModbusAsciiADU> context) {
         tm.shutdown();
@@ -70,7 +77,7 @@ public class ModbusAsciiProtocolLogic extends ModbusProtocolLogic<ModbusAsciiADU
         ModbusAsciiADU modbusTcpADU = new ModbusAsciiADU(unitId, readRequestPdu);
 
         RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
-        transaction.submit(() -> context.sendRequest(modbusTcpADU)
+        transaction.submit(() -> conversationContext.sendRequest(modbusTcpADU)
             .expectResponse(ModbusAsciiADU.class, requestTimeout)
             .onTimeout(future::completeExceptionally)
             .onError((p, e) -> future.completeExceptionally(e))
@@ -106,7 +113,7 @@ public class ModbusAsciiProtocolLogic extends ModbusProtocolLogic<ModbusAsciiADU
 
             ModbusAsciiADU modbusAsciiADU = new ModbusAsciiADU(unitId, requestPdu);
             RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
-            transaction.submit(() -> context.sendRequest(modbusAsciiADU)
+            transaction.submit(() -> conversationContext.sendRequest(modbusAsciiADU)
                 .expectResponse(ModbusAsciiADU.class, requestTimeout)
                 .onTimeout(future::completeExceptionally)
                 .onError((p, e) -> future.completeExceptionally(e))
@@ -135,7 +142,7 @@ public class ModbusAsciiProtocolLogic extends ModbusProtocolLogic<ModbusAsciiADU
 
                     // Prepare the response.
                     PlcReadResponse response = new DefaultPlcReadResponse(request,
-                        Collections.singletonMap(tagName, new ResponseItem<>(responseCode, plcValue)));
+                        Collections.singletonMap(tagName, new DefaultPlcResponseItem<>(responseCode, plcValue)));
 
                     // Pass the response back to the application.
                     future.complete(response);
@@ -169,7 +176,7 @@ public class ModbusAsciiProtocolLogic extends ModbusProtocolLogic<ModbusAsciiADU
             final short unitId = getUnitId(tag);
             ModbusAsciiADU modbusAsciiADU = new ModbusAsciiADU(unitId, requestPdu);
             RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
-            transaction.submit(() -> context.sendRequest(modbusAsciiADU)
+            transaction.submit(() -> conversationContext.sendRequest(modbusAsciiADU)
                 .expectResponse(ModbusAsciiADU.class, requestTimeout)
                 .onTimeout(future::completeExceptionally)
                 .onError((p, e) -> future.completeExceptionally(e))
diff --git a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/base/optimizer/ModbusOptimizer.java b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/base/optimizer/ModbusOptimizer.java
index d88998472b..78b092282c 100644
--- a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/base/optimizer/ModbusOptimizer.java
+++ b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/base/optimizer/ModbusOptimizer.java
@@ -45,7 +45,10 @@ import org.apache.plc4x.java.spi.generation.WriteBufferXmlBased;
 import org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest;
 import org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse;
 import org.apache.plc4x.java.spi.messages.PlcReader;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcTagItem;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcTagItem;
 import org.apache.plc4x.java.spi.optimizer.SingleTagOptimizer;
 import org.apache.plc4x.java.spi.values.PlcBOOL;
 import org.slf4j.Logger;
@@ -179,12 +182,12 @@ public class ModbusOptimizer extends SingleTagOptimizer {
             }
 
             // Now go through the original requests and try to answer them by using the raw data we now have.
-            Map<String, ResponseItem<PlcValue>> values = new HashMap<>();
+            Map<String, PlcResponseItem<PlcValue>> values = new HashMap<>();
             for (String tagName : readRequest.getTagNames()) {
                 ModbusTag modbusTag = (ModbusTag) readRequest.getTag(tagName);
                 String tagType = modbusTag.getClass().getSimpleName().substring("ModbusTag".length());
                 if (!responses.containsKey(tagType)) {
-                    values.put(tagName, new ResponseItem<>(PlcResponseCode.NOT_FOUND, null));
+                    values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.NOT_FOUND, null));
                     continue;
                 }
                 // Go through all responses till we find one where that contains the current tag's data.
@@ -197,7 +200,7 @@ public class ModbusOptimizer extends SingleTagOptimizer {
                             //  current request exceeds the address range, all items in this chunk will fail, even
                             //  if only one element was invalid.
                             if(response.getResponseCode() != PlcResponseCode.OK) {
-                                values.put(tagName, new ResponseItem<>(response.getResponseCode(), null));
+                                values.put(tagName, new DefaultPlcResponseItem<>(response.getResponseCode(), null));
                                 break;
                             }
 
@@ -210,7 +213,7 @@ public class ModbusOptimizer extends SingleTagOptimizer {
                             int bytePosition = bitPosition / 8;
                             int bitPositionInByte = bitPosition % 8;
                             boolean isBitSet = (responseData[bytePosition] & (1 << bitPositionInByte)) != 0;
-                            values.put(tagName, new ResponseItem<>(PlcResponseCode.OK, new PlcBOOL(isBitSet)));
+                            values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, new PlcBOOL(isBitSet)));
                             break;
                         }
                     }
@@ -222,7 +225,7 @@ public class ModbusOptimizer extends SingleTagOptimizer {
                         //  current request exceeds the address range, all items in this chunk will fail, even
                         //  if only one element was invalid.
                         if(response.getResponseCode() != PlcResponseCode.OK) {
-                            values.put(tagName, new ResponseItem<>(response.getResponseCode(), null));
+                            values.put(tagName, new DefaultPlcResponseItem<>(response.getResponseCode(), null));
                             break;
                         }
 
@@ -232,16 +235,16 @@ public class ModbusOptimizer extends SingleTagOptimizer {
                             PlcValue plcValue = DataItem.staticParse(readBuffer, modbusTag.getDataType(),
                                 modbusTag.getNumberOfElements(),
                                 modbusContext.getByteOrder() == ModbusByteOrder.BIG_ENDIAN);
-                            values.put(tagName, new ResponseItem<>(PlcResponseCode.OK, plcValue));
+                            values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, plcValue));
                         } catch (ParseException e) {
-                            values.put(tagName, new ResponseItem<>(PlcResponseCode.INTERNAL_ERROR, null));
+                            values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.INTERNAL_ERROR, null));
                         }
                         break;
                     }
                 }
                 // If no response was found that contains the data, that's probably something we need to fix.
                 if (!values.containsKey(tagName)) {
-                    values.put(tagName, new ResponseItem<>(PlcResponseCode.INTERNAL_ERROR, null));
+                    values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.INTERNAL_ERROR, null));
                 }
             }
 
@@ -302,8 +305,8 @@ public class ModbusOptimizer extends SingleTagOptimizer {
             // finish this one and start a new one.
             if (tag.getAddress() + (sizeInCoils * tag.getNumberOfElements()) > maxCoilCurRequest) {
                 // Finish the current sub-request
-                LinkedHashMap<String, PlcTag> subTags = new LinkedHashMap<>();
-                subTags.put("coils" + subRequests.size(), new ModbusTagCoil(firstCoil, lastCoil - firstCoil, ModbusDataType.BYTE, Collections.emptyMap()));
+                LinkedHashMap<String, PlcTagItem> subTags = new LinkedHashMap<>();
+                subTags.put("coils" + subRequests.size(), new DefaultPlcTagItem(new ModbusTagCoil(firstCoil, lastCoil - firstCoil, ModbusDataType.BYTE, Collections.emptyMap())));
                 subRequests.add(new DefaultPlcReadRequest(reader, subTags));
 
                 // Re-initialize the structures for the next request.
@@ -318,8 +321,8 @@ public class ModbusOptimizer extends SingleTagOptimizer {
         }
 
         // Finish the last sub-request
-        LinkedHashMap<String, PlcTag> subTags = new LinkedHashMap<>();
-        subTags.put("coils" + subRequests.size(), new ModbusTagCoil(firstCoil, lastCoil - firstCoil, ModbusDataType.BYTE, Collections.emptyMap()));
+        LinkedHashMap<String, PlcTagItem> subTags = new LinkedHashMap<>();
+        subTags.put("coils" + subRequests.size(), new DefaultPlcTagItem(new ModbusTagCoil(firstCoil, lastCoil - firstCoil, ModbusDataType.BYTE, Collections.emptyMap())));
         subRequests.add(new DefaultPlcReadRequest(reader, subTags));
         return subRequests;
     }
@@ -343,8 +346,8 @@ public class ModbusOptimizer extends SingleTagOptimizer {
             // finish this one and start a new one.
             if (tag.getAddress() + (sizeInRegisters * tag.getNumberOfElements()) > maxRegisterCurRequest) {
                 // Finish the current sub-request
-                LinkedHashMap<String, PlcTag> subTags = new LinkedHashMap<>();
-                subTags.put("registers" + subRequests.size(), tagFactory.createTag(firstRegister, lastRegister - firstRegister, ModbusDataType.WORD));
+                LinkedHashMap<String, PlcTagItem> subTags = new LinkedHashMap<>();
+                subTags.put("registers" + subRequests.size(), new DefaultPlcTagItem(tagFactory.createTag(firstRegister, lastRegister - firstRegister, ModbusDataType.WORD)));
                 subRequests.add(new DefaultPlcReadRequest(reader, subTags));
 
                 // Re-initialize the structures for the next request.
@@ -359,8 +362,8 @@ public class ModbusOptimizer extends SingleTagOptimizer {
         }
 
         // Finish the last sub-request
-        LinkedHashMap<String, PlcTag> subTags = new LinkedHashMap<>();
-        subTags.put("registers" + subRequests.size(), tagFactory.createTag(firstRegister, lastRegister - firstRegister, ModbusDataType.WORD));
+        LinkedHashMap<String, PlcTagItem> subTags = new LinkedHashMap<>();
+        subTags.put("registers" + subRequests.size(), new DefaultPlcTagItem(tagFactory.createTag(firstRegister, lastRegister - firstRegister, ModbusDataType.WORD)));
         subRequests.add(new DefaultPlcReadRequest(reader, subTags));
         return subRequests;
     }
diff --git a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/base/tag/ModbusTag.java b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/base/tag/ModbusTag.java
index ba571f9ae1..2f8baa1e54 100644
--- a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/base/tag/ModbusTag.java
+++ b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/base/tag/ModbusTag.java
@@ -75,7 +75,7 @@ public abstract class ModbusTag implements PlcTag, Serializable {
             address += ":" + getDataType().name();
         }
         if(!getArrayInfo().isEmpty()) {
-            address += "[" + getArrayInfo().get(0).getUpperBound() + "]";
+            address += "[" + (getArrayInfo().get(0).getUpperBound() + 1) + "]";
         }
         return address;
     }
@@ -158,7 +158,7 @@ public abstract class ModbusTag implements PlcTag, Serializable {
     @Override
     public List<ArrayInfo> getArrayInfo() {
         if(quantity != 1) {
-            return Collections.singletonList(new DefaultArrayInfo(0, quantity));
+            return Collections.singletonList(new DefaultArrayInfo(0, quantity - 1));
         }
         return Collections.emptyList();
     }
diff --git a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/rtu/ModbusRtuDriver.java b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/rtu/ModbusRtuDriver.java
index 176f6758ae..19a0e872dd 100644
--- a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/rtu/ModbusRtuDriver.java
+++ b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/rtu/ModbusRtuDriver.java
@@ -24,7 +24,6 @@ import org.apache.plc4x.java.modbus.rtu.context.ModbusRtuContext;
 import org.apache.plc4x.java.spi.configuration.PlcConnectionConfiguration;
 import org.apache.plc4x.java.spi.configuration.PlcTransportConfiguration;
 import org.apache.plc4x.java.modbus.base.tag.ModbusTag;
-import org.apache.plc4x.java.modbus.base.tag.ModbusTagHandler;
 import org.apache.plc4x.java.modbus.readwrite.DriverType;
 import org.apache.plc4x.java.modbus.readwrite.ModbusRtuADU;
 import org.apache.plc4x.java.modbus.rtu.config.ModbusRtuConfiguration;
@@ -33,12 +32,10 @@ import org.apache.plc4x.java.modbus.tcp.config.ModbusTcpTransportConfiguration;
 import org.apache.plc4x.java.spi.connection.GeneratedDriverBase;
 import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer;
 import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer;
-import org.apache.plc4x.java.spi.generation.MessageInput;
 import org.apache.plc4x.java.spi.generation.ParseException;
 import org.apache.plc4x.java.spi.generation.ReadBufferByteBased;
 import org.apache.plc4x.java.spi.optimizer.BaseOptimizer;
 import org.apache.plc4x.java.spi.optimizer.SingleTagOptimizer;
-import org.apache.plc4x.java.spi.values.PlcValueHandler;
 
 import java.util.Arrays;
 import java.util.List;
@@ -119,16 +116,6 @@ public class ModbusRtuDriver extends GeneratedDriverBase<ModbusRtuADU> {
         return new SingleTagOptimizer();
     }
 
-    @Override
-    protected ModbusTagHandler getTagHandler() {
-        return new ModbusTagHandler();
-    }
-
-    @Override
-    protected org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() {
-        return new PlcValueHandler();
-    }
-
     @Override
     protected ProtocolStackConfigurer<ModbusRtuADU> getStackConfigurer() {
         return SingleProtocolStackConfigurer.builder(ModbusRtuADU.class, io -> (ModbusRtuADU) ModbusRtuADU.staticParse(io, DriverType.MODBUS_RTU, true))
diff --git a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/rtu/protocol/ModbusRtuProtocolLogic.java b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/rtu/protocol/ModbusRtuProtocolLogic.java
index e3ad6e07b1..486ccb7fad 100644
--- a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/rtu/protocol/ModbusRtuProtocolLogic.java
+++ b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/rtu/protocol/ModbusRtuProtocolLogic.java
@@ -25,14 +25,16 @@ import org.apache.plc4x.java.api.types.PlcResponseCode;
 import org.apache.plc4x.java.api.value.PlcValue;
 import org.apache.plc4x.java.modbus.base.tag.ModbusTag;
 import org.apache.plc4x.java.modbus.base.protocol.ModbusProtocolLogic;
+import org.apache.plc4x.java.modbus.base.tag.ModbusTagHandler;
 import org.apache.plc4x.java.modbus.readwrite.*;
 import org.apache.plc4x.java.modbus.rtu.config.ModbusRtuConfiguration;
 import org.apache.plc4x.java.modbus.types.ModbusByteOrder;
 import org.apache.plc4x.java.spi.ConversationContext;
 import org.apache.plc4x.java.spi.configuration.HasConfiguration;
+import org.apache.plc4x.java.spi.connection.PlcTagHandler;
 import org.apache.plc4x.java.spi.generation.ParseException;
 import org.apache.plc4x.java.spi.messages.*;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem;
 import org.apache.plc4x.java.spi.transaction.RequestTransactionManager;
 
 import java.time.Duration;
@@ -53,6 +55,11 @@ public class ModbusRtuProtocolLogic extends ModbusProtocolLogic<ModbusRtuADU> im
         this.tm = new RequestTransactionManager(1);
     }
 
+    @Override
+    public PlcTagHandler getTagHandler() {
+        return new ModbusTagHandler();
+    }
+
     @Override
     public void close(ConversationContext<ModbusRtuADU> context) {
         tm.shutdown();
@@ -70,7 +77,7 @@ public class ModbusRtuProtocolLogic extends ModbusProtocolLogic<ModbusRtuADU> im
         ModbusRtuADU modbusRtuADU = new ModbusRtuADU(unitId, readRequestPdu);
 
         RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
-        transaction.submit(() -> context.sendRequest(modbusRtuADU)
+        transaction.submit(() -> conversationContext.sendRequest(modbusRtuADU)
             .expectResponse(ModbusRtuADU.class, requestTimeout)
             .onTimeout(future::completeExceptionally)
             .onError((p, e) -> future.completeExceptionally(e))
@@ -106,7 +113,7 @@ public class ModbusRtuProtocolLogic extends ModbusProtocolLogic<ModbusRtuADU> im
 
             ModbusRtuADU modbusRtuADU = new ModbusRtuADU(unitId, requestPdu);
             RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
-            transaction.submit(() -> context.sendRequest(modbusRtuADU)
+            transaction.submit(() -> conversationContext.sendRequest(modbusRtuADU)
                 .expectResponse(ModbusRtuADU.class, requestTimeout)
                 .onTimeout(future::completeExceptionally)
                 .onError((p, e) -> future.completeExceptionally(e))
@@ -135,7 +142,7 @@ public class ModbusRtuProtocolLogic extends ModbusProtocolLogic<ModbusRtuADU> im
 
                     // Prepare the response.
                     PlcReadResponse response = new DefaultPlcReadResponse(request,
-                        Collections.singletonMap(tagName, new ResponseItem<>(responseCode, plcValue)));
+                        Collections.singletonMap(tagName, new DefaultPlcResponseItem<>(responseCode, plcValue)));
 
                     // Pass the response back to the application.
                     future.complete(response);
@@ -169,7 +176,7 @@ public class ModbusRtuProtocolLogic extends ModbusProtocolLogic<ModbusRtuADU> im
             final short unitId = getUnitId(tag);
             ModbusRtuADU modbusRtuADU = new ModbusRtuADU(unitId, requestPdu);
             RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
-            transaction.submit(() -> context.sendRequest(modbusRtuADU)
+            transaction.submit(() -> conversationContext.sendRequest(modbusRtuADU)
                 .expectResponse(ModbusRtuADU.class, requestTimeout)
                 .onTimeout(future::completeExceptionally)
                 .onError((p, e) -> future.completeExceptionally(e))
diff --git a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/tcp/ModbusTcpDriver.java b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/tcp/ModbusTcpDriver.java
index 09fff6f315..a0bd18b9c6 100644
--- a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/tcp/ModbusTcpDriver.java
+++ b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/tcp/ModbusTcpDriver.java
@@ -29,12 +29,9 @@ import org.apache.plc4x.java.modbus.readwrite.DriverType;
 import org.apache.plc4x.java.modbus.tcp.config.ModbusTcpConfiguration;
 import org.apache.plc4x.java.modbus.tcp.config.ModbusTcpTransportConfiguration;
 import org.apache.plc4x.java.modbus.tcp.discovery.ModbusPlcDiscoverer;
-import org.apache.plc4x.java.modbus.base.tag.ModbusTagHandler;
 import org.apache.plc4x.java.modbus.readwrite.ModbusTcpADU;
 import org.apache.plc4x.java.modbus.tcp.protocol.ModbusTcpProtocolLogic;
 import org.apache.plc4x.java.spi.messages.DefaultPlcDiscoveryRequest;
-import org.apache.plc4x.java.spi.optimizer.SingleTagOptimizer;
-import org.apache.plc4x.java.spi.values.PlcValueHandler;
 import org.apache.plc4x.java.spi.connection.GeneratedDriverBase;
 import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer;
 import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer;
@@ -124,16 +121,6 @@ public class ModbusTcpDriver extends GeneratedDriverBase<ModbusTcpADU> {
         return new /*SingleTagOptimizer();/*/ModbusOptimizer();
     }
 
-    @Override
-    protected ModbusTagHandler getTagHandler() {
-        return new ModbusTagHandler();
-    }
-
-    @Override
-    protected org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() {
-        return new PlcValueHandler();
-    }
-
     @Override
     protected ProtocolStackConfigurer<ModbusTcpADU> getStackConfigurer() {
         return SingleProtocolStackConfigurer.builder(ModbusTcpADU.class, (io) -> (ModbusTcpADU) ModbusTcpADU.staticParse(io, DriverType.MODBUS_TCP, true))
diff --git a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/tcp/protocol/ModbusTcpProtocolLogic.java b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/tcp/protocol/ModbusTcpProtocolLogic.java
index ced1e1396d..e1615118a9 100644
--- a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/tcp/protocol/ModbusTcpProtocolLogic.java
+++ b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/tcp/protocol/ModbusTcpProtocolLogic.java
@@ -31,9 +31,10 @@ import org.apache.plc4x.java.modbus.tcp.config.ModbusTcpConfiguration;
 import org.apache.plc4x.java.modbus.types.ModbusByteOrder;
 import org.apache.plc4x.java.spi.ConversationContext;
 import org.apache.plc4x.java.spi.configuration.HasConfiguration;
+import org.apache.plc4x.java.spi.connection.PlcTagHandler;
 import org.apache.plc4x.java.spi.generation.ParseException;
 import org.apache.plc4x.java.spi.messages.*;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem;
 import org.apache.plc4x.java.spi.transaction.RequestTransactionManager;
 
 import java.time.Duration;
@@ -55,6 +56,11 @@ public class ModbusTcpProtocolLogic extends ModbusProtocolLogic<ModbusTcpADU> im
         this.tm = new RequestTransactionManager(1);
     }
 
+    @Override
+    public PlcTagHandler getTagHandler() {
+        return new ModbusTagHandler();
+    }
+
     @Override
     public void close(ConversationContext<ModbusTcpADU> context) {
         tm.shutdown();
@@ -77,7 +83,7 @@ public class ModbusTcpProtocolLogic extends ModbusProtocolLogic<ModbusTcpADU> im
         ModbusTcpADU modbusTcpADU = new ModbusTcpADU(transactionIdentifier, unitId, readRequestPdu);
 
         RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
-        transaction.submit(() -> context.sendRequest(modbusTcpADU)
+        transaction.submit(() -> conversationContext.sendRequest(modbusTcpADU)
             .expectResponse(ModbusTcpADU.class, requestTimeout)
             .onTimeout(future::completeExceptionally)
             .onError((p, e) -> future.completeExceptionally(e))
@@ -120,7 +126,7 @@ public class ModbusTcpProtocolLogic extends ModbusProtocolLogic<ModbusTcpADU> im
             }
             ModbusTcpADU modbusTcpADU = new ModbusTcpADU(transactionIdentifier, unitId, requestPdu);
             RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
-            transaction.submit(() -> context.sendRequest(modbusTcpADU)
+            transaction.submit(() -> conversationContext.sendRequest(modbusTcpADU)
                 .expectResponse(ModbusTcpADU.class, requestTimeout)
                 .onTimeout(future::completeExceptionally)
                 .onError((p, e) -> future.completeExceptionally(e))
@@ -151,7 +157,7 @@ public class ModbusTcpProtocolLogic extends ModbusProtocolLogic<ModbusTcpADU> im
 
                     // Prepare the response.
                     PlcReadResponse response = new DefaultPlcReadResponse(request,
-                        Collections.singletonMap(tagName, new ResponseItem<>(responseCode, plcValue)));
+                        Collections.singletonMap(tagName, new DefaultPlcResponseItem<>(responseCode, plcValue)));
 
                     // Pass the response back to the application.
                     future.complete(response);
@@ -190,7 +196,7 @@ public class ModbusTcpProtocolLogic extends ModbusProtocolLogic<ModbusTcpADU> im
             }
             ModbusTcpADU modbusTcpADU = new ModbusTcpADU(transactionIdentifier, unitId, requestPdu);
             RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
-            transaction.submit(() -> context.sendRequest(modbusTcpADU)
+            transaction.submit(() -> conversationContext.sendRequest(modbusTcpADU)
                 .expectResponse(ModbusTcpADU.class, requestTimeout)
                 .onTimeout(future::completeExceptionally)
                 .onError((p, e) -> future.completeExceptionally(e))
diff --git a/plc4j/drivers/modbus/src/test/java/org/apache/plc4x/java/modbus/ModbusEncodeTest.java b/plc4j/drivers/modbus/src/test/java/org/apache/plc4x/java/modbus/ModbusEncodeTest.java
index a88d37e3ec..8e6426ccec 100644
--- a/plc4j/drivers/modbus/src/test/java/org/apache/plc4x/java/modbus/ModbusEncodeTest.java
+++ b/plc4j/drivers/modbus/src/test/java/org/apache/plc4x/java/modbus/ModbusEncodeTest.java
@@ -21,7 +21,7 @@ package org.apache.plc4x.java.modbus;
 import org.apache.plc4x.java.api.value.PlcValue;
 import org.apache.plc4x.java.modbus.base.tag.ModbusTagCoil;
 import org.apache.plc4x.java.modbus.base.tag.ModbusTagHoldingRegister;
-import org.apache.plc4x.java.spi.values.PlcValueHandler;
+import org.apache.plc4x.java.spi.values.DefaultPlcValueHandler;
 import org.apache.plc4x.java.spi.values.PlcList;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
@@ -32,143 +32,143 @@ public class ModbusEncodeTest {
     @Test
     public void testEncodeBooleanBOOL() {
         Boolean[] object = {true,false,true,false,true,false,true,true,false};
-        ModbusTagCoil coils = ModbusTagCoil.of("coil:8:BOOL");
-        PlcList list = (PlcList) PlcValueHandler.of(coils, object);
+        ModbusTagCoil coils = ModbusTagCoil.of("coil:8:BOOL[9]");
+        PlcList list = (PlcList) new DefaultPlcValueHandler().newPlcValue(coils, object);
         Assertions.assertEquals("[true,false,true,false,true,false,true,true,false]", list.toString());
     }
 
     @Test
     public void testEncodeIntegerSINT() {
         Integer[] object = {1,-1,127,-128,5,6,7,8};
-        ModbusTagHoldingRegister holdingregister = ModbusTagHoldingRegister.of("holding-register:8:SINT{unit-id: 10}");
-        Assertions.assertEquals((short) 10, holdingregister.getUnitId());
-        PlcList list = (PlcList) PlcValueHandler.of(holdingregister, object);
+        ModbusTagHoldingRegister holdingRegister = ModbusTagHoldingRegister.of("holding-register:8:SINT[8]{unit-id: 10}");
+        Assertions.assertEquals((short) 10, holdingRegister.getUnitId());
+        PlcList list = (PlcList) new DefaultPlcValueHandler().newPlcValue(holdingRegister, object);
         Assertions.assertEquals("[1,-1,127,-128,5,6,7,8]", list.toString());
     }
 
     @Test
     public void testEncodeIntegerUSINT() {
         Integer[] object = {1,255,0,4,5,6,7,8};
-        ModbusTagHoldingRegister holdingregister = ModbusTagHoldingRegister.of("holding-register:8:USINT");
-        PlcList list = (PlcList) PlcValueHandler.of(holdingregister, object);
+        ModbusTagHoldingRegister holdingRegister = ModbusTagHoldingRegister.of("holding-register:8:USINT[8]");
+        PlcList list = (PlcList) new DefaultPlcValueHandler().newPlcValue(holdingRegister, object);
         Assertions.assertEquals("[1,255,0,4,5,6,7,8]", list.toString());
     }
 
     @Test
     public void testEncodeIntegerBYTE() {
         Integer[] object = {1,255,0,4,5,6,7,8};
-        ModbusTagHoldingRegister holdingregister = ModbusTagHoldingRegister.of("holding-register:8:BYTE");
-        PlcList list = (PlcList) PlcValueHandler.of(holdingregister, object);
+        ModbusTagHoldingRegister holdingRegister = ModbusTagHoldingRegister.of("holding-register:8:BYTE[8]");
+        PlcList list = (PlcList) new DefaultPlcValueHandler().newPlcValue(holdingRegister, object);
         Assertions.assertEquals("[1,255,0,4,5,6,7,8]", list.toString());
     }
 
     @Test
     public void testEncodeIntegerINT() {
         Integer[] object = {1,-1,32000,-32000,5,6,7};
-        ModbusTagHoldingRegister holdingregister = ModbusTagHoldingRegister.of("holding-register:7:INT");
-        PlcList list = (PlcList) PlcValueHandler.of(holdingregister, object);
+        ModbusTagHoldingRegister holdingRegister = ModbusTagHoldingRegister.of("holding-register:7:INT[7]");
+        PlcList list = (PlcList) new DefaultPlcValueHandler().newPlcValue(holdingRegister, object);
         Assertions.assertEquals("[1,-1,32000,-32000,5,6,7]", list.toString());
     }
 
     @Test
     public void testEncodeIntegerUINT() {
         Integer[] object = {1,65535,10,55000,5,6,7};
-        ModbusTagHoldingRegister holdingregister = ModbusTagHoldingRegister.of("holding-register:7:UINT");
-        PlcList list = (PlcList) PlcValueHandler.of(holdingregister, object);
+        ModbusTagHoldingRegister holdingRegister = ModbusTagHoldingRegister.of("holding-register:7:UINT[7]");
+        PlcList list = (PlcList) new DefaultPlcValueHandler().newPlcValue(holdingRegister, object);
         Assertions.assertEquals("[1,65535,10,55000,5,6,7]", list.toString());
     }
 
     @Test
     public void testEncodeIntegerWORD() {
         Integer[] object = {1,65535,10,55000,5,6,7};
-        ModbusTagHoldingRegister holdingregister = ModbusTagHoldingRegister.of("holding-register:7:WORD");
-        PlcList list = (PlcList) PlcValueHandler.of(holdingregister, object);
+        ModbusTagHoldingRegister holdingRegister = ModbusTagHoldingRegister.of("holding-register:7:WORD[7]");
+        PlcList list = (PlcList) new DefaultPlcValueHandler().newPlcValue(holdingRegister, object);
         Assertions.assertEquals("[1,65535,10,55000,5,6,7]", list.toString());
     }
 
     @Test
     public void testEncodeIntegerDINT() {
         Integer[] object = {1,655354775,-2147483648,2147483647,5,6,7};
-        ModbusTagHoldingRegister holdingregister = ModbusTagHoldingRegister.of("holding-register:7:DINT");
-        PlcList list = (PlcList) PlcValueHandler.of(holdingregister, object);
+        ModbusTagHoldingRegister holdingRegister = ModbusTagHoldingRegister.of("holding-register:7:DINT[7]");
+        PlcList list = (PlcList) new DefaultPlcValueHandler().newPlcValue(holdingRegister, object);
         Assertions.assertEquals("[1,655354775,-2147483648,2147483647,5,6,7]", list.toString());
     }
 
     @Test
     public void testEncodeLongUDINT() {
         Long[] object = {1L,655354775L,0L,4294967295L,5L,6L,7L};
-        ModbusTagHoldingRegister holdingregister = ModbusTagHoldingRegister.of("holding-register:7:UDINT");
-        PlcList list = (PlcList) PlcValueHandler.of(holdingregister, object);
+        ModbusTagHoldingRegister holdingRegister = ModbusTagHoldingRegister.of("holding-register:7:UDINT[7]");
+        PlcList list = (PlcList) new DefaultPlcValueHandler().newPlcValue(holdingRegister, object);
         Assertions.assertEquals("[1,655354775,0,4294967295,5,6,7]", list.toString());
     }
 
     @Test
     public void testEncodeLongDWORD() {
         Long[] object = {1L,655354775L,0L,4294967295L,5L,6L,7L};
-        ModbusTagHoldingRegister holdingregister = ModbusTagHoldingRegister.of("holding-register:7:DWORD");
-        PlcList list = (PlcList) PlcValueHandler.of(holdingregister, object);
+        ModbusTagHoldingRegister holdingRegister = ModbusTagHoldingRegister.of("holding-register:7:DWORD[7]");
+        PlcList list = (PlcList) new DefaultPlcValueHandler().newPlcValue(holdingRegister, object);
         Assertions.assertEquals("[1,655354775,0,4294967295,5,6,7]", list.toString());
     }
 
     @Test
     public void testEncodeLongLINT() {
         Long[] object = {1L,655354775L,-9223372036854775808L,9223372036854775807L,5L,6L,7L};
-        ModbusTagHoldingRegister holdingregister = ModbusTagHoldingRegister.of("holding-register:7:LINT");
-        PlcList list = (PlcList) PlcValueHandler.of(holdingregister, object);
+        ModbusTagHoldingRegister holdingRegister = ModbusTagHoldingRegister.of("holding-register:7:LINT[7]");
+        PlcList list = (PlcList) new DefaultPlcValueHandler().newPlcValue(holdingRegister, object);
         Assertions.assertEquals("[1,655354775,-9223372036854775808,9223372036854775807,5,6,7]", list.toString());
     }
 
     @Test
     public void testEncodeBigIntegerULINT() {
         BigInteger[] object = {BigInteger.valueOf(1L),BigInteger.valueOf(655354775L),BigInteger.valueOf(0),new BigInteger("18446744073709551615"),BigInteger.valueOf(5L),BigInteger.valueOf(6L),BigInteger.valueOf(7L)};
-        ModbusTagHoldingRegister holdingregister = ModbusTagHoldingRegister.of("holding-register:7:ULINT");
-        PlcList list = (PlcList) PlcValueHandler.of(holdingregister, object);
+        ModbusTagHoldingRegister holdingRegister = ModbusTagHoldingRegister.of("holding-register:7:ULINT[7]");
+        PlcList list = (PlcList) new DefaultPlcValueHandler().newPlcValue(holdingRegister, object);
         Assertions.assertEquals("[1,655354775,0,18446744073709551615,5,6,7]", list.toString());
     }
 
     @Test
     public void testEncodeBigIntegerLWORD() {
         BigInteger[] object = {BigInteger.valueOf(1L),BigInteger.valueOf(655354775L),BigInteger.valueOf(0),new BigInteger("18446744073709551615"),BigInteger.valueOf(5L),BigInteger.valueOf(6L),BigInteger.valueOf(7L)};
-        ModbusTagHoldingRegister holdingregister = ModbusTagHoldingRegister.of("holding-register:7:LWORD");
-        PlcList list = (PlcList) PlcValueHandler.of(holdingregister, object);
+        ModbusTagHoldingRegister holdingRegister = ModbusTagHoldingRegister.of("holding-register:7:LWORD[7]");
+        PlcList list = (PlcList) new DefaultPlcValueHandler().newPlcValue(holdingRegister, object);
         Assertions.assertEquals("[1,655354775,0,18446744073709551615,5,6,7]", list.toString());
     }
 
     @Test
     public void testEncodeFloatREAL() {
         Float[] object = {1.1f,1000.1f,100000.1f,3.4028232E38f,-3.4028232E38f,-1f,10384759934840.0f};
-        ModbusTagHoldingRegister holdingregister = ModbusTagHoldingRegister.of("holding-register:7:REAL");
-        PlcList list = (PlcList) PlcValueHandler.of(holdingregister, object);
+        ModbusTagHoldingRegister holdingRegister = ModbusTagHoldingRegister.of("holding-register:7:REAL[7]");
+        PlcList list = (PlcList) new DefaultPlcValueHandler().newPlcValue(holdingRegister, object);
         //! When using Java 19 it seems the toString method uses a different precision than the previous versions,
         //! so we need to check differently in this case.
         for (int i = 0; i < list.getLength(); i++) {
             PlcValue plcValue = list.getIndex(i);
             Float referenceValue = object[i];
-            Assertions.assertEquals(referenceValue, plcValue.getFloat());
+            Assertions.assertEquals(referenceValue, plcValue.getFloat(), 0.001);
         }
     }
 
     @Test
     public void testEncodeDoubleLREAL() {
         Double[] object = {1.1,1000.1,100000.1,1.7E308,-1.7E308,-1d,10384759934840.0};
-        ModbusTagHoldingRegister holdingregister = ModbusTagHoldingRegister.of("holding-register:7:LREAL");
-        PlcList list = (PlcList) PlcValueHandler.of(holdingregister, object);
+        ModbusTagHoldingRegister holdingRegister = ModbusTagHoldingRegister.of("holding-register:7:LREAL[7]");
+        PlcList list = (PlcList) new DefaultPlcValueHandler().newPlcValue(holdingRegister, object);
         Assertions.assertEquals("[1.1,1000.1,100000.1,1.7E308,-1.7E308,-1.0,1.038475993484E13]", list.toString());
     }
 
     /*@Test
     public void testEncodeStringSTRING() {
         String[] object = {"Hello Toddy!"};
-        ModbusTagHoldingRegister holdingregister = ModbusTagHoldingRegister.of("holding-register:8:STRING");
-        PlcList list = (PlcList) handler.encodeString(holdingregister, object);
+        ModbusTagHoldingRegister holdingRegister = ModbusTagHoldingRegister.of("holding-register:8:STRING");
+        PlcList list = (PlcList) handler.encodeString(holdingRegister, object);
         Assertions.assertEquals("[H,e,l,l,o, ,T,o,d,d,y,!]", list.toString());
     }
 
     @Test
     public void testEncodeStringWSTRING() {
         String[] object = {"Hello Toddy!"};
-        ModbusTagHoldingRegister holdingregister = ModbusTagdHoldingRegister.of("holding-register:8:WSTRING");
-        PlcList list = (PlcList) handler.encodeString(holdingregister, object);
+        ModbusTagHoldingRegister holdingRegister = ModbusTagdHoldingRegister.of("holding-register:8:WSTRING");
+        PlcList list = (PlcList) handler.encodeString(holdingRegister, object);
         Assertions.assertEquals("[H,e,l,l,o, ,T,o,d,d,y,!]", list.toString());
     } */
 }
diff --git a/plc4j/drivers/modbus/src/test/java/org/apache/plc4x/java/modbus/ModbusTagTest.java b/plc4j/drivers/modbus/src/test/java/org/apache/plc4x/java/modbus/ModbusTagTest.java
index 746922b215..bf94f28591 100644
--- a/plc4j/drivers/modbus/src/test/java/org/apache/plc4x/java/modbus/ModbusTagTest.java
+++ b/plc4j/drivers/modbus/src/test/java/org/apache/plc4x/java/modbus/ModbusTagTest.java
@@ -39,7 +39,7 @@ class ModbusTagTest {
                                  int allowedMax,
                                  Class<? extends ModbusTag> expectedClass,
                                  int expectedAddressShift) {
-        // Ensure all tagpatterns compile to the right tag
+        // Ensure all tag patterns compile to the right tag
         for (int i = 1; i <= allowedMax; i++) {
             List<ModbusTag> tags = new ArrayList<>();
             for (String tagPattern : tagPatterns) {
diff --git a/plc4j/drivers/modbus/src/test/java/org/apache/plc4x/java/modbus/base/optimizer/LittleEndianByteSwapTest.java b/plc4j/drivers/modbus/src/test/java/org/apache/plc4x/java/modbus/base/optimizer/LittleEndianByteSwapTest.java
index de936093e6..cad8651633 100644
--- a/plc4j/drivers/modbus/src/test/java/org/apache/plc4x/java/modbus/base/optimizer/LittleEndianByteSwapTest.java
+++ b/plc4j/drivers/modbus/src/test/java/org/apache/plc4x/java/modbus/base/optimizer/LittleEndianByteSwapTest.java
@@ -33,7 +33,7 @@ import org.apache.plc4x.java.spi.connection.PlcTagHandler;
 import org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest;
 import org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse;
 import org.apache.plc4x.java.spi.messages.PlcReader;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem;
 import org.apache.plc4x.java.spi.optimizer.BaseOptimizer;
 import org.apache.plc4x.java.spi.values.PlcRawByteArray;
 import org.junit.jupiter.api.Assertions;
@@ -248,13 +248,13 @@ public class LittleEndianByteSwapTest {
         Map<PlcReadRequest, BaseOptimizer.SubResponse<PlcReadResponse>> readResponses = new HashMap<>();
         readResponses.put(firstRequest, new BaseOptimizer.SubResponse<>(
             new DefaultPlcReadResponse(firstRequest, Map.of(
-                "coils0", new ResponseItem<>(PlcResponseCode.OK, new PlcRawByteArray(Hex.decodeHex("3060480c00c084000000000000000000000000000000")))))));
+                "coils0", new DefaultPlcResponseItem<>(PlcResponseCode.OK, new PlcRawByteArray(Hex.decodeHex("3060480c00c084000000000000000000000000000000")))))));
         readResponses.put(secondRequest, new BaseOptimizer.SubResponse<>(
             new DefaultPlcReadResponse(secondRequest, Map.of(
-                "registers0", new ResponseItem<>(PlcResponseCode.OK, new PlcRawByteArray(Hex.decodeHex("134141b000000000f80146c3000000003852c31f000000000b7841ae00000000fc0046e000000000028fc31f00000000c50441ab00000000540046dd00000000c000c31e000000006e973f32000000009998420300000000a5e33c9b00000000ccd041fc00000000020c3f2f00000000c3f9409e0000000047ae3f39000000009fbe3f3a00000000fbe83ff900000000d70a3aa30000000033333e33000000008f5c412400000000b83143d4000000005c293f5700000000c28f3f0500000000ac09 [...]
+                "registers0", new DefaultPlcResponseItem<>(PlcResponseCode.OK, new PlcRawByteArray(Hex.decodeHex("134141b000000000f80146c3000000003852c31f000000000b7841ae00000000fc0046e000000000028fc31f00000000c50441ab00000000540046dd00000000c000c31e000000006e973f32000000009998420300000000a5e33c9b00000000ccd041fc00000000020c3f2f00000000c3f9409e0000000047ae3f39000000009fbe3f3a00000000fbe83ff900000000d70a3aa30000000033333e33000000008f5c412400000000b83143d4000000005c293f5700000000c28f3f0500 [...]
         readResponses.put(thirdRequest, new BaseOptimizer.SubResponse<>(
             new DefaultPlcReadResponse(thirdRequest, Map.of(
-                "registers1", new ResponseItem<>(PlcResponseCode.OK, new PlcRawByteArray(Hex.decodeHex("a75cbc11000000007620bc26000000002f833f3c0000000086593f38000000005c293f0f0000000013aabc50000000003ffbbc8700000000da513f3b00000000c7113f3a0000000051ec3f3800000000a75cbc11000000007620bca60000000016873ed900000000ebee3ec000000000000000000000000044e5bc3b")))))));
+                "registers1", new DefaultPlcResponseItem<>(PlcResponseCode.OK, new PlcRawByteArray(Hex.decodeHex("a75cbc11000000007620bc26000000002f833f3c0000000086593f38000000005c293f0f0000000013aabc50000000003ffbbc8700000000da513f3b00000000c7113f3a0000000051ec3f3800000000a75cbc11000000007620bca60000000016873ed900000000ebee3ec000000000000000000000000044e5bc3b")))))));
 
         ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
         // Process the responses
diff --git a/plc4j/drivers/modbus/src/test/java/org/apache/plc4x/java/modbus/base/optimizer/ModbusOptimizerTest.java b/plc4j/drivers/modbus/src/test/java/org/apache/plc4x/java/modbus/base/optimizer/ModbusOptimizerTest.java
index 5c8eadf391..be18764f70 100644
--- a/plc4j/drivers/modbus/src/test/java/org/apache/plc4x/java/modbus/base/optimizer/ModbusOptimizerTest.java
+++ b/plc4j/drivers/modbus/src/test/java/org/apache/plc4x/java/modbus/base/optimizer/ModbusOptimizerTest.java
@@ -28,6 +28,8 @@ import org.apache.plc4x.java.modbus.readwrite.ModbusDataType;
 import org.apache.plc4x.java.modbus.types.ModbusByteOrder;
 import org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest;
 import org.apache.plc4x.java.spi.messages.PlcReader;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcTagItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcTagItem;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.MethodSource;
@@ -225,10 +227,10 @@ class ModbusOptimizerTest {
         Mockito.when(driverContext.getByteOrder()).thenReturn(ModbusByteOrder.BIG_ENDIAN);
         Mockito.when(driverContext.getMaxCoilsPerRequest()).thenReturn(2000);
         Mockito.when(driverContext.getMaxRegistersPerRequest()).thenReturn(125);
-        LinkedHashMap<String, PlcTag> tagMap = new LinkedHashMap<>();
+        LinkedHashMap<String, PlcTagItem> tagMap = new LinkedHashMap<>();
         int i = 0;
         for (PlcTag tag : tags) {
-            tagMap.put("tag" + i++, tag);
+            tagMap.put("tag" + i++, new DefaultPlcTagItem(tag));
         }
         ModbusOptimizer sut = new ModbusOptimizer();
         List<PlcReadRequest> plcReadRequests = sut.processReadRequest(new DefaultPlcReadRequest(reader, tagMap), driverContext);
diff --git a/plc4j/drivers/modbus/src/test/resources/logback-test.xml b/plc4j/drivers/modbus/src/test/resources/logback-test.xml
index 2b9cea25dc..941f1546f8 100644
--- a/plc4j/drivers/modbus/src/test/resources/logback-test.xml
+++ b/plc4j/drivers/modbus/src/test/resources/logback-test.xml
@@ -29,7 +29,7 @@
     </encoder>
   </appender>
 
-  <root level="error">
+  <root level="warn">
     <appender-ref ref="STDOUT" />
   </root>
 
diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/OpcuaPlcDriver.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/OpcuaPlcDriver.java
index 6d083cfb69..f430497d03 100644
--- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/OpcuaPlcDriver.java
+++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/OpcuaPlcDriver.java
@@ -25,11 +25,11 @@ import org.apache.plc4x.java.opcua.context.OpcuaDriverContext;
 import org.apache.plc4x.java.opcua.optimizer.OpcuaOptimizer;
 import org.apache.plc4x.java.opcua.protocol.OpcuaProtocolLogic;
 import org.apache.plc4x.java.opcua.readwrite.OpcuaAPU;
-import org.apache.plc4x.java.opcua.tag.OpcuaPlcTagHandler;
 import org.apache.plc4x.java.opcua.tag.OpcuaTag;
 import org.apache.plc4x.java.spi.connection.GeneratedDriverBase;
 import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer;
 import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer;
+import org.apache.plc4x.java.spi.values.LegacyPlcValueHandler;
 import org.apache.plc4x.java.spi.values.PlcValueHandler;
 
 import java.util.Collections;
@@ -64,6 +64,11 @@ public class OpcuaPlcDriver extends GeneratedDriverBase<OpcuaAPU> {
         return Collections.singletonList("tcp");
     }
 
+    @Override
+    protected PlcValueHandler getValueHandler() {
+        return new LegacyPlcValueHandler();
+    }
+
     @Override
     protected boolean canRead() {
         return true;
@@ -84,16 +89,6 @@ public class OpcuaPlcDriver extends GeneratedDriverBase<OpcuaAPU> {
         return new OpcuaOptimizer();
     }
 
-    @Override
-    protected OpcuaPlcTagHandler getTagHandler() {
-        return new OpcuaPlcTagHandler();
-    }
-
-    @Override
-    protected org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() {
-        return new PlcValueHandler();
-    }
-
     @Override
     protected boolean fireDiscoverEvent() {
         return true;
diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/optimizer/OpcuaOptimizer.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/optimizer/OpcuaOptimizer.java
index 5daec530e7..7b61baddaf 100644
--- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/optimizer/OpcuaOptimizer.java
+++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/optimizer/OpcuaOptimizer.java
@@ -19,11 +19,11 @@
 package org.apache.plc4x.java.opcua.optimizer;
 
 import org.apache.plc4x.java.api.messages.PlcReadRequest;
-import org.apache.plc4x.java.api.messages.PlcRequest;
-import org.apache.plc4x.java.api.model.PlcTag;
 import org.apache.plc4x.java.opcua.tag.OpcuaTag;
 import org.apache.plc4x.java.spi.context.DriverContext;
 import org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcTagItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcTagItem;
 import org.apache.plc4x.java.spi.optimizer.BaseOptimizer;
 
 import java.util.LinkedHashMap;
@@ -37,11 +37,11 @@ public class OpcuaOptimizer extends BaseOptimizer{
         List<PlcReadRequest> processedRequests = new LinkedList<>();
 
         // List of all items in the current request.
-        LinkedHashMap<String, PlcTag> curTags = new LinkedHashMap<>();
+        LinkedHashMap<String, PlcTagItem> curTags = new LinkedHashMap<>();
 
         for (String tagName : readRequest.getTagNames()) {
             OpcuaTag tag = (OpcuaTag) readRequest.getTag(tagName);
-            curTags.put(tagName, tag);
+            curTags.put(tagName, new DefaultPlcTagItem(tag));
         }
 
         // Create a new PlcReadRequest from the remaining tag items.
diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogic.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogic.java
index ced558a4c2..91112aef60 100644
--- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogic.java
+++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaProtocolLogic.java
@@ -28,6 +28,7 @@ import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
 import org.apache.plc4x.java.api.messages.*;
 import org.apache.plc4x.java.api.model.PlcConsumerRegistration;
 import org.apache.plc4x.java.api.model.PlcSubscriptionHandle;
+import org.apache.plc4x.java.api.model.PlcTag;
 import org.apache.plc4x.java.api.types.PlcResponseCode;
 import org.apache.plc4x.java.api.types.PlcValueType;
 import org.apache.plc4x.java.api.value.PlcValue;
@@ -36,19 +37,22 @@ import org.apache.plc4x.java.opcua.context.Conversation;
 import org.apache.plc4x.java.opcua.context.OpcuaDriverContext;
 import org.apache.plc4x.java.opcua.context.SecureChannel;
 import org.apache.plc4x.java.opcua.readwrite.*;
+import org.apache.plc4x.java.opcua.tag.OpcuaPlcTagHandler;
 import org.apache.plc4x.java.opcua.tag.OpcuaTag;
 import org.apache.plc4x.java.spi.ConversationContext;
 import org.apache.plc4x.java.spi.Plc4xProtocolBase;
 import org.apache.plc4x.java.spi.configuration.HasConfiguration;
+import org.apache.plc4x.java.spi.connection.PlcTagHandler;
 import org.apache.plc4x.java.spi.context.DriverContext;
 import org.apache.plc4x.java.spi.messages.*;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem;
 import org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration;
 import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionTag;
 import org.apache.plc4x.java.spi.transaction.RequestTransactionManager;
 import org.apache.plc4x.java.spi.transaction.RequestTransactionManager.RequestTransaction;
+import org.apache.plc4x.java.spi.values.LegacyPlcValueHandler;
 import org.apache.plc4x.java.spi.values.PlcList;
-import org.apache.plc4x.java.spi.values.PlcValueHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -91,6 +95,11 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
         this.configuration = configuration;
     }
 
+    @Override
+    public PlcTagHandler getTagHandler() {
+        return new OpcuaPlcTagHandler();
+    }
+
     @Override
     public void close(ConversationContext<OpcuaAPU> context) {
         tm.shutdown();
@@ -201,9 +210,12 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
 
         List<ExtensionObjectDefinition> readValueArray = new ArrayList<>(request.getTagNames().size());
         Iterator<String> iterator = request.getTagNames().iterator();
+        Map<String, PlcTag> tagMap = new HashMap<>();
         for (int i = 0; i < request.getTagNames().size(); i++) {
             String tagName = iterator.next();
+            // TODO: We need to check that the tag-return-code is OK as it could also be INVALID_TAG
             OpcuaTag tag = (OpcuaTag) request.getTag(tagName);
+            tagMap.put(tagName, tag);
 
             NodeId nodeId = generateNodeId(tag);
 
@@ -225,7 +237,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
         transaction.submit(() -> {
             conversation.submit(opcuaReadRequest, ReadResponse.class).whenComplete((response, error) -> bridge(transaction, future, response, error));
         });
-        return future.thenApply(response -> new DefaultPlcReadResponse(request, readResponse(request.getTagNames(), response.getResults())));
+        return future.thenApply(response -> new DefaultPlcReadResponse(request, readResponse(request.getTagNames(), tagMap, response.getResults())));
     }
 
     static NodeId generateNodeId(OpcuaTag tag) {
@@ -250,11 +262,12 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
         return nodeId;
     }
 
-    public Map<String, ResponseItem<PlcValue>> readResponse(LinkedHashSet<String> tagNames, List<DataValue> results) {
+    public Map<String, PlcResponseItem<PlcValue>> readResponse(LinkedHashSet<String> tagNames, Map<String, PlcTag> tagMap, List<DataValue> results) {
         PlcResponseCode responseCode = null; // initialize variable
-        Map<String, ResponseItem<PlcValue>> response = new HashMap<>();
+        Map<String, PlcResponseItem<PlcValue>> response = new HashMap<>();
         int count = 0;
         for (String tagName : tagNames) {
+            PlcTag tag = tagMap.get(tagName);
             PlcValue value = null;
             if (results.get(count).getValueSpecified()) {
                 Variant variant = results.get(count).getValue();
@@ -266,44 +279,44 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
                     for (int i = 0; i < length; i++) {
                         tmpValue[i] = array[i] != 0;
                     }
-                    value = PlcValueHandler.of(tmpValue);
+                    value = LegacyPlcValueHandler.of(tmpValue);
                 } else if (variant instanceof VariantSByte) {
                     byte[] array = ((VariantSByte) variant).getValue();
-                    value = PlcValueHandler.of(array);
+                    value = LegacyPlcValueHandler.of(tag, array);
                 } else if (variant instanceof VariantByte) {
                     List<Short> array = ((VariantByte) variant).getValue();
                     Short[] tmpValue = array.toArray(new Short[0]);
-                    value = PlcValueHandler.of(tmpValue);
+                    value = LegacyPlcValueHandler.of(tmpValue);
                 } else if (variant instanceof VariantInt16) {
                     List<Short> array = ((VariantInt16) variant).getValue();
                     Short[] tmpValue = array.toArray(new Short[0]);
-                    value = PlcValueHandler.of(tmpValue);
+                    value = LegacyPlcValueHandler.of(tmpValue);
                 } else if (variant instanceof VariantUInt16) {
                     List<Integer> array = ((VariantUInt16) variant).getValue();
                     Integer[] tmpValue = array.toArray(new Integer[0]);
-                    value = PlcValueHandler.of(tmpValue);
+                    value = LegacyPlcValueHandler.of(tmpValue);
                 } else if (variant instanceof VariantInt32) {
                     List<Integer> array = ((VariantInt32) variant).getValue();
                     Integer[] tmpValue = array.toArray(new Integer[0]);
-                    value = PlcValueHandler.of(tmpValue);
+                    value = LegacyPlcValueHandler.of(tmpValue);
                 } else if (variant instanceof VariantUInt32) {
                     List<Long> array = ((VariantUInt32) variant).getValue();
                     Long[] tmpValue = array.toArray(new Long[0]);
-                    value = PlcValueHandler.of(tmpValue);
+                    value = LegacyPlcValueHandler.of(tmpValue);
                 } else if (variant instanceof VariantInt64) {
                     List<Long> array = ((VariantInt64) variant).getValue();
                     Long[] tmpValue = array.toArray(new Long[0]);
-                    value = PlcValueHandler.of(tmpValue);
+                    value = LegacyPlcValueHandler.of(tmpValue);
                 } else if (variant instanceof VariantUInt64) {
-                    value = PlcValueHandler.of(((VariantUInt64) variant).getValue());
+                    value = LegacyPlcValueHandler.of(((VariantUInt64) variant).getValue());
                 } else if (variant instanceof VariantFloat) {
                     List<Float> array = ((VariantFloat) variant).getValue();
                     Float[] tmpValue = array.toArray(new Float[0]);
-                    value = PlcValueHandler.of(tmpValue);
+                    value = LegacyPlcValueHandler.of(tmpValue);
                 } else if (variant instanceof VariantDouble) {
                     List<Double> array = ((VariantDouble) variant).getValue();
                     Double[] tmpValue = array.toArray(new Double[0]);
-                    value = PlcValueHandler.of(tmpValue);
+                    value = LegacyPlcValueHandler.of(tmpValue);
                 } else if (variant instanceof VariantString) {
                     int length = ((VariantString) variant).getValue().size();
                     List<PascalString> stringArray = ((VariantString) variant).getValue();
@@ -311,7 +324,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
                     for (int i = 0; i < length; i++) {
                         tmpValue[i] = stringArray.get(i).getStringValue();
                     }
-                    value = PlcValueHandler.of(tmpValue);
+                    value = LegacyPlcValueHandler.of(tmpValue);
                 } else if (variant instanceof VariantDateTime) {
                     List<Long> array = ((VariantDateTime) variant).getValue();
                     int length = array.size();
@@ -319,7 +332,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
                     for (int i = 0; i < length; i++) {
                         tmpValue[i] = LocalDateTime.ofInstant(Instant.ofEpochMilli(getDateTime(array.get(i))), ZoneOffset.UTC);
                     }
-                    value = PlcValueHandler.of(tmpValue);
+                    value = LegacyPlcValueHandler.of(tmpValue);
                 } else if (variant instanceof VariantGuid) {
                     List<GuidValue> array = ((VariantGuid) variant).getValue();
                     int length = array.size();
@@ -338,7 +351,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
                         }
                         tmpValue[i] = Long.toHexString(array.get(i).getData1()) + "-" + Integer.toHexString(array.get(i).getData2()) + "-" + Integer.toHexString(array.get(i).getData3()) + "-" + Integer.toHexString(data4) + "-" + Long.toHexString(data5);
                     }
-                    value = PlcValueHandler.of(tmpValue);
+                    value = LegacyPlcValueHandler.of(tmpValue);
                 } else if (variant instanceof VariantXmlElement) {
                     int length = ((VariantXmlElement) variant).getValue().size();
                     List<PascalString> strings = ((VariantXmlElement) variant).getValue();
@@ -346,7 +359,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
                     for (int i = 0; i < length; i++) {
                         tmpValue[i] = strings.get(i).getStringValue();
                     }
-                    value = PlcValueHandler.of(tmpValue);
+                    value = LegacyPlcValueHandler.of(tmpValue);
                 } else if (variant instanceof VariantLocalizedText) {
                     int length = ((VariantLocalizedText) variant).getValue().size();
                     List<LocalizedText> strings = ((VariantLocalizedText) variant).getValue();
@@ -356,7 +369,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
                         tmpValue[i] += strings.get(i).getLocaleSpecified() ? strings.get(i).getLocale().getStringValue() + "|" : "";
                         tmpValue[i] += strings.get(i).getTextSpecified() ? strings.get(i).getText().getStringValue() : "";
                     }
-                    value = PlcValueHandler.of(tmpValue);
+                    value = LegacyPlcValueHandler.of(tmpValue);
                 } else if (variant instanceof VariantQualifiedName) {
                     int length = ((VariantQualifiedName) variant).getValue().size();
                     List<QualifiedName> strings = ((VariantQualifiedName) variant).getValue();
@@ -364,7 +377,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
                     for (int i = 0; i < length; i++) {
                         tmpValue[i] = "ns=" + strings.get(i).getNamespaceIndex() + ";s=" + strings.get(i).getName().getStringValue();
                     }
-                    value = PlcValueHandler.of(tmpValue);
+                    value = LegacyPlcValueHandler.of(tmpValue);
                 } else if (variant instanceof VariantExtensionObject) {
                     int length = ((VariantExtensionObject) variant).getValue().size();
                     List<ExtensionObject> strings = ((VariantExtensionObject) variant).getValue();
@@ -372,7 +385,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
                     for (int i = 0; i < length; i++) {
                         tmpValue[i] = strings.get(i).toString();
                     }
-                    value = PlcValueHandler.of(tmpValue);
+                    value = LegacyPlcValueHandler.of(tmpValue);
                 } else if (variant instanceof VariantNodeId) {
                     int length = ((VariantNodeId) variant).getValue().size();
                     List<NodeId> strings = ((VariantNodeId) variant).getValue();
@@ -380,7 +393,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
                     for (int i = 0; i < length; i++) {
                         tmpValue[i] = strings.get(i).toString();
                     }
-                    value = PlcValueHandler.of(tmpValue);
+                    value = LegacyPlcValueHandler.of(tmpValue);
                 } else if (variant instanceof VariantStatusCode) {
                     int length = ((VariantStatusCode) variant).getValue().size();
                     List<StatusCode> strings = ((VariantStatusCode) variant).getValue();
@@ -388,7 +401,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
                     for (int i = 0; i < length; i++) {
                         tmpValue[i] = strings.get(i).toString();
                     }
-                    value = PlcValueHandler.of(tmpValue);
+                    value = LegacyPlcValueHandler.of(tmpValue);
                 } else if (variant instanceof VariantByteString) {
                     PlcList plcList = new PlcList();
                     List<ByteStringArray> array = ((VariantByteString) variant).getValue();
@@ -398,7 +411,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
                         for (int i = 0; i < length; i++) {
                             tmpValue[i] = byteStringArray.getValue().get(i);
                         }
-                        plcList.add(PlcValueHandler.of(tmpValue));
+                        plcList.add(LegacyPlcValueHandler.of(tmpValue));
                     }
                     value = plcList;
                 } else {
@@ -415,7 +428,7 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
                 LOGGER.error("Error while reading value from OPC UA server error code: {}", results.get(count).getStatusCode().toString());
             }
             count++;
-            response.put(tagName, new ResponseItem<>(responseCode, value));
+            response.put(tagName, new DefaultPlcResponseItem<>(responseCode, value));
         }
         return response;
     }
@@ -779,13 +792,13 @@ public class OpcuaProtocolLogic extends Plc4xProtocolBase<OpcuaAPU> implements H
             })
             .thenCompose(handle -> handle.onSubscribeCreateMonitoredItemsRequest())
             .thenApply(handle -> {
-                Map<String, ResponseItem<PlcSubscriptionHandle>> values = new HashMap<>();
+                Map<String, PlcResponseItem<PlcSubscriptionHandle>> values = new HashMap<>();
                 for (String tagName : subscriptionRequest.getTagNames()) {
                     final DefaultPlcSubscriptionTag tagDefaultPlcSubscription = (DefaultPlcSubscriptionTag) subscriptionRequest.getTag(tagName);
                     if (!(tagDefaultPlcSubscription.getTag() instanceof OpcuaTag)) {
-                        values.put(tagName, new ResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null));
+                        values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null));
                     } else {
-                        values.put(tagName, new ResponseItem<>(PlcResponseCode.OK, handle));
+                        values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, handle));
                     }
                 }
 
diff --git a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaSubscriptionHandle.java b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaSubscriptionHandle.java
index a68a04fb4d..ab241b0411 100644
--- a/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaSubscriptionHandle.java
+++ b/plc4j/drivers/opcua/src/main/java/org/apache/plc4x/java/opcua/protocol/OpcuaSubscriptionHandle.java
@@ -27,12 +27,14 @@ import java.util.concurrent.TimeUnit;
 import org.apache.plc4x.java.api.messages.PlcSubscriptionEvent;
 import org.apache.plc4x.java.api.messages.PlcSubscriptionRequest;
 import org.apache.plc4x.java.api.model.PlcConsumerRegistration;
+import org.apache.plc4x.java.api.model.PlcTag;
 import org.apache.plc4x.java.api.value.PlcValue;
 import org.apache.plc4x.java.opcua.context.Conversation;
 import org.apache.plc4x.java.opcua.tag.OpcuaTag;
 import org.apache.plc4x.java.opcua.readwrite.*;
 import org.apache.plc4x.java.spi.messages.DefaultPlcSubscriptionEvent;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcTagItem;
 import org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration;
 import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionTag;
 import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionHandle;
@@ -260,11 +262,14 @@ public class OpcuaSubscriptionHandle extends DefaultPlcSubscriptionHandle {
     private void onSubscriptionValue(MonitoredItemNotification[] values) {
         LinkedHashSet<String> tagNameList = new LinkedHashSet<>();
         List<DataValue> dataValues = new ArrayList<>(values.length);
+        Map<String, PlcTag> tagMap = new LinkedHashMap<>();
         for (MonitoredItemNotification value : values) {
-            tagNameList.add(tagNames.get((int) value.getClientHandle() - 1));
+            String tagName = tagNames.get((int) value.getClientHandle() - 1);
+            tagNameList.add(tagName);
+            tagMap.put(tagName, subscriptionRequest.getTag(tagName).getTag());
             dataValues.add(value.getValue());
         }
-        Map<String, ResponseItem<PlcValue>> tags = plcSubscriber.readResponse(tagNameList, dataValues);
+        Map<String, PlcResponseItem<PlcValue>> tags = plcSubscriber.readResponse(tagNameList, tagMap, dataValues);
         final PlcSubscriptionEvent event = new DefaultPlcSubscriptionEvent(Instant.now(), tags);
 
         consumers.forEach(plcSubscriptionEventConsumer -> plcSubscriptionEventConsumer.accept(event));
diff --git a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/OpcuaPlcDriverTest.java b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/OpcuaPlcDriverTest.java
index 2de1ee473d..2bb0bd79ae 100644
--- a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/OpcuaPlcDriverTest.java
+++ b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/OpcuaPlcDriverTest.java
@@ -57,7 +57,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.math.BigInteger;
-import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.concurrent.ExecutionException;
@@ -65,9 +64,6 @@ import java.util.stream.Stream;
 import org.testcontainers.containers.BindMode;
 import org.testcontainers.containers.GenericContainer;
 import org.testcontainers.containers.output.Slf4jLogConsumer;
-import org.testcontainers.containers.wait.strategy.Wait;
-import org.testcontainers.images.builder.ImageFromDockerfile;
-import org.testcontainers.jib.JibImage;
 import org.testcontainers.junit.jupiter.Container;
 import org.testcontainers.junit.jupiter.Testcontainers;
 
@@ -82,7 +78,7 @@ public class OpcuaPlcDriverTest {
     private static final Logger LOGGER = LoggerFactory.getLogger(OpcuaPlcDriverTest.class);
 
     @Container
-    public static final GenericContainer milo = new MiloTestContainer()
+    public static final GenericContainer<MiloTestContainer> milo = new MiloTestContainer()
         //.withCreateContainerCmdModifier(cmd -> cmd.withHostName("test-opcua-server"))
         .withReuse(true)
         .withLogConsumer(new Slf4jLogConsumer(LOGGER))
@@ -139,17 +135,17 @@ public class OpcuaPlcDriverTest {
     public static final String STRING_IDENTIFIER_ONLY_ADMIN_READ_WRITE = "ns=2;s=HelloWorld/OnlyAdminCanRead/String";
 
     // Address of local milo server, since it comes from test container its hostname and port is not static
-    private final String miloLocalAddress = "%s:%d/milo";
+    private static final String miloLocalAddress = "%s:%d/milo";
     //Tcp pattern of OPC UA
-    private final String opcPattern = "opcua:tcp://";
+    private static final String opcPattern = "opcua:tcp://";
 
-    private final String paramSectionDivider = "?";
-    private final String paramDivider = "&";
+    private static final String paramSectionDivider = "?";
+    private static final String paramDivider = "&";
 
-    private final String discoveryValidParamTrue = "discovery=true";
-    private final String discoveryValidParamFalse = "discovery=false";
-    private final String discoveryCorruptedParamWrongValueNum = "discovery=1";
-    private final String discoveryCorruptedParamWrongName = "diskovery=false";
+    private static final String discoveryValidParamTrue = "discovery=true";
+    private static final String discoveryValidParamFalse = "discovery=false";
+    private static final String discoveryCorruptedParamWrongValueNum = "discovery=1";
+    private static final String discoveryCorruptedParamWrongName = "diskovery=false";
 
     private String tcpConnectionAddress;
     private List<String> connectionStringValidSet;
diff --git a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/chunk/ChunkFactoryTest.java b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/chunk/ChunkFactoryTest.java
index b97632b1a1..c59b80efb2 100644
--- a/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/chunk/ChunkFactoryTest.java
+++ b/plc4j/drivers/opcua/src/test/java/org/apache/plc4x/java/opcua/protocol/chunk/ChunkFactoryTest.java
@@ -32,10 +32,12 @@ import org.apache.plc4x.java.opcua.readwrite.OpcuaProtocolLimits;
 import org.apache.plc4x.java.opcua.security.SecurityPolicy;
 import org.apache.plc4x.test.DisableOnJenkinsFlag;
 import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.CsvFileSource;
 
 @DisableOnJenkinsFlag
+@Disabled("Disabled flaky test. Tracking issue at https://github.com/apache/plc4x/issues/1764")
 class ChunkFactoryTest {
 
     public static final Map<Integer, Entry<PrivateKey, X509Certificate>> CERTIFICATES = new HashMap<>();
diff --git a/plc4j/drivers/opcua/src/test/resources/logback-test.xml b/plc4j/drivers/opcua/src/test/resources/logback-test.xml
index adf03c9e8c..695109a532 100644
--- a/plc4j/drivers/opcua/src/test/resources/logback-test.xml
+++ b/plc4j/drivers/opcua/src/test/resources/logback-test.xml
@@ -27,7 +27,7 @@
     </encoder>
   </appender>
 
-  <root level="error">
+  <root level="warn">
     <appender-ref ref="STDOUT" />
   </root>
 
diff --git a/plc4j/drivers/open-protocol/src/main/java/org/apache/plc4x/java/openprotocol/OpenProtocolDriver.java b/plc4j/drivers/open-protocol/src/main/java/org/apache/plc4x/java/openprotocol/OpenProtocolDriver.java
index 6bdf9d6843..95a3d0027b 100644
--- a/plc4j/drivers/open-protocol/src/main/java/org/apache/plc4x/java/openprotocol/OpenProtocolDriver.java
+++ b/plc4j/drivers/open-protocol/src/main/java/org/apache/plc4x/java/openprotocol/OpenProtocolDriver.java
@@ -26,13 +26,11 @@ import org.apache.plc4x.java.openprotocol.config.OpenProtocolTcpTransportConfigu
 import org.apache.plc4x.java.openprotocol.protocol.OpenProtocolProtocolLogic;
 import org.apache.plc4x.java.openprotocol.readwrite.OpenProtocolMessage;
 import org.apache.plc4x.java.openprotocol.tag.OpenProtocolTag;
-import org.apache.plc4x.java.openprotocol.tag.OpenProtocolTagHandler;
 import org.apache.plc4x.java.spi.connection.GeneratedDriverBase;
 import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer;
 import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer;
 import org.apache.plc4x.java.spi.optimizer.BaseOptimizer;
 import org.apache.plc4x.java.spi.optimizer.SingleTagOptimizer;
-import org.apache.plc4x.java.spi.values.PlcValueHandler;
 
 import java.util.Collections;
 import java.util.List;
@@ -100,16 +98,6 @@ public class OpenProtocolDriver extends GeneratedDriverBase<OpenProtocolMessage>
         return new SingleTagOptimizer();
     }
 
-    @Override
-    protected OpenProtocolTagHandler getTagHandler() {
-        return new OpenProtocolTagHandler();
-    }
-
-    @Override
-    protected org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() {
-        return new PlcValueHandler();
-    }
-
     @Override
     protected ProtocolStackConfigurer<OpenProtocolMessage> getStackConfigurer() {
         return SingleProtocolStackConfigurer.builder(OpenProtocolMessage.class, io -> OpenProtocolMessage.staticParse(io, 1))
diff --git a/plc4j/drivers/open-protocol/src/main/java/org/apache/plc4x/java/openprotocol/protocol/OpenProtocolProtocolLogic.java b/plc4j/drivers/open-protocol/src/main/java/org/apache/plc4x/java/openprotocol/protocol/OpenProtocolProtocolLogic.java
index deafb87871..0a639c0935 100644
--- a/plc4j/drivers/open-protocol/src/main/java/org/apache/plc4x/java/openprotocol/protocol/OpenProtocolProtocolLogic.java
+++ b/plc4j/drivers/open-protocol/src/main/java/org/apache/plc4x/java/openprotocol/protocol/OpenProtocolProtocolLogic.java
@@ -22,8 +22,10 @@ import org.apache.plc4x.java.api.messages.*;
 import org.apache.plc4x.java.api.model.PlcConsumerRegistration;
 import org.apache.plc4x.java.api.model.PlcSubscriptionHandle;
 import org.apache.plc4x.java.openprotocol.readwrite.OpenProtocolMessage;
+import org.apache.plc4x.java.openprotocol.tag.OpenProtocolTagHandler;
 import org.apache.plc4x.java.spi.ConversationContext;
 import org.apache.plc4x.java.spi.Plc4xProtocolBase;
+import org.apache.plc4x.java.spi.connection.PlcTagHandler;
 import org.apache.plc4x.java.spi.messages.PlcSubscriber;
 import org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration;
 
@@ -33,6 +35,11 @@ import java.util.function.Consumer;
 
 public class OpenProtocolProtocolLogic extends Plc4xProtocolBase<OpenProtocolMessage> implements PlcSubscriber {
 
+    @Override
+    public PlcTagHandler getTagHandler() {
+        return new OpenProtocolTagHandler();
+    }
+
     @Override
     public void onConnect(ConversationContext<OpenProtocolMessage> context) {
     }
diff --git a/plc4j/drivers/open-protocol/src/test/resources/logback-test.xml b/plc4j/drivers/open-protocol/src/test/resources/logback-test.xml
index 2b9cea25dc..941f1546f8 100644
--- a/plc4j/drivers/open-protocol/src/test/resources/logback-test.xml
+++ b/plc4j/drivers/open-protocol/src/test/resources/logback-test.xml
@@ -29,7 +29,7 @@
     </encoder>
   </appender>
 
-  <root level="error">
+  <root level="warn">
     <appender-ref ref="STDOUT" />
   </root>
 
diff --git a/plc4j/drivers/plc4x/src/main/java/org/apache/plc4x/java/plc4x/Plc4xDriver.java b/plc4j/drivers/plc4x/src/main/java/org/apache/plc4x/java/plc4x/Plc4xDriver.java
index 93ea3b3f71..cb738d5339 100644
--- a/plc4j/drivers/plc4x/src/main/java/org/apache/plc4x/java/plc4x/Plc4xDriver.java
+++ b/plc4j/drivers/plc4x/src/main/java/org/apache/plc4x/java/plc4x/Plc4xDriver.java
@@ -23,14 +23,11 @@ import org.apache.plc4x.java.spi.configuration.PlcConnectionConfiguration;
 import org.apache.plc4x.java.spi.configuration.PlcTransportConfiguration;
 import org.apache.plc4x.java.plc4x.config.Plc4xConfiguration;
 import org.apache.plc4x.java.plc4x.config.Plc4xTcpTransportConfiguration;
-import org.apache.plc4x.java.plc4x.tag.Plc4XTagHandler;
 import org.apache.plc4x.java.plc4x.protocol.Plc4xProtocolLogic;
 import org.apache.plc4x.java.plc4x.readwrite.Plc4xMessage;
 import org.apache.plc4x.java.spi.connection.GeneratedDriverBase;
-import org.apache.plc4x.java.spi.connection.PlcTagHandler;
 import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer;
 import org.apache.plc4x.java.spi.connection.SingleProtocolStackConfigurer;
-import org.apache.plc4x.java.spi.values.PlcValueHandler;
 
 import java.util.Collections;
 import java.util.List;
@@ -74,16 +71,6 @@ public class Plc4xDriver extends GeneratedDriverBase<Plc4xMessage> {
         return Collections.singletonList("tcp");
     }
 
-    @Override
-    protected PlcTagHandler getTagHandler() {
-        return new Plc4XTagHandler();
-    }
-
-    @Override
-    protected org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() {
-        return new PlcValueHandler();
-    }
-
     /**
      * This protocol doesn't have a disconnect procedure, so there is no need to wait for a login to finish.
      * @return false
diff --git a/plc4j/drivers/plc4x/src/main/java/org/apache/plc4x/java/plc4x/protocol/Plc4xProtocolLogic.java b/plc4j/drivers/plc4x/src/main/java/org/apache/plc4x/java/plc4x/protocol/Plc4xProtocolLogic.java
index a40ef2810e..3d9288e1e4 100644
--- a/plc4j/drivers/plc4x/src/main/java/org/apache/plc4x/java/plc4x/protocol/Plc4xProtocolLogic.java
+++ b/plc4j/drivers/plc4x/src/main/java/org/apache/plc4x/java/plc4x/protocol/Plc4xProtocolLogic.java
@@ -23,13 +23,16 @@ import org.apache.plc4x.java.api.types.PlcResponseCode;
 import org.apache.plc4x.java.api.value.PlcValue;
 import org.apache.plc4x.java.plc4x.config.Plc4xConfiguration;
 import org.apache.plc4x.java.plc4x.readwrite.*;
+import org.apache.plc4x.java.plc4x.tag.Plc4XTagHandler;
 import org.apache.plc4x.java.plc4x.tag.Plc4xTag;
 import org.apache.plc4x.java.spi.ConversationContext;
 import org.apache.plc4x.java.spi.Plc4xProtocolBase;
 import org.apache.plc4x.java.spi.configuration.HasConfiguration;
+import org.apache.plc4x.java.spi.connection.PlcTagHandler;
 import org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse;
 import org.apache.plc4x.java.spi.messages.DefaultPlcWriteResponse;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem;
 import org.apache.plc4x.java.spi.transaction.RequestTransactionManager;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -60,6 +63,11 @@ public class Plc4xProtocolLogic extends Plc4xProtocolBase<Plc4xMessage> implemen
         this.connectionId = 0;
     }
 
+    @Override
+    public PlcTagHandler getTagHandler() {
+        return new Plc4XTagHandler();
+    }
+
     @Override
     public void close(ConversationContext<Plc4xMessage> context) {
         tm.shutdown();
@@ -109,20 +117,20 @@ public class Plc4xProtocolLogic extends Plc4xProtocolBase<Plc4xMessage> implemen
 
         // Send the request and await a response.
         RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
-        context.sendRequest(plc4xReadRequest)
+        conversationContext.sendRequest(plc4xReadRequest)
             .expectResponse(Plc4xMessage.class, requestTimeout)
             .onTimeout(future::completeExceptionally)
             .check(plc4xMessage -> plc4xMessage.getRequestId() == requestId)
             .only(Plc4xReadResponse.class)
             .check(plc4xReadResponse -> plc4xReadResponse.getConnectionId() == connectionId)
             .handle(plc4xReadResponse -> {
-                Map<String, ResponseItem<PlcValue>> apiResponses = new HashMap<>();
+                Map<String, PlcResponseItem<PlcValue>> apiResponses = new HashMap<>();
                 // Create the API response from the incoming message.
                 for (Plc4xTagValueResponse plc4xTag : plc4xReadResponse.getTags()) {
                     final Plc4xResponseCode plc4xResponseCode = plc4xTag.getResponseCode();
                     final PlcResponseCode apiResponseCode = PlcResponseCode.valueOf(plc4xResponseCode.name());
                     apiResponses.put(plc4xTag.getTag().getName(),
-                        new ResponseItem<>(apiResponseCode, plc4xTag.getValue()));
+                        new DefaultPlcResponseItem<>(apiResponseCode, plc4xTag.getValue()));
                 }
 
                 // Send it back to the calling process.
@@ -153,7 +161,7 @@ public class Plc4xProtocolLogic extends Plc4xProtocolBase<Plc4xMessage> implemen
 
         // Send the request and await a response.
         RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
-        context.sendRequest(write)
+        conversationContext.sendRequest(write)
             .expectResponse(Plc4xMessage.class, requestTimeout)
             .onTimeout(future::completeExceptionally)
             .check(p -> p.getRequestId() == requestId)
diff --git a/plc4j/drivers/profinet-ng/src/main/java/org/apache/plc4x/java/profinet/ProfinetDriver.java b/plc4j/drivers/profinet-ng/src/main/java/org/apache/plc4x/java/profinet/ProfinetDriver.java
index adbd18f44c..34ff1380da 100644
--- a/plc4j/drivers/profinet-ng/src/main/java/org/apache/plc4x/java/profinet/ProfinetDriver.java
+++ b/plc4j/drivers/profinet-ng/src/main/java/org/apache/plc4x/java/profinet/ProfinetDriver.java
@@ -34,7 +34,6 @@ import org.apache.plc4x.java.profinet.discovery.ProfinetDiscoverer;
 import org.apache.plc4x.java.profinet.protocol.ProfinetProtocolLogic;
 import org.apache.plc4x.java.profinet.readwrite.*;
 import org.apache.plc4x.java.profinet.tag.ProfinetTag;
-import org.apache.plc4x.java.profinet.tag.ProfinetTagHandler;
 import org.apache.plc4x.java.spi.configuration.ConfigurationFactory;
 import org.apache.plc4x.java.spi.connection.GeneratedDriverBase;
 import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer;
@@ -166,16 +165,6 @@ public class ProfinetDriver extends GeneratedDriverBase<Ethernet_Frame> {
         return new SingleTagOptimizer();
     }
 
-    @Override
-    protected ProfinetTagHandler getTagHandler() {
-        return new ProfinetTagHandler();
-    }
-
-    @Override
-    protected  org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() {
-        return new org.apache.plc4x.java.spi.values.PlcValueHandler();
-    }
-
     @Override
     protected ProtocolStackConfigurer<Ethernet_Frame> getStackConfigurer() {
         return SingleProtocolStackConfigurer.builder(Ethernet_Frame.class, Ethernet_Frame::staticParse)
diff --git a/plc4j/drivers/profinet-ng/src/main/java/org/apache/plc4x/java/profinet/discovery/ProfinetDiscoverer.java b/plc4j/drivers/profinet-ng/src/main/java/org/apache/plc4x/java/profinet/discovery/ProfinetDiscoverer.java
index 3bf4ebad92..d81582c708 100644
--- a/plc4j/drivers/profinet-ng/src/main/java/org/apache/plc4x/java/profinet/discovery/ProfinetDiscoverer.java
+++ b/plc4j/drivers/profinet-ng/src/main/java/org/apache/plc4x/java/profinet/discovery/ProfinetDiscoverer.java
@@ -33,7 +33,7 @@ import org.apache.plc4x.java.spi.generation.WriteBufferByteBased;
 import org.apache.plc4x.java.spi.messages.DefaultPlcDiscoveryItem;
 import org.apache.plc4x.java.spi.messages.DefaultPlcDiscoveryResponse;
 import org.apache.plc4x.java.spi.messages.PlcDiscoverer;
-import org.apache.plc4x.java.spi.values.PlcValues;
+import org.apache.plc4x.java.spi.values.PlcSTRING;
 import org.apache.plc4x.java.transport.rawsocket.RawSocketTransport;
 import org.pcap4j.core.NotOpenException;
 import org.pcap4j.core.PcapHandle;
@@ -230,16 +230,16 @@ public class ProfinetDiscoverer implements PlcDiscoverer {
             }
 
             Map<String, PlcValue> attributes = new HashMap<>();
-            attributes.put("ipAddress", PlcValues.of(remoteAddress));
-            attributes.put("subnetMask", PlcValues.of(remoteSubnetMask));
-            attributes.put("macAddress", PlcValues.of(srcAddr.toString()));
-            attributes.put("localMacAddress", PlcValues.of(dstAddr.toString()));
-            attributes.put("deviceTypeName", PlcValues.of(deviceTypeName));
-            attributes.put("deviceName", PlcValues.of(deviceName));
-            attributes.put("vendorId", PlcValues.of(vendorId));
-            attributes.put("deviceId", PlcValues.of(deviceId));
-            attributes.put("role", PlcValues.of(role));
-            attributes.put("packetType", PlcValues.of("dcp"));
+            attributes.put("ipAddress", new PlcSTRING(remoteAddress));
+            attributes.put("subnetMask", new PlcSTRING(remoteSubnetMask));
+            attributes.put("macAddress", new PlcSTRING(srcAddr.toString()));
+            attributes.put("localMacAddress", new PlcSTRING(dstAddr.toString()));
+            attributes.put("deviceTypeName", new PlcSTRING(deviceTypeName));
+            attributes.put("deviceName", new PlcSTRING(deviceName));
+            attributes.put("vendorId", new PlcSTRING(vendorId));
+            attributes.put("deviceId", new PlcSTRING(deviceId));
+            attributes.put("role", new PlcSTRING(role));
+            attributes.put("packetType", new PlcSTRING("dcp"));
 
             String name = deviceTypeName + " - " + deviceName;
 
diff --git a/plc4j/drivers/profinet-ng/src/main/java/org/apache/plc4x/java/profinet/protocol/ProfinetProtocolLogic.java b/plc4j/drivers/profinet-ng/src/main/java/org/apache/plc4x/java/profinet/protocol/ProfinetProtocolLogic.java
index 49d8df00af..68f1c39353 100644
--- a/plc4j/drivers/profinet-ng/src/main/java/org/apache/plc4x/java/profinet/protocol/ProfinetProtocolLogic.java
+++ b/plc4j/drivers/profinet-ng/src/main/java/org/apache/plc4x/java/profinet/protocol/ProfinetProtocolLogic.java
@@ -33,10 +33,12 @@ import org.apache.plc4x.java.profinet.gsdml.*;
 import org.apache.plc4x.java.profinet.packets.PnDcpPacketFactory;
 import org.apache.plc4x.java.profinet.readwrite.*;
 import org.apache.plc4x.java.profinet.tag.ProfinetTag;
+import org.apache.plc4x.java.profinet.tag.ProfinetTagHandler;
 import org.apache.plc4x.java.profinet.utils.ProfinetDataTypeMapper;
 import org.apache.plc4x.java.spi.ConversationContext;
 import org.apache.plc4x.java.spi.Plc4xProtocolBase;
 import org.apache.plc4x.java.spi.configuration.HasConfiguration;
+import org.apache.plc4x.java.spi.connection.PlcTagHandler;
 import org.apache.plc4x.java.spi.context.DriverContext;
 import org.apache.plc4x.java.spi.messages.DefaultPlcBrowseItem;
 import org.apache.plc4x.java.spi.messages.DefaultPlcBrowseResponse;
@@ -78,6 +80,11 @@ public class ProfinetProtocolLogic extends Plc4xProtocolBase<Ethernet_Frame> imp
         this.configuration = configuration;
     }
 
+    @Override
+    public PlcTagHandler getTagHandler() {
+        return new ProfinetTagHandler();
+    }
+
     @Override
     public void onConnect(ConversationContext<Ethernet_Frame> context) {
         super.onConnect(context);
@@ -572,7 +579,7 @@ public class ProfinetProtocolLogic extends Plc4xProtocolBase<Ethernet_Frame> imp
             expectedSubmodules.add(new PnIoCm_Block_ExpectedSubmoduleReq((short) 1, (short) 0, Collections.singletonList(new PnIoCm_ExpectedSubmoduleBlockReqApi(slotNumber, 0x00000020, 0x0000, expectedSubmoduleData))));
         }
 
-        RawSocketChannel rawSocketChannel = (RawSocketChannel) context.getChannel();
+        RawSocketChannel rawSocketChannel = (RawSocketChannel) conversationContext.getChannel();
         MacAddress remoteMacAddress = new MacAddress(rawSocketChannel.getRemoteMacAddress().getAddress());
         InetSocketAddress remoteAddress = (InetSocketAddress) rawSocketChannel.getRemoteAddress();
         MacAddress localMacAddress = new MacAddress(rawSocketChannel.getLocalMacAddress().getAddress());
@@ -699,7 +706,7 @@ public class ProfinetProtocolLogic extends Plc4xProtocolBase<Ethernet_Frame> imp
             udpFrame);
 
         CompletableFuture<PlcSubscriptionResponse> future = new CompletableFuture<>();
-        context.sendRequest(requestEthernetFrame)
+        conversationContext.sendRequest(requestEthernetFrame)
             .name("Expect Subscription response")
             .expectResponse(Ethernet_Frame.class, Duration.ofMillis(1000))
             .onTimeout(future::completeExceptionally)
@@ -716,7 +723,7 @@ public class ProfinetProtocolLogic extends Plc4xProtocolBase<Ethernet_Frame> imp
                 // TODO: Maybe do some checks on this.
 
                 // Now we wait for an incoming ApplicationReady request and confirm that.
-                context.expectRequest(Ethernet_Frame.class, Duration.ofMillis(500000))
+                conversationContext.expectRequest(Ethernet_Frame.class, Duration.ofMillis(500000))
                     .name("Expect ApplicationReady request")
                     .onTimeout(future::completeExceptionally)
                     .check(ethernetFrame -> ethernetFrame.getPayload() instanceof Ethernet_FramePayload_IPv4)
@@ -732,8 +739,8 @@ public class ProfinetProtocolLogic extends Plc4xProtocolBase<Ethernet_Frame> imp
                         int sessionKey = pnIoCmBlock.getSessionKey();
 
                         // Send back a response, but this is just a hack ... we need to move this into the subscribe method, or we can't complete the future that we're returning.
-                        RawSocketChannel pnChannel = (RawSocketChannel) context.getChannel();
-                        PnDcpPacketFactory.sendApplicationReadyResponse(context, pnChannel, profinetDriverContext, payloadIPv4.getSourcePort(), dceRpc_packet.getActivityUuid(), arUuid, sessionKey);
+                        RawSocketChannel pnChannel = (RawSocketChannel) conversationContext.getChannel();
+                        PnDcpPacketFactory.sendApplicationReadyResponse(conversationContext, pnChannel, profinetDriverContext, payloadIPv4.getSourcePort(), dceRpc_packet.getActivityUuid(), arUuid, sessionKey);
 
                         connected = true;
                         // TODO: Prepare the subscription response.
@@ -741,7 +748,7 @@ public class ProfinetProtocolLogic extends Plc4xProtocolBase<Ethernet_Frame> imp
                     });
 
                 // Now send the ParameterEnd request and wait for a response.
-                CompletableFuture<PnIoCm_Control_Response_ParameterEnd> parameterEndFuture = PnDcpPacketFactory.sendParameterEndRequest(context, rawSocketChannel, profinetDriverContext);
+                CompletableFuture<PnIoCm_Control_Response_ParameterEnd> parameterEndFuture = PnDcpPacketFactory.sendParameterEndRequest(conversationContext, rawSocketChannel, profinetDriverContext);
                 parameterEndFuture.whenComplete((parameterEnd, throwable) -> {
                     // We needed to put the code to expect the ApplicationReady to subscribe before sending,
                     // as the device sends it within 4 ms, and we can't guarantee that we're done setting up
diff --git a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/ProfinetDriver.java b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/ProfinetDriver.java
index 60de10c6d0..f9e3b1f34d 100644
--- a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/ProfinetDriver.java
+++ b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/ProfinetDriver.java
@@ -30,7 +30,6 @@ import org.apache.plc4x.java.profinet.discovery.ProfinetPlcDiscoverer;
 import org.apache.plc4x.java.profinet.protocol.ProfinetProtocolLogic;
 import org.apache.plc4x.java.profinet.readwrite.Ethernet_Frame;
 import org.apache.plc4x.java.profinet.tag.ProfinetTag;
-import org.apache.plc4x.java.profinet.tag.ProfinetTagHandler;
 import org.apache.plc4x.java.spi.connection.GeneratedDriverBase;
 import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer;
 import org.apache.plc4x.java.spi.messages.DefaultPlcDiscoveryRequest;
@@ -135,16 +134,6 @@ public class ProfinetDriver extends GeneratedDriverBase<Ethernet_Frame> {
         return new SingleTagOptimizer();
     }
 
-    @Override
-    protected ProfinetTagHandler getTagHandler() {
-        return new ProfinetTagHandler();
-    }
-
-    @Override
-    protected  org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() {
-        return new org.apache.plc4x.java.spi.values.PlcValueHandler();
-    }
-
     @Override
     protected ProtocolStackConfigurer<Ethernet_Frame> getStackConfigurer() {
         return SingleProtocolStackConfigurer.builder(Ethernet_Frame.class, Ethernet_Frame::staticParse)
diff --git a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetDevice.java b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetDevice.java
index 4c000a3a27..59c470989f 100644
--- a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetDevice.java
+++ b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetDevice.java
@@ -35,7 +35,7 @@ import org.apache.plc4x.java.spi.generation.*;
 import org.apache.plc4x.java.spi.messages.DefaultPlcSubscriptionEvent;
 import org.apache.plc4x.java.spi.messages.DefaultPlcSubscriptionResponse;
 import org.apache.plc4x.java.spi.messages.PlcSubscriber;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem;
 import org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration;
 import org.apache.plc4x.java.spi.values.PlcSTRING;
 import org.slf4j.Logger;
@@ -145,7 +145,7 @@ public class ProfinetDevice implements PlcSubscriber {
     @Override
     public CompletableFuture<PlcSubscriptionResponse> subscribe(PlcSubscriptionRequest subscriptionRequest) {
         return CompletableFuture.supplyAsync(() -> {
-            Map<String, ResponseItem<PlcSubscriptionHandle>> values = new HashMap<>();
+            Map<String, PlcResponseItem<PlcSubscriptionHandle>> values = new HashMap<>();
 
             return new DefaultPlcSubscriptionResponse(subscriptionRequest, values);
         });
@@ -406,7 +406,7 @@ public class ProfinetDevice implements PlcSubscriber {
     }
 
     public void handleRealTimeResponse(PnDcp_Pdu_RealTimeCyclic cyclicPdu) {
-        Map<String, ResponseItem<PlcValue>> tags = new HashMap<>();
+        Map<String, PlcResponseItem<PlcValue>> tags = new HashMap<>();
         ReadBuffer buffer = new ReadBufferByteBased(cyclicPdu.getDataUnit().getData());
 
         if (firstMessage) {
@@ -419,8 +419,8 @@ public class ProfinetDevice implements PlcSubscriber {
                 module.parseTags(tags, deviceContext.getDeviceName(), buffer);
             }
 
-            Map<Consumer<PlcSubscriptionEvent>, Map<String, ResponseItem<PlcValue>>> response = new HashMap<>();
-            for (Map.Entry<String, ResponseItem<PlcValue>> entry : tags.entrySet()) {
+            Map<Consumer<PlcSubscriptionEvent>, Map<String, PlcResponseItem<PlcValue>>> response = new HashMap<>();
+            for (Map.Entry<String, PlcResponseItem<PlcValue>> entry : tags.entrySet()) {
                 boolean processTag = false;
                 ProfinetSubscriptionHandle handle = deviceContext.getSubscriptionHandle(entry.getKey());
                 if (handle != null) {
@@ -451,7 +451,7 @@ public class ProfinetDevice implements PlcSubscriber {
                 }
             }
 
-            for (Map.Entry<Consumer<PlcSubscriptionEvent>, Map<String, ResponseItem<PlcValue>>> entry : response.entrySet()) {
+            for (Map.Entry<Consumer<PlcSubscriptionEvent>, Map<String, PlcResponseItem<PlcValue>>> entry : response.entrySet()) {
                 entry.getKey().accept(new DefaultPlcSubscriptionEvent(Instant.now(), entry.getValue()));
             }
         } catch (ParseException e) {
diff --git a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetEmptyModule.java b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetEmptyModule.java
index a35fc29a94..be1cbce016 100644
--- a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetEmptyModule.java
+++ b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetEmptyModule.java
@@ -26,7 +26,7 @@ import org.apache.plc4x.java.profinet.readwrite.PnIoCm_IoDataObject;
 import org.apache.plc4x.java.profinet.readwrite.PnIoCm_Submodule;
 import org.apache.plc4x.java.spi.generation.ParseException;
 import org.apache.plc4x.java.spi.generation.ReadBuffer;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -96,7 +96,7 @@ public class ProfinetEmptyModule implements ProfinetModule{
     public void populateOutputCR(int ioPsOffset, int ioCsOffset) {    }
 
     @Override
-    public Map<String, ResponseItem<PlcValue>> parseTags(Map<String, ResponseItem<PlcValue>> tags, String addressSpace, ReadBuffer buffer) throws ParseException {
+    public Map<String, PlcResponseItem<PlcValue>> parseTags(Map<String, PlcResponseItem<PlcValue>> tags, String addressSpace, ReadBuffer buffer) throws ParseException {
         return tags;
     }
 
diff --git a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetModule.java b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetModule.java
index a7f81612c4..b7c7a1c6ea 100644
--- a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetModule.java
+++ b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetModule.java
@@ -21,15 +21,13 @@ package org.apache.plc4x.java.profinet.device;
 
 import org.apache.plc4x.java.api.messages.PlcBrowseItem;
 import org.apache.plc4x.java.api.value.PlcValue;
-import org.apache.plc4x.java.profinet.gsdml.ProfinetVirtualSubmoduleItem;
 import org.apache.plc4x.java.profinet.readwrite.PnIoCm_IoCs;
 import org.apache.plc4x.java.profinet.readwrite.PnIoCm_IoDataObject;
 import org.apache.plc4x.java.profinet.readwrite.PnIoCm_Submodule;
 import org.apache.plc4x.java.spi.generation.ParseException;
 import org.apache.plc4x.java.spi.generation.ReadBuffer;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem;
 
-import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
@@ -53,5 +51,5 @@ public interface ProfinetModule {
     int getOutputIoPsSize();
     void populateOutputCR(int ioPsOffset, int ioCsOffset);
 
-    Map<String, ResponseItem<PlcValue>> parseTags(Map<String, ResponseItem<PlcValue>> tags, String addressSpace, ReadBuffer buffer) throws ParseException;
+    Map<String, PlcResponseItem<PlcValue>> parseTags(Map<String, PlcResponseItem<PlcValue>> tags, String addressSpace, ReadBuffer buffer) throws ParseException;
 }
diff --git a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetModuleImpl.java b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetModuleImpl.java
index a1e8d2641b..63a6f8d431 100644
--- a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetModuleImpl.java
+++ b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetModuleImpl.java
@@ -28,8 +28,8 @@ import org.apache.plc4x.java.profinet.tag.ProfinetTag;
 import org.apache.plc4x.java.spi.generation.ParseException;
 import org.apache.plc4x.java.spi.generation.ReadBuffer;
 import org.apache.plc4x.java.spi.messages.DefaultPlcBrowseItem;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
-import org.apache.plc4x.java.spi.values.PlcSINT;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem;
 import org.apache.plc4x.java.spi.values.PlcSTRING;
 
 import java.util.*;
@@ -303,7 +303,7 @@ public class ProfinetModuleImpl implements ProfinetModule {
     }
 
     @Override
-    public Map<String, ResponseItem<PlcValue>> parseTags(Map<String, ResponseItem<PlcValue>> tags, String addressSpace, ReadBuffer buffer) throws ParseException {
+    public Map<String, PlcResponseItem<PlcValue>> parseTags(Map<String, PlcResponseItem<PlcValue>> tags, String addressSpace, ReadBuffer buffer) throws ParseException {
         for (PnIoCm_IoDataObject block : inputIoPsApiBlocks) {
             int identNumber = block.getSubSlotNumber();
             for (ProfinetVirtualSubmoduleItem virtual : module.getVirtualSubmoduleList()) {
@@ -314,31 +314,31 @@ public class ProfinetModuleImpl implements ProfinetModule {
                                 if (item.isUseAsBits()) {
                                     for (int i = 0; i < ProfinetDataType.firstEnumForFieldConversion(item.getDataType().toUpperCase()).getDataTypeSize() * 8; i++) {
                                         String tagName = addressSpace + "." + this.slot + "." + block.getSubSlotNumber() + "." + item.getTextId() + "." + i;
-                                        tags.put(tagName, new ResponseItem<>(PlcResponseCode.OK, DataItem.staticParse(buffer, ProfinetDataType.BOOL, 1)));
+                                        tags.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, DataItem.staticParse(buffer, ProfinetDataType.BOOL, 1)));
                                     }
                                 } else {
                                     String tagName = addressSpace + "." + this.slot + "." + block.getSubSlotNumber() + "." + item.getTextId();
                                     ProfinetDataType datatype = ProfinetDataType.firstEnumForFieldConversion(item.getDataType().toUpperCase());
-                                    tags.put(tagName, new ResponseItem<>(PlcResponseCode.OK, DataItem.staticParse(buffer, datatype, 1)));
+                                    tags.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, DataItem.staticParse(buffer, datatype, 1)));
                                 }
                             }
                         }
                     }
                     String statusName = addressSpace + "." + this.slot + "." + block.getSubSlotNumber() + "." + virtual.getId() + ".Status";
-                    tags.put(statusName, new ResponseItem<>(PlcResponseCode.OK, DataItem.staticParse(buffer, ProfinetDataType.SINT, 1)));
+                    tags.put(statusName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, DataItem.staticParse(buffer, ProfinetDataType.SINT, 1)));
                 }
             }
             if (module.getSystemDefinedSubmoduleList() != null) {
                 for (ProfinetInterfaceSubmoduleItem systemInterface : module.getSystemDefinedSubmoduleList().getInterfaceSubmodules()) {
                     if (identNumber == systemInterface.getSubslotNumber()) {
                         String statusName = addressSpace + "." + this.slot + "." + block.getSubSlotNumber() + "." + systemInterface.getId() + ".Status";
-                        tags.put(statusName, new ResponseItem<>(PlcResponseCode.OK, DataItem.staticParse(buffer, ProfinetDataType.SINT, 1)));
+                        tags.put(statusName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, DataItem.staticParse(buffer, ProfinetDataType.SINT, 1)));
                     }
                 }
                 for (ProfinetPortSubmoduleItem systemPort : module.getSystemDefinedSubmoduleList().getPortSubmodules()) {
                     if (identNumber == systemPort.getSubslotNumber()) {
                         String statusName = addressSpace + "." + this.slot + "." + block.getSubSlotNumber() + "." + systemPort.getId() + ".Status";
-                        tags.put(statusName, new ResponseItem<>(PlcResponseCode.OK, DataItem.staticParse(buffer, ProfinetDataType.SINT, 1)));
+                        tags.put(statusName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, DataItem.staticParse(buffer, ProfinetDataType.SINT, 1)));
                     }
                 }
             }
diff --git a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetSubscriptionHandle.java b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetSubscriptionHandle.java
index 8a5ddb8656..42127da5c5 100644
--- a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetSubscriptionHandle.java
+++ b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/device/ProfinetSubscriptionHandle.java
@@ -19,23 +19,11 @@
 
 package org.apache.plc4x.java.profinet.device;
 
-import org.apache.plc4x.java.api.messages.PlcSubscriptionEvent;
-import org.apache.plc4x.java.api.model.PlcConsumerRegistration;
 import org.apache.plc4x.java.api.model.PlcSubscriptionTag;
-import org.apache.plc4x.java.api.model.PlcTag;
 import org.apache.plc4x.java.api.types.PlcSubscriptionType;
 import org.apache.plc4x.java.api.value.PlcValue;
-import org.apache.plc4x.java.spi.messages.DefaultPlcSubscriptionEvent;
 import org.apache.plc4x.java.spi.messages.PlcSubscriber;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
-import org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration;
 import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionHandle;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.time.Instant;
-import java.util.*;
-import java.util.function.Consumer;
 
 public class ProfinetSubscriptionHandle extends DefaultPlcSubscriptionHandle {
 
diff --git a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/protocol/ProfinetProtocolLogic.java b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/protocol/ProfinetProtocolLogic.java
index 95beb4f774..50ea805d11 100644
--- a/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/protocol/ProfinetProtocolLogic.java
+++ b/plc4j/drivers/profinet/src/main/java/org/apache/plc4x/java/profinet/protocol/ProfinetProtocolLogic.java
@@ -32,11 +32,14 @@ import org.apache.plc4x.java.profinet.device.*;
 import org.apache.plc4x.java.profinet.discovery.ProfinetPlcDiscoverer;
 import org.apache.plc4x.java.profinet.readwrite.*;
 import org.apache.plc4x.java.profinet.tag.ProfinetTag;
+import org.apache.plc4x.java.profinet.tag.ProfinetTagHandler;
 import org.apache.plc4x.java.spi.ConversationContext;
 import org.apache.plc4x.java.spi.Plc4xProtocolBase;
 import org.apache.plc4x.java.spi.configuration.HasConfiguration;
+import org.apache.plc4x.java.spi.connection.PlcTagHandler;
 import org.apache.plc4x.java.spi.messages.*;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem;
 import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionTag;
 import org.apache.plc4x.java.utils.rawsockets.netty.RawSocketChannel;
 import org.pcap4j.core.*;
@@ -92,8 +95,8 @@ public class ProfinetProtocolLogic extends Plc4xProtocolBase<Ethernet_Frame> imp
     }
 
     @Override
-    public void setContext(ConversationContext<Ethernet_Frame> context) {
-        super.setContext(context);
+    public void setConversationContext(ConversationContext<Ethernet_Frame> conversationContext) {
+        super.setConversationContext(conversationContext);
 
         // Open the receiving UDP port and keep it open.
         try {
@@ -105,10 +108,15 @@ public class ProfinetProtocolLogic extends Plc4xProtocolBase<Ethernet_Frame> imp
         profinetDriverContext.getHandler().setConfiguredDevices(devices);
 
         for (Map.Entry<String, ProfinetDevice> device : devices.entrySet()) {
-            device.getValue().setContext(context, this.profinetDriverContext.getChannel());
+            device.getValue().setContext(conversationContext, this.profinetDriverContext.getChannel());
         }
     }
 
+    @Override
+    public PlcTagHandler getTagHandler() {
+        return new ProfinetTagHandler();
+    }
+
     /**
      * Start a PN or LLDP discovery to find PN devices on the network.
      * We pass in a driverContext handler, that checks if an incoming response has the information needed for
@@ -238,7 +246,7 @@ public class ProfinetProtocolLogic extends Plc4xProtocolBase<Ethernet_Frame> imp
     @Override
     public CompletableFuture<PlcSubscriptionResponse> subscribe(PlcSubscriptionRequest subscriptionRequest) {
         return CompletableFuture.supplyAsync(() -> {
-            Map<String, ResponseItem<PlcSubscriptionHandle>> values = new HashMap<>();
+            Map<String, PlcResponseItem<PlcSubscriptionHandle>> values = new HashMap<>();
 
             for (String fieldName : subscriptionRequest.getTagNames()) {
                 PlcSubscriptionTag tag = subscriptionRequest.getTag(fieldName);
@@ -250,9 +258,9 @@ public class ProfinetProtocolLogic extends Plc4xProtocolBase<Ethernet_Frame> imp
                 device.getDeviceContext().addSubscriptionHandle(fieldDefaultPlcSubscription.getAddressString(), subscriptionHandle);
 
                 if (!(fieldDefaultPlcSubscription.getTag() instanceof ProfinetTag)) {
-                    values.put(fieldName, new ResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null));
+                    values.put(fieldName, new DefaultPlcResponseItem<>(PlcResponseCode.INVALID_ADDRESS, null));
                 } else {
-                    values.put(fieldName, new ResponseItem<>(PlcResponseCode.OK, subscriptionHandle));
+                    values.put(fieldName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, subscriptionHandle));
                 }
             }
             return new DefaultPlcSubscriptionResponse(subscriptionRequest, values);
diff --git a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/events/S7CyclicEvent.java b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/events/S7CyclicEvent.java
index f65076e994..6b7c83d3bf 100644
--- a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/events/S7CyclicEvent.java
+++ b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/events/S7CyclicEvent.java
@@ -42,7 +42,7 @@ import java.util.stream.IntStream;
 import org.apache.plc4x.java.s7.readwrite.tag.S7SubscriptionTag;
 import org.apache.plc4x.java.s7.readwrite.tag.S7Tag;
 import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionTag;
-import org.apache.plc4x.java.spi.values.PlcValueHandler;
+import org.apache.plc4x.java.spi.values.DefaultPlcValueHandler;
 
 public class S7CyclicEvent implements S7Event {
 
@@ -77,7 +77,7 @@ public class S7CyclicEvent implements S7Event {
             int i = n[0];
             map.put(Fields.RETURNCODE_.name() + i, event.getItems().get(i).getReturnCode().getValue());
             map.put(Fields.TRANSPORTSIZE_.name() + i, event.getItems().get(i).getTransportSize().getValue());
-            map.put(tagname, DataToPlcValue(tagname, request, event.getItems().get(i).getData()));
+            map.put(tagname, dataToPlcValue(tagname, request, event.getItems().get(i).getData()));
             n[0]++;                                    
         });
 
@@ -97,7 +97,7 @@ public class S7CyclicEvent implements S7Event {
             int i = n[0];
             map.put(Fields.RETURNCODE_.name() + i, event.getItems().get(i).getReturnCode().getValue());
             map.put(Fields.TRANSPORTSIZE_.name() + i, event.getItems().get(i).getTransportSize().getValue());
-            map.put(tagname, DataToPlcValue(tagname, request, event.getItems().get(i).getData()));
+            map.put(tagname, dataToPlcValue(tagname, request, event.getItems().get(i).getData()));
             n[0]++;                                    
         });
         
@@ -117,7 +117,7 @@ public class S7CyclicEvent implements S7Event {
             int i = n[0];
             map.put(Fields.RETURNCODE_.name() + i, event.getItems().get(i).getReturnCode().getValue());
             map.put(Fields.TRANSPORTSIZE_.name() + i, event.getItems().get(i).getTransportSize().getValue());
-            map.put(tagname, DataToPlcValue(tagname, request, event.getItems().get(i).getData()));
+            map.put(tagname, dataToPlcValue(tagname, request, event.getItems().get(i).getData()));
             n[0]++;                                    
         });       
     }
@@ -136,7 +136,7 @@ public class S7CyclicEvent implements S7Event {
             int i = n[0];
             map.put(Fields.RETURNCODE_.name() + i, event.getItems().get(i).getReturnCode().getValue());
             map.put(Fields.TRANSPORTSIZE_.name() + i, event.getItems().get(i).getTransportSize().getValue());
-            map.put(tagname, DataToPlcValue(tagname, request, event.getItems().get(i).getData()));
+            map.put(tagname, dataToPlcValue(tagname, request, event.getItems().get(i).getData()));
             n[0]++;                                    
         });       
     }
@@ -744,7 +744,7 @@ public class S7CyclicEvent implements S7Event {
     }
     
         
-    private static PlcValue DataToPlcValue(String tagname, PlcSubscriptionRequest request, List<Short> data){
+    private static PlcValue dataToPlcValue(String tagname, PlcSubscriptionRequest request, List<Short> data){
         
         int[] i = new int[1];
         
@@ -770,7 +770,7 @@ public class S7CyclicEvent implements S7Event {
                 for (int iter = 0; iter < s7Tags[0].getNumberOfElements(); iter++) {
                     bools[iter] = bb.readBoolean();
                 }
-                plcValue = PlcValueHandler.of(bools);
+                plcValue = DefaultPlcValueHandler.of(s7Tags[0], bools);
                 break;
             case BYTE:
                 // TODO: This looks suspicious
@@ -778,7 +778,7 @@ public class S7CyclicEvent implements S7Event {
                 for (Byte b:bytes) {
                     b = Byte.valueOf(bb.readByte());
                 }
-                plcValue = PlcValueHandler.of(bytes);
+                plcValue = DefaultPlcValueHandler.of(s7Tags[0], bytes);
                 break;
             case WORD:
                 break;  
@@ -791,7 +791,7 @@ public class S7CyclicEvent implements S7Event {
                 for (int iter = 0; iter < s7Tags[0].getNumberOfElements(); iter ++) {
                     shorts[iter] = bb.readShort();
                 }
-                plcValue = PlcValueHandler.of(shorts);
+                plcValue = DefaultPlcValueHandler.of(s7Tags[0], shorts);
                 break;
             case UINT:
                 break;    
@@ -805,7 +805,7 @@ public class S7CyclicEvent implements S7Event {
                 for (Integer di:integers) {
                     di = Integer.valueOf(bb.readInt());
                 }
-                plcValue = PlcValueHandler.of(integers);
+                plcValue = DefaultPlcValueHandler.of(s7Tags[0], integers);
                 break;
             case UDINT:
                 break;    
@@ -815,7 +815,7 @@ public class S7CyclicEvent implements S7Event {
                 for (Long l:longs) {
                     l = bb.readLong();
                 }
-                plcValue = PlcValueHandler.of(longs);
+                plcValue = DefaultPlcValueHandler.of(s7Tags[0], longs);
                 break;
             case ULINT:
                 break;  
@@ -825,7 +825,7 @@ public class S7CyclicEvent implements S7Event {
                 for (Float f:floats) {
                     f = bb.readFloat();
                 }
-                plcValue = PlcValueHandler.of(floats);
+                plcValue = DefaultPlcValueHandler.of(s7Tags[0], floats);
                 break;
             case LREAL:
                 // TODO: This looks suspicious
@@ -833,7 +833,7 @@ public class S7CyclicEvent implements S7Event {
                 for (Double d:doubles) {
                     d = bb.readDouble();
                 }
-                plcValue = PlcValueHandler.of(doubles);
+                plcValue = DefaultPlcValueHandler.of(s7Tags[0], doubles);
                 break;
             case CHAR:
                 break;   
diff --git a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/S7Driver.java b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/S7Driver.java
index 047aabc647..f814cd3a49 100644
--- a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/S7Driver.java
+++ b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/S7Driver.java
@@ -29,12 +29,10 @@ import org.apache.plc4x.java.s7.readwrite.optimizer.S7Optimizer;
 import org.apache.plc4x.java.s7.readwrite.protocol.S7HGeneratedDriverBase;
 import org.apache.plc4x.java.s7.readwrite.protocol.S7HSingleProtocolStackConfigurer;
 import org.apache.plc4x.java.s7.readwrite.protocol.S7ProtocolLogic;
-import org.apache.plc4x.java.s7.readwrite.tag.S7PlcTagHandler;
 import org.apache.plc4x.java.s7.readwrite.tag.S7Tag;
 import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer;
 import org.apache.plc4x.java.spi.messages.DefaultPlcDiscoveryRequest;
 import org.apache.plc4x.java.spi.optimizer.BaseOptimizer;
-import org.apache.plc4x.java.spi.values.PlcValueHandler;
 import org.pcap4j.core.PcapNativeException;
 import org.pcap4j.core.Pcaps;
 
@@ -99,16 +97,6 @@ public class S7Driver extends S7HGeneratedDriverBase {
         return new S7Optimizer();
     }
 
-    @Override
-    protected S7PlcTagHandler getTagHandler() {
-        return new S7PlcTagHandler();
-    }
-
-    @Override
-    protected org.apache.plc4x.java.api.value.PlcValueHandler getValueHandler() {
-        return new PlcValueHandler();
-    }
-
     @Override
     public PlcDiscoveryRequest.Builder discoveryRequestBuilder() {
         // TODO: This should actually happen in the execute method of the discoveryRequest and not here ...
diff --git a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/connection/S7HMuxImpl.java b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/connection/S7HMuxImpl.java
index 122ce4b309..83703f2ab2 100644
--- a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/connection/S7HMuxImpl.java
+++ b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/connection/S7HMuxImpl.java
@@ -102,11 +102,11 @@ public class S7HMuxImpl extends MessageToMessageCodec<ByteBuf, ByteBuf> implemen
      */
     public final static AttributeKey<Integer> RETRY_TIME = AttributeKey.valueOf("RETRY_TIME");
 
-    ChannelHandlerContext embed_ctx = null;
-    protected Channel embeded_channel = null;
-    protected Channel tcp_channel = null;
-    protected Channel primary_channel = null;
-    protected Channel secondary_channel = null;
+    ChannelHandlerContext embedCtx = null;
+    protected Channel embededChannel = null;
+    protected Channel tcpChannel = null;
+    protected Channel primaryChannel = null;
+    protected Channel secondaryChannel = null;
 
     /*
      * From S7ProtocolLogic
@@ -114,13 +114,15 @@ public class S7HMuxImpl extends MessageToMessageCodec<ByteBuf, ByteBuf> implemen
      * the Embedded channel when we created it.
      */
     @Override
-    protected void encode(ChannelHandlerContext ctx, ByteBuf outbb, List<Object> list) throws Exception {
-        logger.debug("ENCODE: " + outbb.toString());
-        if ((embed_ctx == null) && (ctx.channel() instanceof EmbeddedChannel)) embed_ctx = ctx;
-        if ((tcp_channel != null) && (embed_ctx == ctx)) {
-            tcp_channel.writeAndFlush(outbb.copy());
+    protected void encode(ChannelHandlerContext ctx, ByteBuf outBB, List<Object> list) {
+        logger.debug("ENCODE: {}", outBB.toString());
+        if ((embedCtx == null) && (ctx.channel() instanceof EmbeddedChannel)) {
+            embedCtx = ctx;
+        }
+        if ((tcpChannel != null) && (embedCtx == ctx)) {
+            tcpChannel.writeAndFlush(outBB.copy());
         } else {
-            list.add(outbb.copy());
+            list.add(outBB.copy());
         }
     }
 
@@ -131,7 +133,7 @@ public class S7HMuxImpl extends MessageToMessageCodec<ByteBuf, ByteBuf> implemen
      */
     @Override
     protected void decode(ChannelHandlerContext ctx, ByteBuf inbb, List<Object> list) throws Exception {
-        embed_ctx.fireChannelRead(inbb.copy());
+        embedCtx.fireChannelRead(inbb.copy());
     }
 
     @Override
@@ -165,16 +167,16 @@ public class S7HMuxImpl extends MessageToMessageCodec<ByteBuf, ByteBuf> implemen
         logger.info("{}  userEventTriggered: {} Event: {}", LocalTime.now(), ctx.name(), evt);
         if (evt instanceof ConnectEvent) {
             try {
-                tcp_channel.pipeline().remove("watchdog");
+                tcpChannel.pipeline().remove("watchdog");
             } catch (Exception ex) {
                 logger.info(ex.toString());
             }
             try {
-                tcp_channel.pipeline().addFirst("watchdog", new ReadTimeoutHandler(30));
-                if (tcp_channel.isActive()) {
-                    embeded_channel.attr(IS_CONNECTED).set(true);
+                tcpChannel.pipeline().addFirst("watchdog", new ReadTimeoutHandler(30));
+                if (tcpChannel.isActive()) {
+                    embededChannel.attr(IS_CONNECTED).set(true);
                 } else {
-                    embeded_channel.attr(IS_CONNECTED).set(false);
+                    embededChannel.attr(IS_CONNECTED).set(false);
                 }
             } catch (Exception ex) {
                 logger.info(ex.toString());
@@ -209,39 +211,39 @@ public class S7HMuxImpl extends MessageToMessageCodec<ByteBuf, ByteBuf> implemen
     public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
         super.channelUnregistered(ctx);
         logger.debug("{} channelUnregistered: {}", LocalTime.now(), ctx.name());
-        String strCanal = (tcp_channel == primary_channel) ? "PRIMARY" : "SECONDARY";
-        logger.debug("Unregistered of channel: " + strCanal);
+        String strCanal = (tcpChannel == primaryChannel) ? "PRIMARY" : "SECONDARY";
+        logger.debug("Unregistered of channel: {}", strCanal);
         //TODO: If embedded channel is closed, we need close all channels
-        if (ctx == embed_ctx) return;
+        if (ctx == embedCtx) return;
 
-        if (tcp_channel == ctx.channel())
-            embeded_channel.attr(IS_CONNECTED).set(false);
+        if (tcpChannel == ctx.channel())
+            embededChannel.attr(IS_CONNECTED).set(false);
 
-        logger.info(embed_ctx.executor().toString());
+        logger.info(embedCtx.executor().toString());
 
-        if ((tcp_channel == primary_channel) &&
-            (primary_channel == ctx.channel()))
-            if ((!primary_channel.isActive()) &&
-                (secondary_channel != null)) {
-                if (secondary_channel.isActive())
-                    synchronized (tcp_channel) {
+        if ((tcpChannel == primaryChannel) &&
+            (primaryChannel == ctx.channel()))
+            if ((!primaryChannel.isActive()) &&
+                (secondaryChannel != null)) {
+                if (secondaryChannel.isActive())
+                    synchronized (tcpChannel) {
                         logger.info("Using secondary TCP channel.");
-                        tcp_channel = secondary_channel;
-                        embeded_channel.attr(IS_PRIMARY).set(false);
-                        embeded_channel.pipeline().fireUserEventTriggered(new ConnectEvent());
+                        tcpChannel = secondaryChannel;
+                        embededChannel.attr(IS_PRIMARY).set(false);
+                        embededChannel.pipeline().fireUserEventTriggered(new ConnectEvent());
                     }
             }
 
 
-        if ((tcp_channel == secondary_channel) &&
-            (secondary_channel == ctx.channel()))
-            if ((!secondary_channel.isActive() &&
-                (primary_channel.isActive()))) {
-                synchronized (tcp_channel) {
+        if ((tcpChannel == secondaryChannel) &&
+            (secondaryChannel == ctx.channel()))
+            if ((!secondaryChannel.isActive() &&
+                (primaryChannel.isActive()))) {
+                synchronized (tcpChannel) {
                     logger.info("Using primary TCP channel.");
-                    tcp_channel = primary_channel;
-                    embeded_channel.attr(IS_PRIMARY).set(true);
-                    embeded_channel.pipeline().fireUserEventTriggered(new ConnectEvent());
+                    tcpChannel = primaryChannel;
+                    embededChannel.attr(IS_PRIMARY).set(true);
+                    embededChannel.pipeline().fireUserEventTriggered(new ConnectEvent());
                 }
             }
     }
@@ -249,32 +251,32 @@ public class S7HMuxImpl extends MessageToMessageCodec<ByteBuf, ByteBuf> implemen
 
     @Override
     public void setEmbeddedChannel(Channel embeded_channel) {
-        this.embeded_channel = embeded_channel;
-        this.embeded_channel.attr(IS_CONNECTED).set(false);
-        this.embeded_channel.attr(IS_PRIMARY).set(true);
-        this.embeded_channel.attr(READ_TIME_OUT).set(8);
-        this.embeded_channel.attr(IS_PING_ACTIVE).set(false);
-        this.embeded_channel.attr(PING_TIME).set(-1);
-        this.embeded_channel.attr(RETRY_TIME).set(8);
+        this.embededChannel = embeded_channel;
+        this.embededChannel.attr(IS_CONNECTED).set(false);
+        this.embededChannel.attr(IS_PRIMARY).set(true);
+        this.embededChannel.attr(READ_TIME_OUT).set(8);
+        this.embededChannel.attr(IS_PING_ACTIVE).set(false);
+        this.embededChannel.attr(PING_TIME).set(-1);
+        this.embededChannel.attr(RETRY_TIME).set(8);
     }
 
     public void setPrimaryChannel(Channel primary_channel) {
-        if ((this.primary_channel == null) && (tcp_channel == null)) {
+        if ((this.primaryChannel == null) && (tcpChannel == null)) {
             if (primary_channel != null) {
-                this.primary_channel = primary_channel;
-                tcp_channel = primary_channel;
-                embeded_channel.attr(IS_PRIMARY).set(true);
+                this.primaryChannel = primary_channel;
+                tcpChannel = primary_channel;
+                embededChannel.attr(IS_PRIMARY).set(true);
             }
-        } else if ((!this.primary_channel.isActive()) && (tcp_channel == secondary_channel)) {
-            this.primary_channel = primary_channel;
-        } else if ((!this.primary_channel.isActive()) && (tcp_channel == this.primary_channel)) {
-            synchronized (tcp_channel) {
-                tcp_channel.close();
-                this.primary_channel = primary_channel;
-                tcp_channel = primary_channel;
-                embeded_channel.attr(IS_PRIMARY).set(true);
-                if (tcp_channel.isActive()) {
-                    embed_ctx.fireUserEventTriggered(new ConnectEvent());
+        } else if ((!this.primaryChannel.isActive()) && (tcpChannel == secondaryChannel)) {
+            this.primaryChannel = primary_channel;
+        } else if ((!this.primaryChannel.isActive()) && (tcpChannel == this.primaryChannel)) {
+            synchronized (tcpChannel) {
+                tcpChannel.close();
+                this.primaryChannel = primary_channel;
+                tcpChannel = primary_channel;
+                embededChannel.attr(IS_PRIMARY).set(true);
+                if (tcpChannel.isActive()) {
+                    embedCtx.fireUserEventTriggered(new ConnectEvent());
                 }
             }
         }
@@ -282,25 +284,25 @@ public class S7HMuxImpl extends MessageToMessageCodec<ByteBuf, ByteBuf> implemen
 
     @Override
     public void setSecondaryChannel(Channel secondary_channel) {
-        if ((this.primary_channel == null) && (tcp_channel == null)) {
+        if ((this.primaryChannel == null) && (tcpChannel == null)) {
             if (secondary_channel != null) {
-                this.secondary_channel = secondary_channel;
-                tcp_channel = secondary_channel;
-                embeded_channel.attr(IS_PRIMARY).set(false);
+                this.secondaryChannel = secondary_channel;
+                tcpChannel = secondary_channel;
+                embededChannel.attr(IS_PRIMARY).set(false);
             }
-        } else if ((this.secondary_channel == null) || (tcp_channel == primary_channel)) {
-            this.secondary_channel = secondary_channel;
-        } else if ((!this.secondary_channel.isActive()) && (tcp_channel == primary_channel)) {
-            this.secondary_channel = secondary_channel;
-        } else if ((!this.secondary_channel.isActive()) && (tcp_channel == this.secondary_channel)) {
-            synchronized (tcp_channel) {
-                tcp_channel.close();
-                this.secondary_channel = secondary_channel;
-                tcp_channel = secondary_channel;
-                embeded_channel.attr(IS_PRIMARY).set(false);
+        } else if ((this.secondaryChannel == null) || (tcpChannel == primaryChannel)) {
+            this.secondaryChannel = secondary_channel;
+        } else if ((!this.secondaryChannel.isActive()) && (tcpChannel == primaryChannel)) {
+            this.secondaryChannel = secondary_channel;
+        } else if ((!this.secondaryChannel.isActive()) && (tcpChannel == this.secondaryChannel)) {
+            synchronized (tcpChannel) {
+                tcpChannel.close();
+                this.secondaryChannel = secondary_channel;
+                tcpChannel = secondary_channel;
+                embededChannel.attr(IS_PRIMARY).set(false);
             }
-            if (tcp_channel.isActive()) {
-                embed_ctx.fireUserEventTriggered(new ConnectEvent());
+            if (tcpChannel.isActive()) {
+                embedCtx.fireUserEventTriggered(new ConnectEvent());
             }
         }
     }
diff --git a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/discovery/S7PlcDiscoverer.java b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/discovery/S7PlcDiscoverer.java
index 50f623c729..9a487666dc 100644
--- a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/discovery/S7PlcDiscoverer.java
+++ b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/discovery/S7PlcDiscoverer.java
@@ -46,7 +46,7 @@ import org.apache.plc4x.java.spi.generation.WriteBufferByteBased;
 import org.apache.plc4x.java.spi.messages.DefaultPlcDiscoveryItem;
 import org.apache.plc4x.java.spi.messages.DefaultPlcDiscoveryResponse;
 import org.apache.plc4x.java.spi.messages.PlcDiscoverer;
-import org.apache.plc4x.java.spi.values.PlcValues;
+import org.apache.plc4x.java.spi.values.PlcSTRING;
 import org.pcap4j.core.NotOpenException;
 import org.pcap4j.core.PcapHandle;
 import org.pcap4j.core.PcapNativeException;
@@ -286,16 +286,16 @@ public class S7PlcDiscoverer implements PlcDiscoverer {
             // Only add devices we know support the S7Comm protocol.
             if(supportsS7Comm) {
                 Map<String, PlcValue> attributes = new HashMap<>();
-                attributes.put("ipAddress", PlcValues.of(remoteAddress));
-                attributes.put("subnetMask", PlcValues.of(remoteSubnetMask));
-                attributes.put("macAddress", PlcValues.of(srcAddr.toString()));
-                attributes.put("localMacAddress", PlcValues.of(dstAddr.toString()));
-                attributes.put("deviceTypeName", PlcValues.of(deviceTypeName));
-                attributes.put("deviceName", PlcValues.of(deviceName));
-                attributes.put("vendorId", PlcValues.of(vendorId));
-                attributes.put("deviceId", PlcValues.of(deviceId));
-                attributes.put("role", PlcValues.of(role));
-                attributes.put("packetType", PlcValues.of("dcp"));
+                attributes.put("ipAddress", new PlcSTRING(remoteAddress));
+                attributes.put("subnetMask", new PlcSTRING(remoteSubnetMask));
+                attributes.put("macAddress", new PlcSTRING(srcAddr.toString()));
+                attributes.put("localMacAddress", new PlcSTRING(dstAddr.toString()));
+                attributes.put("deviceTypeName", new PlcSTRING(deviceTypeName));
+                attributes.put("deviceName", new PlcSTRING(deviceName));
+                attributes.put("vendorId", new PlcSTRING(vendorId));
+                attributes.put("deviceId", new PlcSTRING(deviceId));
+                attributes.put("role", new PlcSTRING(role));
+                attributes.put("packetType", new PlcSTRING("dcp"));
 
                 String name = deviceTypeName + " - " + deviceName;
 
diff --git a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/optimizer/S7Optimizer.java b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/optimizer/S7Optimizer.java
index 5695bfec43..b48512c9a0 100644
--- a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/optimizer/S7Optimizer.java
+++ b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/optimizer/S7Optimizer.java
@@ -22,7 +22,6 @@ import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
 import org.apache.plc4x.java.api.messages.PlcReadRequest;
 import org.apache.plc4x.java.api.messages.PlcReadResponse;
 import org.apache.plc4x.java.api.messages.PlcWriteRequest;
-import org.apache.plc4x.java.api.model.PlcTag;
 import org.apache.plc4x.java.api.types.PlcResponseCode;
 import org.apache.plc4x.java.api.types.PlcValueType;
 import org.apache.plc4x.java.api.value.PlcValue;
@@ -35,8 +34,12 @@ import org.apache.plc4x.java.spi.generation.WriteBuffer;
 import org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest;
 import org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse;
 import org.apache.plc4x.java.spi.messages.DefaultPlcWriteRequest;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
-import org.apache.plc4x.java.spi.messages.utils.TagValueItem;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcTagItem;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcTagValueItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcTagItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcTagValueItem;
 import org.apache.plc4x.java.spi.optimizer.BaseOptimizer;
 import org.apache.plc4x.java.spi.utils.Serializable;
 import org.apache.plc4x.java.spi.values.PlcNull;
@@ -78,14 +81,15 @@ public class S7Optimizer extends BaseOptimizer {
 
         // List of all items in the current request.
 
-        LinkedHashMap<String, PlcTag> curTags = new LinkedHashMap<>();
+        LinkedHashMap<String, PlcTagItem> curTagItems = new LinkedHashMap<>();
 
         for (String tagName : readRequest.getTagNames()) {
 
             //TODO: Individual processing of these types of tags. like S7StringTag
             if ((readRequest.getTag(tagName) instanceof S7SzlTag) ||
                 (readRequest.getTag(tagName) instanceof S7ClkTag)) {
-                curTags.put(tagName, readRequest.getTag(tagName));
+                // We are only expecting valid tagValueItems being passed in.
+                curTagItems.put(tagName, new DefaultPlcTagItem(readRequest.getTag(tagName)));
                 continue;
             }
 
@@ -119,7 +123,8 @@ public class S7Optimizer extends BaseOptimizer {
                 curResponseSize += readResponseItemSize;
 
                 // Add the tag to the current request
-                curTags.put(tagName, tag);
+                // We are only expecting valid tagValueItems being passed in.
+                curTagItems.put(tagName, new DefaultPlcTagItem(tag));
             }
             // If the current item would exceed the PDU size in the response, even if this is a new request, split
             // up the array to fill up the last request and create so many sub-requests that read all in total.
@@ -132,8 +137,8 @@ public class S7Optimizer extends BaseOptimizer {
                 for(int curRequest = 0; curRequest < numRequests; curRequest++) {
                     int numCurRequestItems = Math.min(numItemsPerRequest, itemsLeft);
                     S7Tag tagFragment = new S7Tag(tag.getDataType(), tag.getMemoryArea(), tag.getBlockNumber(), curByteOffset, (byte) 0, numCurRequestItems);
-                    LinkedHashMap<String, PlcTag> tagFragments = new LinkedHashMap<>();
-                    tagFragments.put(tagName, tagFragment);
+                    LinkedHashMap<String, PlcTagItem> tagFragments = new LinkedHashMap<>();
+                    tagFragments.put(tagName, new DefaultPlcTagItem(tagFragment));
                     processedRequests.add(new DefaultPlcReadRequest(((DefaultPlcReadRequest) readRequest).getReader(), tagFragments));
                     curByteOffset += numItemsPerRequest * tag.getDataType().getSizeInBytes();
                     itemsLeft -= numCurRequestItems;
@@ -143,12 +148,12 @@ public class S7Optimizer extends BaseOptimizer {
             else {
                 // Create a new PlcReadRequest containing the current tag item.
                 processedRequests.add(new DefaultPlcReadRequest(
-                    ((DefaultPlcReadRequest) readRequest).getReader(), curTags));
+                    ((DefaultPlcReadRequest) readRequest).getReader(), curTagItems));
 
                 // Reset the size and item lists.
                 curRequestSize = EMPTY_READ_REQUEST_SIZE + readRequestItemSize;
                 curResponseSize = EMPTY_READ_RESPONSE_SIZE + readResponseItemSize;
-                curTags = new LinkedHashMap<>();
+                curTagItems = new LinkedHashMap<>();
 
                 // Splitting of huge tags not yet implemented, throw an exception instead.
                 if (((curRequestSize + readRequestItemSize) > s7DriverContext.getPduSize()) &&
@@ -157,21 +162,22 @@ public class S7Optimizer extends BaseOptimizer {
                 }
 
                 // Add the tag to the new current request
-                curTags.put(tagName, tag);
+                // We are only expecting valid tagValueItems being passed in.
+                curTagItems.put(tagName, new DefaultPlcTagItem(tag));
             }
         }
 
         // Create a new PlcReadRequest from the remaining tag items.
-        if (!curTags.isEmpty()) {
+        if (!curTagItems.isEmpty()) {
             processedRequests.add(new DefaultPlcReadRequest(
-                ((DefaultPlcReadRequest) readRequest).getReader(), curTags));
+                ((DefaultPlcReadRequest) readRequest).getReader(), curTagItems));
         }
 
         return processedRequests;
     }
 
     protected PlcReadResponse processReadResponses(PlcReadRequest readRequest, Map<PlcReadRequest, SubResponse<PlcReadResponse>> readResponses, DriverContext driverContext) {
-        Map<String, ResponseItem<PlcValue>> tagValues = new HashMap<>();
+        Map<String, PlcResponseItem<PlcValue>> tagValues = new HashMap<>();
         for (Map.Entry<PlcReadRequest, SubResponse<PlcReadResponse>> requestsEntries : readResponses.entrySet()) {
             PlcReadRequest curRequest = requestsEntries.getKey();
             SubResponse<PlcReadResponse> readResponse = requestsEntries.getValue();
@@ -191,7 +197,7 @@ public class S7Optimizer extends BaseOptimizer {
                             if (globalS7Tag.getDataType() == TransportSize.BYTE) {
                                 PlcRawByteArray existingItem;
                                 if (tagValues.containsKey(tagName)) {
-                                    ResponseItem<PlcValue> existingTagItem = tagValues.get(tagName);
+                                    PlcResponseItem<PlcValue> existingTagItem = tagValues.get(tagName);
                                     // If a previous response was invalid, we'll discard this part of it too.
                                     if(existingTagItem.getCode() != PlcResponseCode.OK) {
                                         continue;
@@ -199,7 +205,7 @@ public class S7Optimizer extends BaseOptimizer {
                                     existingItem = (PlcRawByteArray) existingTagItem.getValue();
                                 } else {
                                     existingItem = new PlcRawByteArray(new byte[globalS7Tag.getNumberOfElements()]);
-                                    tagValues.put(tagName, new ResponseItem<>(responseCode, existingItem));
+                                    tagValues.put(tagName, new DefaultPlcResponseItem<>(responseCode, existingItem));
                                 }
                                 byte[] currentItemByteArray = value.getRaw();
                                 int elementOffset = (currentS7Tag.getByteOffset() - globalS7Tag.getByteOffset()) / globalS7Tag.getDataType().getSizeInBytes();
@@ -210,7 +216,7 @@ public class S7Optimizer extends BaseOptimizer {
                             else {
                                 List<PlcValue> existingItems;
                                 if (tagValues.containsKey(tagName)) {
-                                    ResponseItem<PlcValue> existingTagItem = tagValues.get(tagName);
+                                    PlcResponseItem<PlcValue> existingTagItem = tagValues.get(tagName);
                                     // If a previous response was invalid, we'll discard this part of it too.
                                     if(existingTagItem.getCode() != PlcResponseCode.OK) {
                                         continue;
@@ -219,7 +225,7 @@ public class S7Optimizer extends BaseOptimizer {
                                 } else {
                                     existingItems = new ArrayList<>(Arrays.asList(new PlcValue[globalS7Tag.getNumberOfElements()]));
                                     PlcListModifiable mergedValue = new PlcListModifiable(existingItems);
-                                    tagValues.put(tagName, new ResponseItem<>(responseCode, mergedValue));
+                                    tagValues.put(tagName, new DefaultPlcResponseItem<>(responseCode, mergedValue));
                                 }
                                 List<? extends PlcValue> currentItems = value.getList();
                                 int elementOffset = (currentS7Tag.getByteOffset() - globalS7Tag.getByteOffset()) / globalS7Tag.getDataType().getSizeInBytes();
@@ -230,13 +236,13 @@ public class S7Optimizer extends BaseOptimizer {
                         } else {
                             // Even if a previous part was ok, if at least one part is invalid, we'll
                             // treat all parts equally broken.
-                            tagValues.put(tagName, new ResponseItem<>(responseCode, new PlcNull()));
+                            tagValues.put(tagName, new DefaultPlcResponseItem<>(responseCode, new PlcNull()));
                         }
                     } else {
-                        tagValues.put(tagName, new ResponseItem<>(responseCode, value));
+                        tagValues.put(tagName, new DefaultPlcResponseItem<>(responseCode, value));
                     }
                 } else {
-                    tagValues.put(tagName, new ResponseItem<>(PlcResponseCode.INTERNAL_ERROR, null));
+                    tagValues.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.INTERNAL_ERROR, null));
                 }
             }
         }
@@ -261,7 +267,7 @@ public class S7Optimizer extends BaseOptimizer {
         int curResponseSize = EMPTY_WRITE_RESPONSE_SIZE;
 
         // List of all items in the current request.
-        LinkedHashMap<String, TagValueItem> curTags = new LinkedHashMap<>();
+        LinkedHashMap<String, PlcTagValueItem> curTags = new LinkedHashMap<>();
 
         for (String tagName : writeRequest.getTagNames()) {
             S7Tag tag = (S7Tag) writeRequest.getTag(tagName);
@@ -326,7 +332,8 @@ public class S7Optimizer extends BaseOptimizer {
                     throw new PlcRuntimeException("Tag size exceeds maximum payload for one item.");
                 }
             }
-            curTags.put(tagName, new TagValueItem(tag, value));
+            // We are only expecting valid tagValueItems being passed in.
+            curTags.put(tagName, new DefaultPlcTagValueItem(tag, value));
         }
 
         // Create a new PlcWriteRequest from the remaining tag items.
diff --git a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7HGeneratedDriverBase.java b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7HGeneratedDriverBase.java
index e7b54148c1..f721e664fd 100644
--- a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7HGeneratedDriverBase.java
+++ b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7HGeneratedDriverBase.java
@@ -23,14 +23,12 @@ import org.apache.plc4x.java.api.authentication.PlcAuthentication;
 import org.apache.plc4x.java.spi.configuration.PlcConnectionConfiguration;
 import org.apache.plc4x.java.spi.configuration.PlcTransportConfiguration;
 import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
-import org.apache.plc4x.java.api.value.PlcValueHandler;
 import org.apache.plc4x.java.s7.readwrite.TPKTPacket;
 import org.apache.plc4x.java.s7.readwrite.configuration.S7Configuration;
 import org.apache.plc4x.java.s7.readwrite.configuration.S7TcpTransportConfiguration;
 import org.apache.plc4x.java.spi.configuration.ConfigurationFactory;
 import org.apache.plc4x.java.spi.connection.ChannelFactory;
 import org.apache.plc4x.java.spi.connection.GeneratedDriverBase;
-import org.apache.plc4x.java.spi.connection.PlcTagHandler;
 import org.apache.plc4x.java.spi.connection.ProtocolStackConfigurer;
 import org.apache.plc4x.java.spi.transport.Transport;
 import org.slf4j.Logger;
@@ -163,7 +161,6 @@ public class S7HGeneratedDriverBase extends GeneratedDriverBase<TPKTPacket> {
         return new S7HPlcConnection(
             canPing(),
             canRead(), canWrite(), canSubscribe(), canBrowse(),
-            getTagHandler(),
             getValueHandler(),
             configuration,
             channelFactory,
@@ -177,15 +174,6 @@ public class S7HGeneratedDriverBase extends GeneratedDriverBase<TPKTPacket> {
             getAuthentication());
     }
 
-    @Override
-    protected PlcTagHandler getTagHandler() {
-        throw new UnsupportedOperationException("getTagHandler, Not supported yet.");
-    }
-
-    @Override
-    protected PlcValueHandler getValueHandler() {
-        throw new UnsupportedOperationException("getValueHandler, Not supported yet.");
-    }
     @Override
     protected ProtocolStackConfigurer<TPKTPacket> getStackConfigurer() {
         throw new UnsupportedOperationException("getStackConfigurer, Not supported yet.");
diff --git a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7HMuxImpl.java b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7HMuxImpl.java
index 26248b1c52..1a987940d0 100644
--- a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7HMuxImpl.java
+++ b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7HMuxImpl.java
@@ -114,24 +114,24 @@ public class S7HMuxImpl extends MessageToMessageCodec<ByteBuf, ByteBuf> implemen
      */
     final static AttributeKey<Integer> RETRY_TIME = AttributeKey.valueOf("RETRY_TIME");
 
-    ChannelHandlerContext embed_ctx = null;
-    protected Channel embeded_channel = null;
-    protected Channel tcp_channel = null;
-    protected Channel primary_channel = null;
-    protected Channel secondary_channel = null;
+    ChannelHandlerContext embedCtx = null;
+    protected Channel embededChannel = null;
+    protected Channel tcpChannel = null;
+    protected Channel primaryChannel = null;
+    protected Channel secondaryChannel = null;
 
     /*
      * From S7ProtocolLogic
      * TODO: Evaluate if the "embed_ctx" is really required since we set
-     * the Embeded channel when we created it.
+     *  the Embeded channel when we created it.
      */
     @Override
-    protected void encode(ChannelHandlerContext ctx, ByteBuf outbb, List<Object> list) {
-        if ((embed_ctx == null) && (ctx.channel() instanceof EmbeddedChannel)) embed_ctx = ctx;
-        if ((tcp_channel != null) && (embed_ctx == ctx)) {
-            tcp_channel.writeAndFlush(outbb.copy());
+    protected void encode(ChannelHandlerContext ctx, ByteBuf outBB, List<Object> list) {
+        if ((embedCtx == null) && (ctx.channel() instanceof EmbeddedChannel)) embedCtx = ctx;
+        if ((tcpChannel != null) && (embedCtx == ctx)) {
+            tcpChannel.writeAndFlush(outBB.copy());
         } else {
-            list.add(outbb.copy());
+            list.add(outBB.copy());
         }
     }
 
@@ -141,8 +141,8 @@ public class S7HMuxImpl extends MessageToMessageCodec<ByteBuf, ByteBuf> implemen
      * the pipeline of the channel "embeded_channel"
      */
     @Override
-    protected void decode(ChannelHandlerContext ctx, ByteBuf inbb, List<Object> list) throws Exception {     
-        embed_ctx.fireChannelRead(inbb.copy());
+    protected void decode(ChannelHandlerContext ctx, ByteBuf inBB, List<Object> list) throws Exception {
+        embedCtx.fireChannelRead(inBB.copy());
     }
 
     @Override
@@ -177,19 +177,19 @@ public class S7HMuxImpl extends MessageToMessageCodec<ByteBuf, ByteBuf> implemen
         logger.info(LocalTime.now() + " userEventTriggered: " + ctx.name() + " Event: " + evt);
         if (evt instanceof ConnectedEvent) {
             try {
-                tcp_channel.pipeline().remove("watchdog");
+                tcpChannel.pipeline().remove("watchdog");
             } catch (Exception ex) {
                 logger.info(ex.toString());
             }
             try {
-                if ((embeded_channel.attr(READ_TIME_OUT).get() > 0) &&
-                    embeded_channel.attr(IS_PING_ACTIVE).get())
-                    tcp_channel.pipeline().addFirst("watchdog",
-                        new ReadTimeoutHandler(embeded_channel.attr(READ_TIME_OUT).get()));
-                if (tcp_channel.isActive()) {
-                    embeded_channel.attr(IS_CONNECTED).set(true);
+                if ((embededChannel.attr(READ_TIME_OUT).get() > 0) &&
+                    embededChannel.attr(IS_PING_ACTIVE).get())
+                    tcpChannel.pipeline().addFirst("watchdog",
+                        new ReadTimeoutHandler(embededChannel.attr(READ_TIME_OUT).get()));
+                if (tcpChannel.isActive()) {
+                    embededChannel.attr(IS_CONNECTED).set(true);
                 } else {
-                    embeded_channel.attr(IS_CONNECTED).set(false);
+                    embededChannel.attr(IS_CONNECTED).set(false);
                 }
             } catch (Exception ex) {
                 logger.info(ex.toString());
@@ -223,45 +223,45 @@ public class S7HMuxImpl extends MessageToMessageCodec<ByteBuf, ByteBuf> implemen
     @Override
     public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
         super.channelUnregistered(ctx);
-        logger.debug(LocalTime.now().toString() + " channelUnregistered: " + ctx.name());
-        String strCanal = (tcp_channel == primary_channel) ? "PRIMARY" : "SECONDARY";
-        logger.info("Unregistered of channel: " + strCanal);
+        logger.debug("{} channelUnregistered: {}", LocalTime.now(), ctx.name());
+        String strCanal = (tcpChannel == primaryChannel) ? "PRIMARY" : "SECONDARY";
+        logger.info("Unregistered of channel: {}", strCanal);
         //TODO: If embedded channel is closed, we need close all channels
-        if (ctx == embed_ctx) return;
+        if (ctx == embedCtx) return;
 
-        if (tcp_channel == ctx.channel()) {
-            embeded_channel.attr(IS_CONNECTED).set(false);
-            embeded_channel.attr(WAS_CONNECTED).set(true);
-            embeded_channel.pipeline().fireUserEventTriggered(new DisconnectedEvent());
+        if (tcpChannel == ctx.channel()) {
+            embededChannel.attr(IS_CONNECTED).set(false);
+            embededChannel.attr(WAS_CONNECTED).set(true);
+            embededChannel.pipeline().fireUserEventTriggered(new DisconnectedEvent());
         }
 
-        logger.info(embed_ctx.executor().toString());
+        logger.info(embedCtx.executor().toString());
 
-        if ((tcp_channel == primary_channel) &&
-            (primary_channel == ctx.channel()))
-            if ((!primary_channel.isActive()) &&
-                (secondary_channel != null))
-                if (secondary_channel.isActive()) {
-                    synchronized (tcp_channel) {
+        if ((tcpChannel == primaryChannel) &&
+            (primaryChannel == ctx.channel()))
+            if ((!primaryChannel.isActive()) &&
+                (secondaryChannel != null))
+                if (secondaryChannel.isActive()) {
+                    synchronized (tcpChannel) {
                         logger.info("Using secondary TCP channel.");
-                        tcp_channel = secondary_channel;
-                        embeded_channel.attr(IS_PRIMARY).set(false);
-                        embeded_channel.pipeline().fireUserEventTriggered(new ConnectEvent());
+                        tcpChannel = secondaryChannel;
+                        embededChannel.attr(IS_PRIMARY).set(false);
+                        embededChannel.pipeline().fireUserEventTriggered(new ConnectEvent());
                     }
                 }
         ;
 
 
-        if ((tcp_channel == secondary_channel) &&
-            (secondary_channel == ctx.channel()))
-            if ((!secondary_channel.isActive()) &&
-                (primary_channel != null))
-                if (primary_channel.isActive()) {
-                    synchronized (tcp_channel) {
+        if ((tcpChannel == secondaryChannel) &&
+            (secondaryChannel == ctx.channel()))
+            if ((!secondaryChannel.isActive()) &&
+                (primaryChannel != null))
+                if (primaryChannel.isActive()) {
+                    synchronized (tcpChannel) {
                         logger.info("Using primary TCP channel.");
-                        tcp_channel = primary_channel;
-                        embeded_channel.attr(IS_PRIMARY).set(true);
-                        embeded_channel.pipeline().fireUserEventTriggered(new ConnectEvent());
+                        tcpChannel = primaryChannel;
+                        embededChannel.attr(IS_PRIMARY).set(true);
+                        embededChannel.pipeline().fireUserEventTriggered(new ConnectEvent());
                     }
                 }
 
@@ -271,43 +271,43 @@ public class S7HMuxImpl extends MessageToMessageCodec<ByteBuf, ByteBuf> implemen
     @Override
     public void setEmbededhannel(Channel embeded_channel, PlcConnectionConfiguration configuration) {
         final S7Configuration conf = (S7Configuration) configuration;
-        this.embeded_channel = embeded_channel;
-        this.embeded_channel.attr(IS_CONNECTED).set(false);
-        this.embeded_channel.attr(WAS_CONNECTED).set(false);
-        this.embeded_channel.attr(IS_PRIMARY).set(true);
+        this.embededChannel = embeded_channel;
+        this.embededChannel.attr(IS_CONNECTED).set(false);
+        this.embededChannel.attr(WAS_CONNECTED).set(false);
+        this.embededChannel.attr(IS_PRIMARY).set(true);
 
         //From the URL
-        this.embeded_channel.attr(READ_TIME_OUT).set(conf.getReadTimeout());
-        this.embeded_channel.attr(IS_PING_ACTIVE).set(conf.getPing());
-        this.embeded_channel.attr(PING_TIME).set(conf.getPingTime());
-        this.embeded_channel.attr(RETRY_TIME).set(conf.getRetryTime());
+        this.embededChannel.attr(READ_TIME_OUT).set(conf.getReadTimeout());
+        this.embededChannel.attr(IS_PING_ACTIVE).set(conf.getPing());
+        this.embededChannel.attr(PING_TIME).set(conf.getPingTime());
+        this.embededChannel.attr(RETRY_TIME).set(conf.getRetryTime());
     }
 
     @Override
     public void setPrimaryChannel(Channel primary_channel) {
-        if ((this.primary_channel == null) && (tcp_channel == null)) {
+        if ((this.primaryChannel == null) && (tcpChannel == null)) {
             if (primary_channel != null) {
-                this.primary_channel = primary_channel;
-                tcp_channel = primary_channel;
-                embeded_channel.attr(IS_PRIMARY).set(true);
+                this.primaryChannel = primary_channel;
+                tcpChannel = primary_channel;
+                embededChannel.attr(IS_PRIMARY).set(true);
             }
-        } else if ((this.primary_channel == null) ||
-            ((tcp_channel == secondary_channel)) && (tcp_channel.isActive())) {
-            this.primary_channel = primary_channel;
+        } else if ((this.primaryChannel == null) ||
+            ((tcpChannel == secondaryChannel)) && (tcpChannel.isActive())) {
+            this.primaryChannel = primary_channel;
 
-        } else if ((!this.primary_channel.isActive()) && (tcp_channel == secondary_channel)) {
-            this.primary_channel = primary_channel;
+        } else if ((!this.primaryChannel.isActive()) && (tcpChannel == secondaryChannel)) {
+            this.primaryChannel = primary_channel;
 
-        } else if (((!this.primary_channel.isActive()) && (tcp_channel == this.primary_channel)) ||
+        } else if (((!this.primaryChannel.isActive()) && (tcpChannel == this.primaryChannel)) ||
             (primary_channel.isActive())) {
-            synchronized (tcp_channel) {
-                tcp_channel.close();
-                this.primary_channel = primary_channel;
-                tcp_channel = primary_channel;
-                embeded_channel.attr(IS_PRIMARY).set(true);
-
-                if (tcp_channel.isActive()) {
-                    embed_ctx.fireUserEventTriggered(new ConnectEvent());
+            synchronized (tcpChannel) {
+                tcpChannel.close();
+                this.primaryChannel = primary_channel;
+                tcpChannel = primary_channel;
+                embededChannel.attr(IS_PRIMARY).set(true);
+
+                if (tcpChannel.isActive()) {
+                    embedCtx.fireUserEventTriggered(new ConnectEvent());
                 }
             }
         } else if (primary_channel.isActive()) {
@@ -317,37 +317,37 @@ public class S7HMuxImpl extends MessageToMessageCodec<ByteBuf, ByteBuf> implemen
 
     @Override
     public void setSecondaryChannel(Channel secondary_channel) {
-        if ((this.primary_channel == null) && (tcp_channel == null)) {
+        if ((this.primaryChannel == null) && (tcpChannel == null)) {
             if (secondary_channel != null) {
-                this.secondary_channel = secondary_channel;
-                tcp_channel = secondary_channel;
-                embeded_channel.attr(IS_PRIMARY).set(false);
+                this.secondaryChannel = secondary_channel;
+                tcpChannel = secondary_channel;
+                embededChannel.attr(IS_PRIMARY).set(false);
             }
 
-        } else if ((this.secondary_channel == null) ||
-            ((tcp_channel == primary_channel)) && (tcp_channel.isActive())) {
-            this.secondary_channel = secondary_channel;
+        } else if ((this.secondaryChannel == null) ||
+            ((tcpChannel == primaryChannel)) && (tcpChannel.isActive())) {
+            this.secondaryChannel = secondary_channel;
 
-        } else if ((!this.secondary_channel.isActive()) && (tcp_channel == primary_channel)) {
-            this.secondary_channel = secondary_channel;
+        } else if ((!this.secondaryChannel.isActive()) && (tcpChannel == primaryChannel)) {
+            this.secondaryChannel = secondary_channel;
 
-        } else if (((!this.secondary_channel.isActive()) && (tcp_channel == this.secondary_channel)) ||
+        } else if (((!this.secondaryChannel.isActive()) && (tcpChannel == this.secondaryChannel)) ||
             (secondary_channel.isActive())) {
-            synchronized (tcp_channel) {
-                tcp_channel.close();
-                this.secondary_channel = secondary_channel;
-                tcp_channel = secondary_channel;
-                embeded_channel.attr(IS_PRIMARY).set(false);
+            synchronized (tcpChannel) {
+                tcpChannel.close();
+                this.secondaryChannel = secondary_channel;
+                tcpChannel = secondary_channel;
+                embededChannel.attr(IS_PRIMARY).set(false);
             }
-            if (tcp_channel.isActive()) {
-                embed_ctx.fireUserEventTriggered(new ConnectEvent());
+            if (tcpChannel.isActive()) {
+                embedCtx.fireUserEventTriggered(new ConnectEvent());
             }
         }
     }
 
     @Override
     public Channel getTCPChannel() {
-        return tcp_channel;
+        return tcpChannel;
     }
 
 
diff --git a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7HPlcConnection.java b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7HPlcConnection.java
index 3bc1392b5e..ea0a1e258b 100644
--- a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7HPlcConnection.java
+++ b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/protocol/S7HPlcConnection.java
@@ -34,7 +34,6 @@ import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
 import org.apache.plc4x.java.api.messages.PlcPingResponse;
 import org.apache.plc4x.java.api.messages.PlcReadRequest;
 import org.apache.plc4x.java.api.messages.PlcReadResponse;
-import org.apache.plc4x.java.api.value.PlcValueHandler;
 import org.apache.plc4x.java.s7.readwrite.TPKTPacket;
 import org.apache.plc4x.java.spi.configuration.ConfigurationFactory;
 import org.apache.plc4x.java.spi.connection.ChannelFactory;
@@ -45,6 +44,7 @@ import org.apache.plc4x.java.spi.events.CloseConnectionEvent;
 import org.apache.plc4x.java.spi.events.ConnectedEvent;
 import org.apache.plc4x.java.spi.events.DisconnectEvent;
 import org.apache.plc4x.java.spi.optimizer.BaseOptimizer;
+import org.apache.plc4x.java.spi.values.PlcValueHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -91,7 +91,6 @@ public class S7HPlcConnection extends DefaultNettyPlcConnection implements Runna
         boolean canWrite,
         boolean canSubscribe,
         boolean canBrowse,
-        PlcTagHandler tagHandler,
         PlcValueHandler valueHandler,
         PlcConnectionConfiguration configuration,
         ChannelFactory channelFactory,
@@ -108,7 +107,6 @@ public class S7HPlcConnection extends DefaultNettyPlcConnection implements Runna
             canWrite,
             canSubscribe,
             canBrowse,
-            tagHandler,
             valueHandler,
             configuration,
             channelFactory,
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 001dc77fca..c50c1bd39c 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
@@ -41,11 +41,16 @@ import org.apache.plc4x.java.s7.readwrite.utils.S7PlcSubscriptionHandle;
 import org.apache.plc4x.java.s7.utils.S7ParamErrorCode;
 import org.apache.plc4x.java.spi.ConversationContext;
 import org.apache.plc4x.java.spi.Plc4xProtocolBase;
+import org.apache.plc4x.java.spi.connection.PlcTagHandler;
 import org.apache.plc4x.java.spi.context.DriverContext;
 import org.apache.plc4x.java.spi.generation.*;
 import org.apache.plc4x.java.spi.messages.*;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
-import org.apache.plc4x.java.spi.messages.utils.TagValueItem;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcTagItem;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcTagValueItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcTagItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcTagValueItem;
 import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionTag;
 import org.apache.plc4x.java.spi.transaction.RequestTransactionManager;
 import org.apache.plc4x.java.spi.values.*;
@@ -70,8 +75,6 @@ import org.apache.plc4x.java.s7.events.S7SysEvent;
 import org.apache.plc4x.java.s7.events.S7UserEvent;
 import org.apache.plc4x.java.s7.readwrite.utils.S7PlcSubscriptionRequest;
 
-import javax.xml.crypto.Data;
-
 /**
  * The S7 Protocol states that there can not be more then {min(maxAmqCaller, maxAmqCallee} "ongoing" requests.
  * So we need to limit those.
@@ -143,6 +146,11 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
         eventLogic.start();
     }
 
+    @Override
+    public PlcTagHandler getTagHandler() {
+        return new S7PlcTagHandler();
+    }
+
     @Override
     public void close(ConversationContext<TPKTPacket> context) {
         // TODO: Find out how to close this prior to Java 19
@@ -445,7 +453,7 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
 
             // Start a new request-transaction (Is ended in the response-handler)
             RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
-            transaction.submit(() -> context.sendRequest(tpktPacket)
+            transaction.submit(() -> conversationContext.sendRequest(tpktPacket)
                 .onTimeout(new TransactionErrorCallback<>(future, transaction))
                 .onError(new TransactionErrorCallback<>(future, transaction))
                 .expectResponse(TPKTPacket.class, REQUEST_TIMEOUT)
@@ -476,7 +484,7 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
             }
 
             try {
-                HashMap<String, ResponseItem<PlcSubscriptionHandle>> values = new HashMap<>();
+                HashMap<String, PlcResponseItem<PlcSubscriptionHandle>> values = new HashMap<>();
                 valuesResponse.forEach((s, p) -> {
                     if (p != null)
                         values.putAll(((DefaultPlcSubscriptionResponse) p).getValues());
@@ -526,7 +534,7 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
 
         // Start a new request-transaction (Is ended in the response-handler)
         RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
-        transaction.submit(() -> context.sendRequest(tpktPacket)
+        transaction.submit(() -> conversationContext.sendRequest(tpktPacket)
             .onTimeout(new TransactionErrorCallback<>(future, transaction))
             .onError(new TransactionErrorCallback<>(future, transaction))
             .expectResponse(TPKTPacket.class, REQUEST_TIMEOUT)
@@ -616,7 +624,7 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
                                                                     S7Message responseMessage)
         throws PlcProtocolException {
 
-        Map<String, ResponseItem<PlcSubscriptionHandle>> values = new HashMap<>();
+        Map<String, PlcResponseItem<PlcSubscriptionHandle>> values = new HashMap<>();
         short errorClass = 0;
         short errorCode = 0;
         if (responseMessage instanceof S7MessageUserData) {
@@ -648,7 +656,7 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
                 logger.warn("Got an error response from the PLC. This particular response code usually indicates " +
                     "that PUT/GET is not enabled on the PLC.");
                 for (String tagName : plcSubscriptionRequest.getTagNames()) {
-                    values.put(tagName, new ResponseItem<>(PlcResponseCode.REMOTE_ERROR, null));
+                    values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.REMOTE_ERROR, null));
                 }
                 return new DefaultPlcSubscriptionResponse(plcSubscriptionRequest, values);
             }
@@ -659,7 +667,7 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
                     "data on a PLC that doesn't support subscriptions (S7-1200 or S7-1500)",
                     errorClass, errorCode);
                 for (String tagName : plcSubscriptionRequest.getTagNames()) {
-                    values.put(tagName, new ResponseItem<>(PlcResponseCode.UNSUPPORTED, null));
+                    values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.UNSUPPORTED, null));
                 }
                 return new DefaultPlcSubscriptionResponse(plcSubscriptionRequest, values);
             } else {
@@ -669,7 +677,7 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
                         "containing a capture of the communication.",
                     errorClass, errorCode);
                 for (String tagName : plcSubscriptionRequest.getTagNames()) {
-                    values.put(tagName, new ResponseItem<>(PlcResponseCode.INTERNAL_ERROR, null));
+                    values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.INTERNAL_ERROR, null));
                 }
                 return new DefaultPlcSubscriptionResponse(plcSubscriptionRequest, values);
             }
@@ -720,12 +728,12 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
             //String tagName = (String) plcSubscriptionRequest.getTagNames().toArray()[0];
             //TODO: Chequear si tagName es el correcto           
             //logger.info("strTagName: " + strTagName);
-            values.put(strTagName, new ResponseItem<>(PlcResponseCode.OK, null));
+            values.put(strTagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, null));
             for (short s : items.getMessageObjects()) {
                 if (s == 0x0000) {
-                    values.put(Integer.toHexString(s), new ResponseItem<>(PlcResponseCode.OK, null));
+                    values.put(Integer.toHexString(s), new DefaultPlcResponseItem<>(PlcResponseCode.OK, null));
                 } else if (s == 0x000a) {
-                    values.put(Integer.toHexString(s), new ResponseItem<>(PlcResponseCode.NOT_FOUND, null));
+                    values.put(Integer.toHexString(s), new DefaultPlcResponseItem<>(PlcResponseCode.NOT_FOUND, null));
                 }
             }
 
@@ -737,7 +745,7 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
             //        payloadItems.get(0);
             //String fieldName = (String) S7PayloadUserDataItemCyclicServicesPush .getFieldNames().toArray()[0];
             //logger.warn("Request field: " + strTagName + ": " + S7ParamErrorCode.valueOf(errorCode) + " " + S7ParamErrorCode.valueOf(errorCode).getEvent());
-            values.put(strTagName, new ResponseItem<>(PlcResponseCode.NOT_FOUND, null));
+            values.put(strTagName, new DefaultPlcResponseItem<>(PlcResponseCode.NOT_FOUND, null));
             return new DefaultPlcSubscriptionResponse(plcSubscriptionRequest, values);
 
         } else if (payloadItems.get(0) instanceof S7PayloadUserDataItemCpuFunctionAlarmQueryResponse) {
@@ -809,7 +817,7 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
             }
 
             PlcResponseCode resCode = (items.getReturnCode() == DataTransportErrorCode.OK) ? PlcResponseCode.OK : PlcResponseCode.INTERNAL_ERROR;
-            values.put(strTagName, new ResponseItem<>(resCode, null));
+            values.put(strTagName, new DefaultPlcResponseItem<>(resCode, null));
             return new DefaultPlcSubscriptionResponse(plcSubscriptionRequest, values);
 
         } else if (payloadItems.get(0) instanceof S7PayloadUserDataItemCyclicServicesSubscribeResponse) {
@@ -832,7 +840,7 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
 
             S7PlcSubscriptionHandle cycHandle = new S7PlcSubscriptionHandle(strTagName, EventType.CYC, eventLogic);
 
-            ResponseItem<PlcSubscriptionHandle> response = new ResponseItem<>(PlcResponseCode.OK, cycHandle);
+            PlcResponseItem<PlcSubscriptionHandle> response = new DefaultPlcResponseItem<>(PlcResponseCode.OK, cycHandle);
             plcSubscriptionRequest.getTagNames().forEach(s -> values.put(s, response));
 
             return new DefaultPlcSubscriptionResponse(plcSubscriptionRequest, values);
@@ -851,7 +859,7 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
             eventQueue.add(cycEvent);
 
             S7PlcSubscriptionHandle cycHandle = new S7PlcSubscriptionHandle(strTagName, EventType.CYC, eventLogic);
-            values.put(strTagName, new ResponseItem<>(PlcResponseCode.OK, cycHandle));
+            values.put(strTagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, cycHandle));
             return new DefaultPlcSubscriptionResponse(plcSubscriptionRequest, values);
 
         } else if (payloadItems.get(0) instanceof S7PayloadUserDataItemCyclicServicesErrorResponse) {
@@ -864,11 +872,11 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
             /*if (errorCode == 0x8104) {
                 values.put(strTagName, new ResponseItem(PlcResponseCode.UNSUPPORTED, null));
             } else {*/
-            values.put(strTagName, new ResponseItem<>(PlcResponseCode.INTERNAL_ERROR, null));
+            values.put(strTagName, new DefaultPlcResponseItem<>(PlcResponseCode.INTERNAL_ERROR, null));
             // }
             return new DefaultPlcSubscriptionResponse(plcSubscriptionRequest, values);
         } else if (payloadItems.get(0) instanceof S7PayloadUserDataItemCyclicServicesUnsubscribeResponse) {
-            values.put(strTagName, new ResponseItem<>(PlcResponseCode.OK, null));
+            values.put(strTagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, null));
             return new DefaultPlcSubscriptionResponse(plcSubscriptionRequest, values);
         }
 
@@ -878,16 +886,16 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
                 S7SubscriptionTag tag = (S7SubscriptionTag) dTag.getTag();
                 switch (tag.getEventType()) {
                     case MODE:
-                        values.put(tagName, new ResponseItem<>(PlcResponseCode.OK, modeHandle));
+                        values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, modeHandle));
                         break;
                     case SYS:
-                        values.put(tagName, new ResponseItem<>(PlcResponseCode.OK, sysHandle));
+                        values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, sysHandle));
                         break;
                     case USR:
-                        values.put(tagName, new ResponseItem<>(PlcResponseCode.OK, usrHandle));
+                        values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, usrHandle));
                         break;
                     case ALM:
-                        values.put(tagName, new ResponseItem<>(PlcResponseCode.OK, almHandle));
+                        values.put(tagName, new DefaultPlcResponseItem<>(PlcResponseCode.OK, almHandle));
                         break;
                 }
 
@@ -1292,19 +1300,21 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
         // Replace the var-length string fields with requests to read the
         // length information instead of the string content.
         int numVarLengthStrings = 0;
-        LinkedHashMap<String, PlcTag> updatedRequestItems = new LinkedHashMap<>(request.getNumberOfTags());
+        LinkedHashMap<String, PlcTagItem> updatedRequestItems = new LinkedHashMap<>(request.getNumberOfTags());
         for (String tagName : request.getTagNames()) {
-            S7Tag s7tag = (S7Tag) request.getTag(tagName);
-            if(s7tag instanceof S7StringVarLengthTag) {
-                if(s7tag.getDataType() == TransportSize.STRING) {
-                    updatedRequestItems.put(tagName, new S7Tag(TransportSize.BYTE, s7tag.getMemoryArea(), s7tag.getBlockNumber(), s7tag.getByteOffset(), s7tag.getBitOffset(), 2));
+            PlcTagItem plcTagItem = request.getTagItem(tagName);
+            if(plcTagItem.getTag() instanceof S7StringVarLengthTag) {
+                S7Tag s7Tag = (S7Tag) plcTagItem.getTag();
+                TransportSize dataType = s7Tag.getDataType();
+                if(dataType == TransportSize.STRING) {
+                    updatedRequestItems.put(tagName, new DefaultPlcTagItem(new S7Tag(TransportSize.BYTE, s7Tag.getMemoryArea(), s7Tag.getBlockNumber(), s7Tag.getByteOffset(), s7Tag.getBitOffset(), 2)));
                     numVarLengthStrings++;
-                } else if(s7tag.getDataType() == TransportSize.WSTRING) {
-                    updatedRequestItems.put(tagName, new S7Tag(TransportSize.BYTE, s7tag.getMemoryArea(), s7tag.getBlockNumber(), s7tag.getByteOffset(), s7tag.getBitOffset(), 4));
+                } else if(dataType == TransportSize.WSTRING) {
+                    updatedRequestItems.put(tagName, new DefaultPlcTagItem(new S7Tag(TransportSize.BYTE, s7Tag.getMemoryArea(), s7Tag.getBlockNumber(), s7Tag.getByteOffset(), s7Tag.getBitOffset(), 4)));
                     numVarLengthStrings++;
                 }
             } else {
-                updatedRequestItems.put(tagName, s7tag);
+                updatedRequestItems.put(tagName, plcTagItem);
             }
         }
 
@@ -1316,24 +1326,24 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
                 return;
             }
             // Collect the responses for the var-length strings and read them separately.
-            LinkedHashMap<String, PlcTag> varLengthStringTags = new LinkedHashMap<>(finalNumVarLengthStrings);
+            LinkedHashMap<String, PlcTagItem> varLengthStringTags = new LinkedHashMap<>(finalNumVarLengthStrings);
             int curItem = 0;
             for (String tagName : request.getTagNames()) {
                 S7Tag s7tag = (S7Tag) request.getTag(tagName);
                 if(s7tag instanceof S7StringVarLengthTag) {
                     S7VarPayloadDataItem s7VarPayloadDataItem = ((S7PayloadReadVarResponse) s7Message.getPayload()).getItems().get(curItem);
-                    // Simply ignore processing var-lenght strings that are not ok
+                    // Simply ignore processing var-length strings that are not ok
                     if(s7VarPayloadDataItem.getReturnCode() == DataTransportErrorCode.OK) {
                         ReadBuffer rb = new ReadBufferByteBased(s7VarPayloadDataItem.getData());
                         try {
                             if (s7tag.getDataType() == TransportSize.STRING) {
                                 rb.readShort(8);
                                 int stringLength = rb.readShort(8);
-                                varLengthStringTags.put(tagName, new S7StringFixedLengthTag(TransportSize.STRING, s7tag.getMemoryArea(), s7tag.getBlockNumber(), s7tag.getByteOffset(), s7tag.getBitOffset(), 1, stringLength));
+                                varLengthStringTags.put(tagName, new DefaultPlcTagItem(new S7StringFixedLengthTag(TransportSize.STRING, s7tag.getMemoryArea(), s7tag.getBlockNumber(), s7tag.getByteOffset(), s7tag.getBitOffset(), 1, stringLength)));
                             } else if (s7tag.getDataType() == TransportSize.WSTRING) {
                                 rb.readInt(16);
                                 int stringLength = rb.readInt(16);
-                                varLengthStringTags.put(tagName, new S7StringFixedLengthTag(TransportSize.WSTRING, s7tag.getMemoryArea(), s7tag.getBlockNumber(), s7tag.getByteOffset(), s7tag.getBitOffset(), 1, stringLength));
+                                varLengthStringTags.put(tagName, new DefaultPlcTagItem(new S7StringFixedLengthTag(TransportSize.WSTRING, s7tag.getMemoryArea(), s7tag.getBlockNumber(), s7tag.getByteOffset(), s7tag.getBitOffset(), 1, stringLength)));
                             }
                         } catch (Exception e) {
                             logger.warn("Error parsing string size for tag {}", tagName, e);
@@ -1428,7 +1438,7 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
             } else {
                 // Create an alternative list of request items, where all var-length string tags are replaced with
                 // fixed-length string tags using the string length returned by the previous request.
-                LinkedHashMap<String, TagValueItem> updatedRequestItems = new LinkedHashMap<>(request.getNumberOfTags());
+                LinkedHashMap<String, PlcTagValueItem> updatedRequestItems = new LinkedHashMap<>(request.getNumberOfTags());
                 for (String tagName : request.getTagNames()) {
                     PlcTag tag = request.getTag(tagName);
                     PlcValue value = request.getPlcValue(tagName);
@@ -1438,9 +1448,9 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
                         S7StringFixedLengthTag newTag = new S7StringFixedLengthTag(varLengthTag.getDataType(), varLengthTag.getMemoryArea(),
                             varLengthTag.getBlockNumber(), varLengthTag.getByteOffset(), varLengthTag.getBitOffset(),
                             varLengthTag.getNumberOfElements(), stringLength);
-                        updatedRequestItems.put(tagName, new TagValueItem(newTag, value));
+                        updatedRequestItems.put(tagName, new DefaultPlcTagValueItem(newTag, value));
                     } else {
-                        updatedRequestItems.put(tagName, new TagValueItem(tag, value));
+                        updatedRequestItems.put(tagName, new DefaultPlcTagValueItem(tag, value));
                     }
                 }
 
@@ -1497,7 +1507,7 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
         // Start a new request-transaction (Is ended in the response-handler)
         RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
         // Send the request.
-        transaction.submit(() -> context.sendRequest(tpktPacket)
+        transaction.submit(() -> conversationContext.sendRequest(tpktPacket)
             .onTimeout(new TransactionErrorCallback<>(future, transaction))
             .onError(new TransactionErrorCallback<>(future, transaction))
             .expectResponse(TPKTPacket.class, REQUEST_TIMEOUT)
@@ -1716,7 +1726,7 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
     }
 
     private PlcResponse decodeReadResponse(S7Message responseMessage, PlcReadRequest plcReadRequest) throws PlcProtocolException {
-        Map<String, ResponseItem<PlcValue>> values = new HashMap<>();
+        Map<String, PlcResponseItem<PlcValue>> values = new HashMap<>();
         short errorClass;
         short errorCode;
 
@@ -1745,7 +1755,7 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
                 logger.warn("Got an error response from the PLC. This particular response code usually indicates " +
                     "that PUT/GET is not enabled on the PLC.");
                 for (String tagName : plcReadRequest.getTagNames()) {
-                    ResponseItem<PlcValue> result = new ResponseItem<>(PlcResponseCode.ACCESS_DENIED, new PlcNull());
+                    PlcResponseItem<PlcValue> result = new DefaultPlcResponseItem<>(PlcResponseCode.ACCESS_DENIED, new PlcNull());
                     values.put(tagName, result);
                 }
                 return new DefaultPlcReadResponse(plcReadRequest, values);
@@ -1754,7 +1764,7 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
                     "that we sent a too large packet or would be receiving a too large one. " +
                     "Please report this, as this is most probably a bug.");
                 for (String tagName : plcReadRequest.getTagNames()) {
-                    ResponseItem<PlcValue> result = new ResponseItem<>(PlcResponseCode.ACCESS_DENIED, new PlcNull());
+                    PlcResponseItem<PlcValue> result = new DefaultPlcResponseItem<>(PlcResponseCode.ACCESS_DENIED, new PlcNull());
                     values.put(tagName, result);
                 }
                 return new DefaultPlcReadResponse(plcReadRequest, values);
@@ -1765,7 +1775,7 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
                         "containing a capture of the communication.",
                     errorClass, errorCode);
                 for (String tagName : plcReadRequest.getTagNames()) {
-                    ResponseItem<PlcValue> result = new ResponseItem<>(PlcResponseCode.INTERNAL_ERROR, new PlcNull());
+                    PlcResponseItem<PlcValue> result = new DefaultPlcResponseItem<>(PlcResponseCode.INTERNAL_ERROR, new PlcNull());
                     values.put(tagName, result);
                 }
                 return new DefaultPlcReadResponse(plcReadRequest, values);
@@ -1875,7 +1885,7 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
                     plcValue = new PlcList(plcValues);
                 }
 
-                ResponseItem<PlcValue> result = new ResponseItem<>(responseCode, plcValue);
+                PlcResponseItem<PlcValue> result = new DefaultPlcResponseItem<>(responseCode, plcValue);
                 values.put(tagName, result);
                 index++;
             }
@@ -1913,7 +1923,7 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
                 }
             }
 
-            ResponseItem<PlcValue> result = new ResponseItem<>(responseCode, plcValue);
+            PlcResponseItem<PlcValue> result = new DefaultPlcResponseItem<>(responseCode, plcValue);
             values.put(tagName, result);
             index++;
         }
@@ -2059,7 +2069,7 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
                         }
                         return null;
                     }).toArray(PlcValue[]::new);
-                    return PlcValueHandler.of(resultItems);
+                    return DefaultPlcValueHandler.of(tag, resultItems);
                 }
             }
         } catch (ParseException e) {
@@ -2156,19 +2166,19 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
     }
 
     private boolean isConnected() {
-        return context.getChannel().attr(S7HMuxImpl.IS_CONNECTED).get();
+        return conversationContext.getChannel().attr(S7HMuxImpl.IS_CONNECTED).get();
         //return true;
     }
 
     private boolean isPrimaryChannel() {
-        return context.getChannel().attr(S7HMuxImpl.IS_PRIMARY).get() == null || context.getChannel().attr(S7HMuxImpl.IS_PRIMARY).get();
+        return conversationContext.getChannel().attr(S7HMuxImpl.IS_PRIMARY).get() == null || conversationContext.getChannel().attr(S7HMuxImpl.IS_PRIMARY).get();
     }
 
     private void setChannelFeatures() {
-        context.getChannel().attr(S7HMuxImpl.READ_TIME_OUT).set(s7DriverContext.getReadTimeout());
-        context.getChannel().attr(S7HMuxImpl.IS_PING_ACTIVE).set(s7DriverContext.getPing());
-        context.getChannel().attr(S7HMuxImpl.PING_TIME).set(s7DriverContext.getPingTime());
-        context.getChannel().attr(S7HMuxImpl.RETRY_TIME).set(s7DriverContext.getRetryTime());
+        conversationContext.getChannel().attr(S7HMuxImpl.READ_TIME_OUT).set(s7DriverContext.getReadTimeout());
+        conversationContext.getChannel().attr(S7HMuxImpl.IS_PING_ACTIVE).set(s7DriverContext.getPing());
+        conversationContext.getChannel().attr(S7HMuxImpl.PING_TIME).set(s7DriverContext.getPingTime());
+        conversationContext.getChannel().attr(S7HMuxImpl.RETRY_TIME).set(s7DriverContext.getRetryTime());
     }
 
 
@@ -2186,7 +2196,7 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
 
         TPKTPacket request = createSzlReassembledRequest(tpduId, sequenceNumber);
 
-        context.sendRequest(request)
+        conversationContext.sendRequest(request)
             .onTimeout(e -> {
                 logger.warn("Timeout during Connection establishing, closing channel...");
                 //context.getChannel().close();
@@ -2226,7 +2236,7 @@ public class S7ProtocolLogic extends Plc4xProtocolBase<TPKTPacket> {
 
         TPKTPacket request = createAlarmQueryReassembledRequest(tpduId, sequenceNumber);
 
-        context.sendRequest(request)
+        conversationContext.sendRequest(request)
             .onTimeout(e -> {
                 logger.warn("Timeout during Connection establishing, closing channel...");
                 //context.getChannel().close();
diff --git a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/tag/S7Tag.java b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/tag/S7Tag.java
index 6f9265c21e..c494dc881d 100644
--- a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/tag/S7Tag.java
+++ b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/tag/S7Tag.java
@@ -148,7 +148,11 @@ public class S7Tag implements PlcTag, Serializable {
     public static S7Tag of(String tagString) {
         Matcher matcher;
         if ((matcher = DATA_BLOCK_ADDRESS_PATTERN.matcher(tagString)).matches()) {
-            TransportSize dataType = TransportSize.valueOf(matcher.group(DATA_TYPE));
+            String dataTypeName = matcher.group(DATA_TYPE);
+            if("RAW_BYTE_ARRAY".equals(dataTypeName)) {
+                dataTypeName = "BYTE";
+            }
+            TransportSize dataType = TransportSize.valueOf(dataTypeName);
             MemoryArea memoryArea = MemoryArea.DATA_BLOCKS;
             Short transferSizeCode = getSizeCode(matcher.group(TRANSFER_SIZE_CODE));
             int blockNumber = checkDataBlockNumber(Integer.parseInt(matcher.group(BLOCK_NUMBER)));
@@ -171,7 +175,11 @@ public class S7Tag implements PlcTag, Serializable {
 
             return new S7Tag(dataType, memoryArea, blockNumber, byteOffset, bitOffset, numElements);
         } else if ((matcher = DATA_BLOCK_SHORT_PATTERN.matcher(tagString)).matches()) {
-            TransportSize dataType = TransportSize.valueOf(matcher.group(DATA_TYPE));
+            String dataTypeName = matcher.group(DATA_TYPE);
+            if("RAW_BYTE_ARRAY".equals(dataTypeName)) {
+                dataTypeName = "BYTE";
+            }
+            TransportSize dataType = TransportSize.valueOf(dataTypeName);
             MemoryArea memoryArea = MemoryArea.DATA_BLOCKS;
             int blockNumber = checkDataBlockNumber(Integer.parseInt(matcher.group(BLOCK_NUMBER)));
             int byteOffset = checkByteOffset(Integer.parseInt(matcher.group(BYTE_OFFSET)));
diff --git a/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/DatatypesTest.java b/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/DatatypesTest.java
index 3f05a90bdb..45d58e3309 100644
--- a/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/DatatypesTest.java
+++ b/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/DatatypesTest.java
@@ -56,7 +56,7 @@ public class DatatypesTest {
             builder.addTagAddress("lreal-value", "%DB2:70:LREAL"); // 3.14159265358979
             builder.addTagAddress("lreal-array", "%DB2:78:LREAL[2]"); // 1.2345, -1.2345
             builder.addTagAddress("string-value", "%DB2:94:STRING(10)"); // "Hurz"
-            // When reading a sized STRING string array, this has to be translated into multiple items
+            // When reading a sized STRING array, this has to be translated into multiple items
             //builder.addField("string-array", "%DB2:350:STRING(10)[2]"); // "Wolf", "Lamm"
             builder.addTagAddress("time-value", "%DB2:862:TIME"); // 1234ms
             builder.addTagAddress("time-array", "%DB2:866:TIME[2]"); // 123ms, 234ms
diff --git a/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/ManualS71200DriverTest.java b/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/ManualS71200DriverTest.java
index b9ba226280..c02494d9be 100644
--- a/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/ManualS71200DriverTest.java
+++ b/plc4j/drivers/s7/src/test/java/org/apache/plc4x/java/s7/readwrite/ManualS71200DriverTest.java
@@ -68,7 +68,7 @@ public class ManualS71200DriverTest extends ManualTest {
      */
 
     public ManualS71200DriverTest(String connectionString) {
-        super(connectionString);
+        super(connectionString, true, true, true, true, 100);
     }
 
     public static void main(String[] args) throws Exception {
@@ -95,7 +95,7 @@ public class ManualS71200DriverTest extends ManualTest {
         test.addTestCase("%DB4:70:DATE", new PlcDATE(LocalDate.parse("1998-03-28")));
         test.addTestCase("%DB4:72:TIME_OF_DAY", new PlcTIME_OF_DAY(LocalTime.parse("15:36:30.123")));
         test.addTestCase("%DB4:908:CHAR[5]", new PlcList(Arrays.asList(new PlcCHAR("w"), new PlcCHAR("i"), new PlcCHAR("e"), new PlcCHAR("s"), new PlcCHAR("e"))));
-        test.addTestCase("%DB4:914:BYTE[11]", new PlcRawByteArray(new byte[] {(byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9, (byte) 10, (byte) 11}));
+        test.addTestCase("%DB4:914:RAW_BYTE_ARRAY[11]", new PlcRawByteArray(new byte[] {(byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9, (byte) 10, (byte) 11}));
 
         long start = System.currentTimeMillis();
         test.run();
diff --git a/plc4j/drivers/s7/src/test/resources/logback-test.xml b/plc4j/drivers/s7/src/test/resources/logback-test.xml
index 33ae65561c..16b83b4882 100644
--- a/plc4j/drivers/s7/src/test/resources/logback-test.xml
+++ b/plc4j/drivers/s7/src/test/resources/logback-test.xml
@@ -27,7 +27,7 @@
     </encoder>
   </appender>
 
-  <root level="error">
+  <root level="warn">
     <appender-ref ref="STDOUT" />
   </root>
 
diff --git a/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/connection/SimulatedConnection.java b/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/connection/SimulatedConnection.java
index 042393bf0f..a14e41fd9a 100644
--- a/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/connection/SimulatedConnection.java
+++ b/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/connection/SimulatedConnection.java
@@ -27,11 +27,13 @@ import org.apache.plc4x.java.api.value.PlcValue;
 import org.apache.plc4x.java.simulated.tag.SimulatedTag;
 import org.apache.plc4x.java.simulated.tag.SimulatedTagHandler;
 import org.apache.plc4x.java.spi.connection.AbstractPlcConnection;
+import org.apache.plc4x.java.spi.connection.PlcTagHandler;
 import org.apache.plc4x.java.spi.messages.*;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem;
 import org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration;
 import org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionHandle;
-import org.apache.plc4x.java.spi.values.PlcValueHandler;
+import org.apache.plc4x.java.spi.values.DefaultPlcValueHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -64,10 +66,15 @@ public class SimulatedConnection extends AbstractPlcConnection implements PlcRea
 
     public SimulatedConnection(SimulatedDevice device) {
         super(true, true, true, true, false,
-            new SimulatedTagHandler(), new PlcValueHandler(), null, null);
+            new DefaultPlcValueHandler(), null, null);
         this.device = device;
     }
 
+    @Override
+    public PlcTagHandler getPlcTagHandler() {
+        return new SimulatedTagHandler();
+    }
+
     @Override
     public void connect() {
         connected = true;
@@ -91,15 +98,15 @@ public class SimulatedConnection extends AbstractPlcConnection implements PlcRea
 
     @Override
     public CompletableFuture<PlcReadResponse> read(PlcReadRequest readRequest) {
-        Map<String, ResponseItem<PlcValue>> tags = new HashMap<>();
+        Map<String, PlcResponseItem<PlcValue>> tags = new HashMap<>();
         for (String tagName : readRequest.getTagNames()) {
             SimulatedTag tag = (SimulatedTag) readRequest.getTag(tagName);
             Optional<PlcValue> valueOptional = device.get(tag);
-            ResponseItem<PlcValue> tagPair;
+            PlcResponseItem<PlcValue> tagPair;
             boolean present = valueOptional.isPresent();
             tagPair = present
-                ? new ResponseItem<>(PlcResponseCode.OK, valueOptional.get())
-                : new ResponseItem<>(PlcResponseCode.NOT_FOUND, null);
+                ? new DefaultPlcResponseItem<>(PlcResponseCode.OK, valueOptional.get())
+                : new DefaultPlcResponseItem<>(PlcResponseCode.NOT_FOUND, null);
             tags.put(tagName, tagPair);
         }
         PlcReadResponse response = new DefaultPlcReadResponse(readRequest, tags);
@@ -110,10 +117,14 @@ public class SimulatedConnection extends AbstractPlcConnection implements PlcRea
     public CompletableFuture<PlcWriteResponse> write(PlcWriteRequest writeRequest) {
         Map<String, PlcResponseCode> tags = new HashMap<>();
         for (String tagName : writeRequest.getTagNames()) {
-            SimulatedTag tag = (SimulatedTag) writeRequest.getTag(tagName);
-            PlcValue value = writeRequest.getPlcValue(tagName);
-            device.set(tag, value);
-            tags.put(tagName, PlcResponseCode.OK);
+            if(writeRequest.getTagResponseCode(tagName) == PlcResponseCode.OK) {
+                SimulatedTag tag = (SimulatedTag) writeRequest.getTag(tagName);
+                PlcValue value = writeRequest.getPlcValue(tagName);
+                device.set(tag, value);
+                tags.put(tagName, PlcResponseCode.OK);
+            } else {
+                tags.put(tagName, writeRequest.getTagResponseCode(tagName));
+            }
         }
         PlcWriteResponse response = new DefaultPlcWriteResponse(writeRequest, tags);
         return CompletableFuture.completedFuture(response);
@@ -133,7 +144,7 @@ public class SimulatedConnection extends AbstractPlcConnection implements PlcRea
     @Override
     public CompletableFuture<PlcSubscriptionResponse> subscribe(PlcSubscriptionRequest subscriptionRequest) {
         LOGGER.info("subscribing {}", subscriptionRequest);
-        Map<String, ResponseItem<PlcSubscriptionHandle>> values = new HashMap<>();
+        Map<String, PlcResponseItem<PlcSubscriptionHandle>> values = new HashMap<>();
         subscriptionRequest.getTagNames().forEach(name -> {
             LOGGER.info("creating handle for tag name {}", name);
             PlcSubscriptionHandle handle = new DefaultPlcSubscriptionHandle(this);
@@ -152,7 +163,7 @@ public class SimulatedConnection extends AbstractPlcConnection implements PlcRea
                     device.addEventSubscription(dispatchSubscriptionEvent(name, handle), handle, subscriptionTag);
                     break;
             }
-            values.put(name, new ResponseItem<>(PlcResponseCode.OK, handle));
+            values.put(name, new DefaultPlcResponseItem<>(PlcResponseCode.OK, handle));
         });
 
         PlcSubscriptionResponse response = new DefaultPlcSubscriptionResponse(subscriptionRequest, values);
@@ -176,7 +187,7 @@ public class SimulatedConnection extends AbstractPlcConnection implements PlcRea
             consumer.accept(
                 new DefaultPlcSubscriptionEvent(
                     Instant.now(),
-                    Collections.singletonMap(name, new ResponseItem<>(PlcResponseCode.OK, plcValue))
+                    Collections.singletonMap(name, new DefaultPlcResponseItem<>(PlcResponseCode.OK, plcValue))
                 )
             );
         };
diff --git a/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/tag/SimulatedTag.java b/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/tag/SimulatedTag.java
index c329236710..71adb0f27f 100644
--- a/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/tag/SimulatedTag.java
+++ b/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/tag/SimulatedTag.java
@@ -93,7 +93,7 @@ public class SimulatedTag implements PlcTag {
 
     @Override
     public List<ArrayInfo> getArrayInfo() {
-        return Collections.singletonList(new DefaultArrayInfo(0, numElements));
+        return Collections.singletonList(new DefaultArrayInfo(0, numElements - 1));
     }
 
     public SimulatedTagType getType() {
diff --git a/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/tag/SimulatedTagHandler.java b/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/tag/SimulatedTagHandler.java
index 20981fa7e8..0e7039f60e 100644
--- a/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/tag/SimulatedTagHandler.java
+++ b/plc4j/drivers/simulated/src/main/java/org/apache/plc4x/java/simulated/tag/SimulatedTagHandler.java
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *   https://www.apache.org/licenses/LICENSE-2.0
+ *   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
@@ -16,11 +16,12 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
 package org.apache.plc4x.java.simulated.tag;
 
 import org.apache.plc4x.java.api.exceptions.PlcInvalidTagException;
-import org.apache.plc4x.java.api.model.PlcTag;
 import org.apache.plc4x.java.api.model.PlcQuery;
+import org.apache.plc4x.java.api.model.PlcTag;
 import org.apache.plc4x.java.spi.connection.PlcTagHandler;
 
 public class SimulatedTagHandler implements PlcTagHandler {
diff --git a/plc4j/drivers/simulated/src/test/java/org/apache/plc4x/java/simulated/connection/SimulatedConnectionTest.java b/plc4j/drivers/simulated/src/test/java/org/apache/plc4x/java/simulated/connection/SimulatedConnectionTest.java
index ed4cb33891..0b2bb2c810 100644
--- a/plc4j/drivers/simulated/src/test/java/org/apache/plc4x/java/simulated/connection/SimulatedConnectionTest.java
+++ b/plc4j/drivers/simulated/src/test/java/org/apache/plc4x/java/simulated/connection/SimulatedConnectionTest.java
@@ -163,7 +163,7 @@ class SimulatedConnectionTest implements WithAssertions {
                 .addTagAddress("state", "STATE/state:STRING", "initialstate")
                 .addTagAddress("event", "STATE/event:STRING", "initialevent")
                 .build();
-            SUT.write(plcWriteRequest).get(1, TimeUnit.SECONDS);
+            PlcWriteResponse plcWriteResponse = SUT.write(plcWriteRequest).get(1, TimeUnit.SECONDS);
             // Note: as we don't have a subscription yet, no callback will be executed
 
             LOGGER.trace("subscribe");
diff --git a/plc4j/drivers/simulated/src/test/java/org/apache/plc4x/java/simulated/tag/SimularedTagHandlerTest.java b/plc4j/drivers/simulated/src/test/java/org/apache/plc4x/java/simulated/tag/SimularedTagHandlerTest.java
deleted file mode 100644
index c570d57015..0000000000
--- a/plc4j/drivers/simulated/src/test/java/org/apache/plc4x/java/simulated/tag/SimularedTagHandlerTest.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * 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
- *
- *   https://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.
- */
-package org.apache.plc4x.java.simulated.tag;
-
-import org.apache.plc4x.java.simulated.tag.SimulatedTag;
-import org.apache.plc4x.java.simulated.tag.SimulatedTagHandler;
-import org.assertj.core.api.WithAssertions;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
-
-@ExtendWith(MockitoExtension.class)
-class SimularedTagHandlerTest implements WithAssertions {
-
-    final SimulatedTagHandler SUT = new SimulatedTagHandler();
-
-    @Mock
-    SimulatedTag plcTag;
-
-    @Test
-    void createTag() {
-        assertThat(SUT.parseTag("STATE/bar:DINT")).isNotNull();
-    }
-
-    /*@Test
-    void encodeBoolean() {
-        assertThat(SUT.encodeBoolean(plcTag, new Boolean[0])).isNotNull();
-    }
-
-    @Test
-    void encodeByte() {
-        when(plcTag.getPlcDataType()).thenReturn("Byte");
-        assertThat(SUT.encodeByte(plcTag, new Byte[0])).isNotNull();
-    }
-
-    @Test
-    void encodeShort() {
-        when(plcTag.getPlcDataType()).thenReturn("Short");
-        assertThat(SUT.encodeShort(plcTag, new Short[0])).isNotNull();
-    }
-
-    @Test
-    void encodeInteger() {
-        when(plcTag.getPlcDataType()).thenReturn("Integer");
-        assertThat(SUT.encodeInteger(plcTag, new Integer[0])).isNotNull();
-    }
-
-    @Test
-    void encodeBigInteger() {
-        when(plcTag.getPlcDataType()).thenReturn("BigInteger");
-        assertThat(SUT.encodeBigInteger(plcTag, new BigInteger[0])).isNotNull();
-    }
-
-    @Test
-    void encodeLong() {
-        when(plcTag.getPlcDataType()).thenReturn("Long");
-        assertThat(SUT.encodeLong(plcTag, new Long[0])).isNotNull();
-    }
-
-    @Test
-    void encodeFloat() {
-        when(plcTag.getPlcDataType()).thenReturn("Float");
-        assertThat(SUT.encodeFloat(plcTag, new Float[0])).isNotNull();
-    }
-
-    @Test
-    void encodeBigDecimal() {
-        when(plcTag.getPlcDataType()).thenReturn("BigDecimal");
-        assertThat(SUT.encodeBigDecimal(plcTag, new BigDecimal[0])).isNotNull();
-    }
-
-    @Test
-    void encodeDouble() {
-        when(plcTag.getPlcDataType()).thenReturn("Double");
-        assertThat(SUT.encodeDouble(plcTag, new Double[0])).isNotNull();
-    }
-
-    @Test
-    void encodeString() {
-        when(plcTag.getPlcDataType()).thenReturn("String");
-        assertThat(SUT.encodeString(plcTag, new String[0])).isNotNull();
-    }
-
-    @Test
-    void encodeTime() {
-        when(plcTag.getPlcDataType()).thenReturn("LocalTime");
-        assertThat(SUT.encodeTime(plcTag, new LocalTime[0])).isNotNull();
-    }
-
-    @Test
-    void encodeDate() {
-        when(plcTag.getPlcDataType()).thenReturn("LocalDate");
-        assertThat(SUT.encodeDate(plcTag, new LocalDate[0])).isNotNull();
-    }
-
-    @Test
-    void encodeDateTime() {
-        when(plcTag.getPlcDataType()).thenReturn("LocalDateTime");
-        assertThat(SUT.encodeDateTime(plcTag, new LocalDateTime[0])).isNotNull();
-    }*/
-
-}
diff --git a/plc4j/drivers/simulated/src/test/java/org/apache/plc4x/java/simulated/tag/SimulatedTagTest.java b/plc4j/drivers/simulated/src/test/java/org/apache/plc4x/java/simulated/tag/SimulatedTagTest.java
index a8a9b658f2..6bedd43518 100644
--- a/plc4j/drivers/simulated/src/test/java/org/apache/plc4x/java/simulated/tag/SimulatedTagTest.java
+++ b/plc4j/drivers/simulated/src/test/java/org/apache/plc4x/java/simulated/tag/SimulatedTagTest.java
@@ -20,7 +20,6 @@ package org.apache.plc4x.java.simulated.tag;
 
 import nl.jqno.equalsverifier.EqualsVerifier;
 import org.apache.plc4x.java.api.exceptions.PlcInvalidTagException;
-import org.apache.plc4x.java.simulated.tag.SimulatedTag;
 import org.apache.plc4x.java.simulated.types.SimulatedTagType;
 import org.junit.jupiter.api.Test;
 
diff --git a/plc4j/drivers/simulated/src/test/resources/logback-test.xml b/plc4j/drivers/simulated/src/test/resources/logback-test.xml
index 2b9cea25dc..941f1546f8 100644
--- a/plc4j/drivers/simulated/src/test/resources/logback-test.xml
+++ b/plc4j/drivers/simulated/src/test/resources/logback-test.xml
@@ -29,7 +29,7 @@
     </encoder>
   </appender>
 
-  <root level="error">
+  <root level="warn">
     <appender-ref ref="STDOUT" />
   </root>
 
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/ConversationContext.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/ConversationContext.java
index 5086893b92..a37b08548d 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/ConversationContext.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/ConversationContext.java
@@ -24,6 +24,7 @@ import org.apache.plc4x.java.spi.configuration.PlcConnectionConfiguration;
 import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
 
 import java.time.Duration;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeoutException;
 import java.util.function.BiConsumer;
@@ -84,6 +85,8 @@ public interface ConversationContext<T> {
          */
         ContextHandler handle(Consumer<T> packetConsumer);
 
+        CompletableFuture<T> toFuture();
+
         /**
          * allows to define a timeout handler which then calls {@code packetConsumer}
          *
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/Plc4xNettyWrapper.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/Plc4xNettyWrapper.java
index 838c9f8e4c..2f93345cfb 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/Plc4xNettyWrapper.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/Plc4xNettyWrapper.java
@@ -75,7 +75,7 @@ public class Plc4xNettyWrapper<T> extends MessageToMessageCodec<T, Object> {
         this.protocolBase = protocol;
         this.authentication = authentication;
         this.timeoutManager = timeoutManager;
-        this.protocolBase.setContext(new ConversationContext<T>() {
+        this.protocolBase.setConversationContext(new ConversationContext<T>() {
 
             @Override
             public PlcAuthentication getAuthentication() {
@@ -188,7 +188,9 @@ public class Plc4xNettyWrapper<T> extends MessageToMessageCodec<T, Object> {
                 } catch (Exception e) {
                     logger.trace("Failure while processing payload {} with handler {}", message, registration, e);
                     BiConsumer biConsumer = registration.getErrorConsumer();
-                    biConsumer.accept(message, e);
+                    if(biConsumer != null) {
+                        biConsumer.accept(message, e);
+                    }
                     registration.confirmError();
                 }
                 return;
@@ -218,7 +220,6 @@ public class Plc4xNettyWrapper<T> extends MessageToMessageCodec<T, Object> {
 
     /**
      * Performs registration of packet handler and makes sure that its timeout will be handled properly.
-     *
      * Since timeouts are controlled by {@link TimeoutManager} there is a need to decorate handler
      * operations so both sides know what's going on.
      *
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/Plc4xProtocolBase.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/Plc4xProtocolBase.java
index 95ace093fd..965fe33da4 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/Plc4xProtocolBase.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/Plc4xProtocolBase.java
@@ -20,13 +20,14 @@ package org.apache.plc4x.java.spi;
 
 import org.apache.commons.lang3.NotImplementedException;
 import org.apache.plc4x.java.api.messages.*;
+import org.apache.plc4x.java.spi.connection.PlcTagHandler;
 import org.apache.plc4x.java.spi.context.DriverContext;
 
 import java.util.concurrent.CompletableFuture;
 
 public abstract class Plc4xProtocolBase<T> {
 
-    protected ConversationContext<T> context;
+    protected ConversationContext<T> conversationContext;
 
     protected DriverContext driverContext;
 
@@ -38,8 +39,12 @@ public abstract class Plc4xProtocolBase<T> {
         return driverContext;
     }
 
-    public void setContext(ConversationContext<T> context) {
-        this.context = context;
+    public void setConversationContext(ConversationContext<T> conversationContext) {
+        this.conversationContext = conversationContext;
+    }
+
+    public ConversationContext<T> getConversationContext() {
+        return conversationContext;
     }
 
     public void onConnect(ConversationContext<T> context) {
@@ -54,10 +59,10 @@ public abstract class Plc4xProtocolBase<T> {
         // Intentionally do nothing here
     }
 
+    public abstract PlcTagHandler getTagHandler();
+
     /**
-     * TODO document me
-     * <p>
-     * Can be used for non requested incoming messages
+     * Default callback, called if an incoming message can't be correlated with an expected response.
      *
      * @param context
      * @param msg
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/AbstractPlcConnection.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/AbstractPlcConnection.java
index b9d2545432..6ac2ef2e8b 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/AbstractPlcConnection.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/AbstractPlcConnection.java
@@ -21,17 +21,19 @@ package org.apache.plc4x.java.spi.connection;
 import org.apache.commons.lang3.NotImplementedException;
 import org.apache.plc4x.java.api.PlcConnection;
 import org.apache.plc4x.java.api.authentication.PlcAuthentication;
+import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
 import org.apache.plc4x.java.api.exceptions.PlcUnsupportedOperationException;
 import org.apache.plc4x.java.api.messages.*;
 import org.apache.plc4x.java.api.metadata.PlcConnectionMetadata;
 import org.apache.plc4x.java.api.model.PlcConsumerRegistration;
 import org.apache.plc4x.java.api.model.PlcSubscriptionHandle;
 import org.apache.plc4x.java.api.model.PlcTag;
+import org.apache.plc4x.java.api.value.PlcValue;
 import org.apache.plc4x.java.spi.Plc4xProtocolBase;
 import org.apache.plc4x.java.spi.generation.Message;
 import org.apache.plc4x.java.spi.messages.*;
 import org.apache.plc4x.java.spi.optimizer.BaseOptimizer;
-import org.apache.plc4x.java.api.value.PlcValueHandler;
+import org.apache.plc4x.java.spi.values.PlcValueHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -55,29 +57,21 @@ public abstract class AbstractPlcConnection implements PlcConnection, PlcConnect
     private boolean canWrite = false;
     private boolean canSubscribe = false;
     private boolean canBrowse = false;
-    private PlcTagHandler tagHandler;
-    private PlcValueHandler valueHandler;
+    private final PlcValueHandler valueHandler;
+    private final BaseOptimizer optimizer;
+    private final PlcAuthentication authentication;
     private Plc4xProtocolBase<? extends Message> protocol;
-    private BaseOptimizer optimizer;
-    private PlcAuthentication authentication;
-
-    /**
-     * @deprecated only for compatibility reasons.
-     */
-    @Deprecated
-    protected AbstractPlcConnection() {
-    }
+    private PlcTagHandler tagHandler;
 
     protected AbstractPlcConnection(boolean canPing, boolean canRead, boolean canWrite,
                                     boolean canSubscribe, boolean canBrowse,
-                                    PlcTagHandler tagHandler, PlcValueHandler valueHandler,
+                                    PlcValueHandler valueHandler,
                                     BaseOptimizer optimizer, PlcAuthentication authentication) {
         this.canPing = canPing;
         this.canRead = canRead;
         this.canWrite = canWrite;
         this.canSubscribe = canSubscribe;
         this.canBrowse = canBrowse;
-        this.tagHandler = tagHandler;
         this.valueHandler = valueHandler;
         this.optimizer = optimizer;
         this.authentication = authentication;
@@ -85,6 +79,7 @@ public abstract class AbstractPlcConnection implements PlcConnection, PlcConnect
 
     public void setProtocol(Plc4xProtocolBase<? extends Message> protocol) {
         this.protocol = protocol;
+        this.tagHandler = protocol.getTagHandler();
     }
 
     public Plc4xProtocolBase<? extends Message> getProtocol() {
@@ -103,6 +98,7 @@ public abstract class AbstractPlcConnection implements PlcConnection, PlcConnect
         return future;
     }
 
+
     @Override
     public boolean isReadSupported() {
         return canRead;
@@ -241,9 +237,20 @@ public abstract class AbstractPlcConnection implements PlcConnection, PlcConnect
         try {
             plcTag = tagHandler.parseTag(tagAddress);
         } catch (Exception e) {
-            logger.error("Error parsing tag address {}", tagAddress);
-            return Optional.empty();
+            throw new PlcRuntimeException("Error parsing tag address: " + tagAddress, e);
         }
         return Optional.ofNullable(plcTag);
     }
+
+    @Override
+    public Optional<PlcValue> parseTagValue(PlcTag tag, Object... values) {
+        PlcValue plcValue;
+        try {
+            plcValue = valueHandler.newPlcValue(tag, values);
+        } catch (Exception e) {
+            throw new PlcRuntimeException("Error parsing tag value " + tag, e);
+        }
+        return Optional.of(plcValue);
+    }
+
 }
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/DefaultNettyPlcConnection.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/DefaultNettyPlcConnection.java
index 147b6db3ce..686fb36a3a 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/DefaultNettyPlcConnection.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/DefaultNettyPlcConnection.java
@@ -28,11 +28,11 @@ import org.apache.plc4x.java.api.exceptions.PlcIoException;
 import org.apache.plc4x.java.api.listener.ConnectionStateListener;
 import org.apache.plc4x.java.api.listener.EventListener;
 import org.apache.plc4x.java.api.messages.PlcPingResponse;
-import org.apache.plc4x.java.api.value.PlcValueHandler;
 import org.apache.plc4x.java.spi.configuration.ConfigurationFactory;
 import org.apache.plc4x.java.spi.events.*;
 import org.apache.plc4x.java.spi.messages.DefaultPlcPingRequest;
 import org.apache.plc4x.java.spi.optimizer.BaseOptimizer;
+import org.apache.plc4x.java.spi.values.PlcValueHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -66,7 +66,6 @@ public class DefaultNettyPlcConnection extends AbstractPlcConnection implements
                                      boolean canWrite,
                                      boolean canSubscribe,
                                      boolean canBrowse,
-                                     PlcTagHandler tagHandler,
                                      PlcValueHandler valueHandler,
                                      PlcConnectionConfiguration configuration,
                                      ChannelFactory channelFactory,
@@ -77,7 +76,7 @@ public class DefaultNettyPlcConnection extends AbstractPlcConnection implements
                                      ProtocolStackConfigurer<?> stackConfigurer,
                                      BaseOptimizer optimizer,
                                      PlcAuthentication authentication) {
-        super(canPing, canRead, canWrite, canSubscribe, canBrowse, tagHandler, valueHandler, optimizer, authentication);
+        super(canPing, canRead, canWrite, canSubscribe, canBrowse, valueHandler, optimizer, authentication);
         this.configuration = configuration;
         this.channelFactory = channelFactory;
         this.fireDiscoverEvent = fireDiscoverEvent;
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/GeneratedDriverBase.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/GeneratedDriverBase.java
index 8c037d908b..c8a85f2c22 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/GeneratedDriverBase.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/GeneratedDriverBase.java
@@ -29,7 +29,6 @@ import org.apache.plc4x.java.api.metadata.Option;
 import org.apache.plc4x.java.api.metadata.OptionMetadata;
 import org.apache.plc4x.java.api.types.OptionType;
 import org.apache.plc4x.java.api.metadata.PlcDriverMetadata;
-import org.apache.plc4x.java.api.value.PlcValueHandler;
 import org.apache.plc4x.java.spi.configuration.ConfigurationFactory;
 import org.apache.plc4x.java.spi.configuration.annotations.*;
 import org.apache.plc4x.java.spi.configuration.annotations.defaults.*;
@@ -38,6 +37,8 @@ import org.apache.plc4x.java.spi.metadata.DefaultOption;
 import org.apache.plc4x.java.spi.metadata.DefaultOptionMetadata;
 import org.apache.plc4x.java.spi.optimizer.BaseOptimizer;
 import org.apache.plc4x.java.spi.transport.Transport;
+import org.apache.plc4x.java.spi.values.DefaultPlcValueHandler;
+import org.apache.plc4x.java.spi.values.PlcValueHandler;
 
 import java.lang.reflect.Field;
 import java.util.*;
@@ -284,9 +285,9 @@ public abstract class GeneratedDriverBase<BASE_PACKET extends Message> implement
         return null;
     }
 
-    protected abstract PlcTagHandler getTagHandler();
-
-    protected abstract PlcValueHandler getValueHandler();
+    protected PlcValueHandler getValueHandler() {
+        return new DefaultPlcValueHandler();
+    }
 
     protected abstract ProtocolStackConfigurer<BASE_PACKET> getStackConfigurer();
 
@@ -397,7 +398,6 @@ public abstract class GeneratedDriverBase<BASE_PACKET extends Message> implement
 
         return new DefaultNettyPlcConnection(
             canPing(), canRead(), canWrite(), canSubscribe(), canBrowse(),
-            getTagHandler(),
             getValueHandler(),
             configuration,
             channelFactory,
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/internal/DefaultSendRequestContext.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/internal/DefaultSendRequestContext.java
index 73af4d3a9e..6709e3effc 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/internal/DefaultSendRequestContext.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/internal/DefaultSendRequestContext.java
@@ -24,6 +24,7 @@ import org.apache.plc4x.java.spi.ConversationContext;
 import java.time.Duration;
 import java.util.Deque;
 import java.util.LinkedList;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.TimeoutException;
 import java.util.function.BiConsumer;
 import java.util.function.Consumer;
@@ -108,6 +109,13 @@ public class DefaultSendRequestContext<T> implements ConversationContext.SendReq
         return new DefaultContextHandler(registration, registration::cancel);
     }
 
+    @Override
+    public CompletableFuture<T> toFuture() {
+        CompletableFuture<T> future = new CompletableFuture<>();
+        handle(future::complete);
+        return future;
+    }
+
     @Override
     public ConversationContext.SendRequestContext<T> onTimeout(Consumer<TimeoutException> onTimeoutConsumer) {
         if (this.onTimeoutConsumer != null && !(this.onTimeoutConsumer instanceof NoopTimeoutConsumer)) {
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcBrowseItem.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcBrowseItem.java
index 72b1a5a2fc..304737b5aa 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcBrowseItem.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcBrowseItem.java
@@ -137,7 +137,7 @@ public class DefaultPlcBrowseItem implements PlcBrowseItem, Serializable {
 
     @Override
     public void serialize(WriteBuffer writeBuffer) throws SerializationException {
-        writeBuffer.pushContext(getClass().getSimpleName());
+        writeBuffer.pushContext("PlcBrowseItem");
         writeBuffer.writeString("address",
             tag.getAddressString().getBytes(StandardCharsets.UTF_8).length * 8,
             tag.getAddressString(), WithOption.WithEncoding(StandardCharsets.UTF_8.name()));
@@ -169,7 +169,7 @@ public class DefaultPlcBrowseItem implements PlcBrowseItem, Serializable {
             }
             writeBuffer.popContext("options");
         }
-        writeBuffer.popContext(getClass().getSimpleName());
+        writeBuffer.popContext("PlcBrowseItem");
     }
 
 }
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultListPlcBrowseItem.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcBrowseItemList.java
similarity index 92%
rename from plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultListPlcBrowseItem.java
rename to plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcBrowseItemList.java
index 56663f354d..50ad9363a4 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultListPlcBrowseItem.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcBrowseItemList.java
@@ -27,15 +27,14 @@ import org.apache.plc4x.java.spi.generation.SerializationException;
 import org.apache.plc4x.java.spi.generation.WriteBuffer;
 
 import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
-public class DefaultListPlcBrowseItem extends DefaultPlcBrowseItem {
+public class DefaultPlcBrowseItemList extends DefaultPlcBrowseItem {
 
     private final List<PlcBrowseItemArrayInfo> arrayInformation;
 
-    public DefaultListPlcBrowseItem(PlcTag tag,
+    public DefaultPlcBrowseItemList(PlcTag tag,
                                     String name,
                                     boolean readable,
                                     boolean writable,
@@ -80,7 +79,7 @@ public class DefaultListPlcBrowseItem extends DefaultPlcBrowseItem {
 
     @Override
     public void serialize(WriteBuffer writeBuffer) throws SerializationException {
-        writeBuffer.pushContext(getClass().getSimpleName());
+        writeBuffer.pushContext("PlcBrowseItemList");
         writeBuffer.writeString("address",
             getTag().getAddressString().getBytes(StandardCharsets.UTF_8).length * 8,
             getTag().getAddressString(), WithOption.WithEncoding(StandardCharsets.UTF_8.name()));
@@ -93,7 +92,7 @@ public class DefaultListPlcBrowseItem extends DefaultPlcBrowseItem {
             writeBuffer.pushContext("children");
             for (PlcBrowseItem child : getChildren().values()) {
                 writeBuffer.pushContext("child");
-                ((DefaultListPlcBrowseItem) child).serialize(writeBuffer);
+                ((DefaultPlcBrowseItemList) child).serialize(writeBuffer);
                 writeBuffer.popContext("child");
             }
             writeBuffer.popContext("children");
@@ -107,12 +106,12 @@ public class DefaultListPlcBrowseItem extends DefaultPlcBrowseItem {
                     optionEntry.getKey(), WithOption.WithEncoding(StandardCharsets.UTF_8.name()));
                 // TODO: Find out how to serialize a PlcValue
                 //writeBuffer.writeString("value", optionEntry.getValue().getBytes(StandardCharsets.UTF_8).length * 8, StandardCharsets.UTF_8.name(), optionEntry.getValue());
-                ((DefaultListPlcBrowseItem) optionEntry).serialize(writeBuffer);
+                ((DefaultPlcBrowseItemList) optionEntry).serialize(writeBuffer);
                 writeBuffer.popContext("option");
             }
             writeBuffer.popContext("options");
         }
-        writeBuffer.popContext(getClass().getSimpleName());
+        writeBuffer.popContext("PlcBrowseItemList");
     }
 
 }
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcBrowseRequest.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcBrowseRequest.java
index 14e523c2a2..efc6bb8c2e 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcBrowseRequest.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcBrowseRequest.java
@@ -28,6 +28,7 @@ import org.apache.plc4x.java.spi.utils.Serializable;
 
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
+import java.util.Objects;
 import java.util.concurrent.CompletableFuture;
 import java.util.function.Supplier;
 
@@ -80,8 +81,8 @@ public class DefaultPlcBrowseRequest implements PlcBrowseRequest, Serializable {
         private final LinkedHashMap<String, Supplier<PlcQuery>> queries;
 
         public Builder(PlcBrowser browser, PlcTagHandler tagHandler) {
-            this.browser = browser;
-            this.tagHandler = tagHandler;
+            this.browser = Objects.requireNonNull(browser);
+            this.tagHandler = Objects.requireNonNull(tagHandler);
             queries = new LinkedHashMap<>();
         }
 
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcDiscoveryItem.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcDiscoveryItem.java
index bc3b6855a5..0aecb61003 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcDiscoveryItem.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcDiscoveryItem.java
@@ -103,7 +103,7 @@ public class DefaultPlcDiscoveryItem implements PlcDiscoveryItem, Serializable {
 
     @Override
     public void serialize(WriteBuffer writeBuffer) throws SerializationException {
-        writeBuffer.pushContext(getClass().getSimpleName());
+        writeBuffer.pushContext("PlcDiscoveryItem");
 
         writeBuffer.writeString("protocolCode",
             protocolCode.getBytes(StandardCharsets.UTF_8).length * 8,
@@ -134,7 +134,7 @@ public class DefaultPlcDiscoveryItem implements PlcDiscoveryItem, Serializable {
                 name, WithOption.WithEncoding(StandardCharsets.UTF_8.name()));
         }
 
-        writeBuffer.popContext(getClass().getSimpleName());
+        writeBuffer.popContext("PlcDiscoveryItem");
     }
 
 }
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcDiscoveryRequest.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcDiscoveryRequest.java
index a782df78f5..9990f1ba5c 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcDiscoveryRequest.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcDiscoveryRequest.java
@@ -25,6 +25,7 @@ import org.apache.plc4x.java.spi.utils.Serializable;
 
 import java.util.LinkedHashMap;
 import java.util.Map;
+import java.util.Objects;
 import java.util.concurrent.CompletableFuture;
 
 public class DefaultPlcDiscoveryRequest implements PlcDiscoveryRequest, Serializable {
@@ -73,7 +74,7 @@ public class DefaultPlcDiscoveryRequest implements PlcDiscoveryRequest, Serializ
         private final LinkedHashMap<String, String> queries;
 
         public Builder(PlcDiscoverer discoverer) {
-            this.discoverer = discoverer;
+            this.discoverer = Objects.requireNonNull(discoverer);
             queries = new LinkedHashMap<>();
         }
 
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcReadRequest.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcReadRequest.java
index 3d189926ff..92c64c4ebb 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcReadRequest.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcReadRequest.java
@@ -19,23 +19,28 @@
 package org.apache.plc4x.java.spi.messages;
 
 import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
+import org.apache.plc4x.java.api.exceptions.PlcTagNotFoundException;
 import org.apache.plc4x.java.api.messages.PlcReadRequest;
 import org.apache.plc4x.java.api.messages.PlcReadResponse;
 import org.apache.plc4x.java.api.messages.PlcTagRequest;
 import org.apache.plc4x.java.api.model.PlcTag;
+import org.apache.plc4x.java.api.types.PlcResponseCode;
 import org.apache.plc4x.java.spi.connection.PlcTagHandler;
 import org.apache.plc4x.java.spi.generation.SerializationException;
 import org.apache.plc4x.java.spi.generation.WriteBuffer;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcTagErrorItem;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcTagItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcTagItem;
 import org.apache.plc4x.java.spi.utils.Serializable;
 
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import java.util.Optional;
+import java.util.Objects;
 import java.util.concurrent.CompletableFuture;
 import java.util.function.Supplier;
+import java.util.stream.Collectors;
 
 import static org.apache.plc4x.java.spi.generation.WithReaderWriterArgs.WithRenderAsList;
 
@@ -43,10 +48,10 @@ public class DefaultPlcReadRequest implements PlcReadRequest, PlcTagRequest, Ser
 
     private final PlcReader reader;
     // This is intentionally a linked hash map in order to keep the order of how elements were added.
-    private final LinkedHashMap<String, PlcTag> tags;
+    private final LinkedHashMap<String, PlcTagItem> tags;
 
     public DefaultPlcReadRequest(PlcReader reader,
-                                 LinkedHashMap<String, PlcTag> tags) {
+                                 LinkedHashMap<String, PlcTagItem> tags) {
         this.reader = reader;
         this.tags = tags;
     }
@@ -67,14 +72,23 @@ public class DefaultPlcReadRequest implements PlcReadRequest, PlcTagRequest, Ser
         return new LinkedHashSet<>(tags.keySet());
     }
 
+    public PlcTagItem getTagItem(String tagName) {
+        return tags.get(tagName);
+    }
+
+    @Override
+    public PlcTag getTag(String tagName) {
+        return tags.get(tagName).getTag();
+    }
+
     @Override
-    public PlcTag getTag(String name) {
-        return tags.get(name);
+    public PlcResponseCode getTagResponseCode(String tagName) {
+        return tags.get(tagName).getResponseCode();
     }
 
     @Override
     public List<PlcTag> getTags() {
-        return new LinkedList<>(tags.values());
+        return tags.values().stream().filter(plcTagItem -> plcTagItem instanceof DefaultPlcTagItem).map(PlcTagItem::getTag).collect(Collectors.toList());
     }
 
     public PlcReader getReader() {
@@ -87,14 +101,14 @@ public class DefaultPlcReadRequest implements PlcReadRequest, PlcTagRequest, Ser
 
         writeBuffer.pushContext("PlcTagRequest");
         writeBuffer.pushContext("tags", WithRenderAsList(true));
-        for (Map.Entry<String, PlcTag> tagEntry : tags.entrySet()) {
+        for (Map.Entry<String, PlcTagItem> tagEntry : tags.entrySet()) {
             String tagName = tagEntry.getKey();
             writeBuffer.pushContext(tagName);
-            PlcTag tag = tagEntry.getValue();
-            if(!(tag instanceof Serializable)) {
-                throw new RuntimeException("Error serializing. Tag doesn't implement Serializable");
+            PlcTagItem tagItem = tagEntry.getValue();
+            if (!(tagItem instanceof Serializable)) {
+                throw new RuntimeException("Error serializing. PlcTagItem doesn't implement Serializable");
             }
-            ((Serializable) tag).serialize(writeBuffer);
+            ((Serializable) tagItem).serialize(writeBuffer);
             writeBuffer.popContext(tagName);
         }
         writeBuffer.popContext("tags");
@@ -107,36 +121,48 @@ public class DefaultPlcReadRequest implements PlcReadRequest, PlcTagRequest, Ser
 
         private final PlcReader reader;
         private final PlcTagHandler tagHandler;
-        private final Map<String, Supplier<PlcTag>> tags;
+        private final Map<String, Supplier<PlcTagItem>> tagItems;
 
         public Builder(PlcReader reader, PlcTagHandler tagHandler) {
-            this.reader = reader;
-            this.tagHandler = tagHandler;
-            tags = new LinkedHashMap<>();
+            this.reader = Objects.requireNonNull(reader);
+            this.tagHandler = Objects.requireNonNull(tagHandler);
+            tagItems = new LinkedHashMap<>();
         }
 
         @Override
         public PlcReadRequest.Builder addTagAddress(String name, String tagAddress) {
-            if (tags.containsKey(name)) {
+            if (tagItems.containsKey(name)) {
                 throw new PlcRuntimeException("Duplicate tag definition '" + name + "'");
             }
-            tags.put(name, () -> tagHandler.parseTag(tagAddress));
+            tagItems.put(name, () -> {
+                try {
+                    PlcTag tag = tagHandler.parseTag(tagAddress);
+                    return new DefaultPlcTagItem(tag);
+                } catch (PlcTagNotFoundException e) {
+                    return new DefaultPlcTagErrorItem(PlcResponseCode.NOT_FOUND);
+                } catch (Exception e) {
+                    return new DefaultPlcTagErrorItem(PlcResponseCode.INVALID_ADDRESS);
+                }
+            });
             return this;
         }
 
         @Override
         public PlcReadRequest.Builder addTag(String name, PlcTag tag) {
-            if (tags.containsKey(name)) {
+            if (tagItems.containsKey(name)) {
                 throw new PlcRuntimeException("Duplicate tag definition '" + name + "'");
             }
-            tags.put(name, () -> tag);
+            tagItems.put(name, () -> new DefaultPlcTagItem(tag));
             return this;
         }
 
         @Override
         public PlcReadRequest build() {
-            LinkedHashMap<String, PlcTag> parsedTags = new LinkedHashMap<>();
-            tags.forEach((name, tagSupplier) -> parsedTags.put(name, tagSupplier.get()));
+            LinkedHashMap<String, PlcTagItem> parsedTags = new LinkedHashMap<>();
+            tagItems.forEach((name, tagItemSupplier) -> {
+                PlcTagItem plcTagItem = tagItemSupplier.get();
+                parsedTags.put(name, plcTagItem);
+            });
             return new DefaultPlcReadRequest(reader, parsedTags);
         }
     }
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcReadResponse.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcReadResponse.java
index 9984211ccc..53a514e5cb 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcReadResponse.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcReadResponse.java
@@ -25,13 +25,13 @@ import org.apache.plc4x.java.api.messages.PlcReadResponse;
 import org.apache.plc4x.java.api.model.PlcTag;
 import org.apache.plc4x.java.api.types.PlcResponseCode;
 import org.apache.plc4x.java.spi.generation.SerializationException;
-import org.apache.plc4x.java.spi.generation.WithWriterArgs;
 import org.apache.plc4x.java.spi.generation.WriteBuffer;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem;
 import org.apache.plc4x.java.spi.utils.Serializable;
 import org.apache.plc4x.java.spi.values.PlcList;
 import org.apache.plc4x.java.api.value.PlcValue;
 import org.apache.plc4x.java.spi.values.PlcStruct;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
@@ -45,10 +45,10 @@ import static org.apache.plc4x.java.spi.generation.WithReaderWriterArgs.WithRend
 public class DefaultPlcReadResponse implements PlcReadResponse, Serializable {
 
     private final PlcReadRequest request;
-    private final Map<String, ResponseItem<PlcValue>> values;
+    private final Map<String, PlcResponseItem<PlcValue>> values;
 
     public DefaultPlcReadResponse(PlcReadRequest request,
-                                  Map<String, ResponseItem<PlcValue>> values) {
+                                  Map<String, PlcResponseItem<PlcValue>> values) {
         this.request = request;
         this.values = values;
     }
@@ -70,7 +70,7 @@ public class DefaultPlcReadResponse implements PlcReadResponse, Serializable {
 
     @Override
     public PlcValue getPlcValue(String name) {
-        return values.getOrDefault(name, new ResponseItem<>(null, null)).getValue();
+        return values.getOrDefault(name, new DefaultPlcResponseItem<>(null, null)).getValue();
     }
 
     @Override
@@ -102,7 +102,7 @@ public class DefaultPlcReadResponse implements PlcReadResponse, Serializable {
         return values.get(name).getCode();
     }
 
-    public Map<String, ResponseItem<PlcValue>> getValues() {
+    public Map<String, PlcResponseItem<PlcValue>> getValues() {
         return values;
     }
 
@@ -605,11 +605,11 @@ public class DefaultPlcReadResponse implements PlcReadResponse, Serializable {
         return Collections.singletonList(tagInternal.getDateTime());
     }
 
-    public void add(String key, ResponseItem<PlcValue> value) {
+    public void add(String key, PlcResponseItem<PlcValue> value) {
         values.put(key, value);
     }
 
-    public Map<String, ResponseItem<PlcValue>> getMap() {
+    public Map<String, PlcResponseItem<PlcValue>> getMap() {
         return values;
     }
 
@@ -653,11 +653,14 @@ public class DefaultPlcReadResponse implements PlcReadResponse, Serializable {
         writeBuffer.popContext("request");
 
         writeBuffer.pushContext("values", WithRenderAsList(true));
-        for (Map.Entry<String, ResponseItem<PlcValue>> valueEntry : values.entrySet()) {
+        for (Map.Entry<String, PlcResponseItem<PlcValue>> valueEntry : values.entrySet()) {
             String tagName = valueEntry.getKey();
             writeBuffer.pushContext(tagName);
-            ResponseItem<PlcValue> valueResponse = valueEntry.getValue();
-            valueResponse.serialize(writeBuffer);
+            PlcResponseItem<PlcValue> valueResponse = valueEntry.getValue();
+            if (!(valueResponse instanceof Serializable)) {
+                throw new RuntimeException("Error serializing. PlcResponseItem doesn't implement Serializable");
+            }
+            ((Serializable) valueResponse).serialize(writeBuffer);
             writeBuffer.popContext(tagName);
         }
         writeBuffer.popContext("values");
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcSubscriptionEvent.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcSubscriptionEvent.java
index da21c8358f..2035f76e00 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcSubscriptionEvent.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcSubscriptionEvent.java
@@ -21,7 +21,7 @@ package org.apache.plc4x.java.spi.messages;
 import org.apache.plc4x.java.api.messages.PlcSubscriptionEvent;
 import org.apache.plc4x.java.api.model.PlcTag;
 import org.apache.plc4x.java.api.value.PlcValue;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem;
 
 import java.time.Instant;
 import java.util.Collection;
@@ -32,7 +32,7 @@ public class DefaultPlcSubscriptionEvent extends DefaultPlcReadResponse implemen
     public final Instant timestamp;
 
     public DefaultPlcSubscriptionEvent(Instant timestamp,
-                                       Map<String, ResponseItem<PlcValue>> tags) {
+                                       Map<String, PlcResponseItem<PlcValue>> tags) {
         super(null, tags);
         this.timestamp = timestamp;
     }
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcSubscriptionRequest.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcSubscriptionRequest.java
index 7264b78209..acd6bd23dd 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcSubscriptionRequest.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcSubscriptionRequest.java
@@ -111,8 +111,8 @@ public class DefaultPlcSubscriptionRequest implements PlcSubscriptionRequest, Se
         private final LinkedHashMap<String, List<Consumer<PlcSubscriptionEvent>>> preRegisteredConsumers;
 
         public Builder(PlcSubscriber subscriber, PlcTagHandler tagHandler) {
-            this.subscriber = subscriber;
-            this.tagHandler = tagHandler;
+            this.subscriber = Objects.requireNonNull(subscriber);
+            this.tagHandler = Objects.requireNonNull(tagHandler);
             this.tags = new TreeMap<>();
             this.preRegisteredConsumers = new LinkedHashMap<>();
         }
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcSubscriptionResponse.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcSubscriptionResponse.java
index 47d806eb43..10595de831 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcSubscriptionResponse.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcSubscriptionResponse.java
@@ -28,7 +28,7 @@ import org.apache.plc4x.java.api.model.PlcSubscriptionHandle;
 import org.apache.plc4x.java.api.types.PlcResponseCode;
 import org.apache.plc4x.java.spi.generation.SerializationException;
 import org.apache.plc4x.java.spi.generation.WriteBuffer;
-import org.apache.plc4x.java.spi.messages.utils.ResponseItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcResponseItem;
 import org.apache.plc4x.java.spi.utils.Serializable;
 
 import java.util.Collection;
@@ -39,10 +39,10 @@ public class DefaultPlcSubscriptionResponse implements PlcSubscriptionResponse,
 
     private final PlcSubscriptionRequest request;
 
-    private final Map<String, ResponseItem<PlcSubscriptionHandle>> values;
+    private final Map<String, PlcResponseItem<PlcSubscriptionHandle>> values;
 
     public DefaultPlcSubscriptionResponse(PlcSubscriptionRequest request,
-                                          Map<String, ResponseItem<PlcSubscriptionHandle>> values) {
+                                          Map<String, PlcResponseItem<PlcSubscriptionHandle>> values) {
         this.request = request;
         this.values = values;
         request.getPreRegisteredConsumers().forEach((subscriptionTagName, consumers) -> {
@@ -56,7 +56,7 @@ public class DefaultPlcSubscriptionResponse implements PlcSubscriptionResponse,
 
     @Override
     public PlcSubscriptionHandle getSubscriptionHandle(String name) {
-        ResponseItem<PlcSubscriptionHandle> response = values.get(name);
+        PlcResponseItem<PlcSubscriptionHandle> response = values.get(name);
         if (response == null) {
             return null;
         }
@@ -78,7 +78,7 @@ public class DefaultPlcSubscriptionResponse implements PlcSubscriptionResponse,
 
     @Override
     public PlcResponseCode getResponseCode(String name) {
-        ResponseItem<PlcSubscriptionHandle> response = values.get(name);
+        PlcResponseItem<PlcSubscriptionHandle> response = values.get(name);
         if (response == null) {
             return null;
         }
@@ -92,10 +92,10 @@ public class DefaultPlcSubscriptionResponse implements PlcSubscriptionResponse,
 
     @Override
     public Collection<PlcSubscriptionHandle> getSubscriptionHandles() {
-        return values.values().stream().map(ResponseItem::getValue).collect(Collectors.toList());
+        return values.values().stream().map(PlcResponseItem::getValue).collect(Collectors.toList());
     }
 
-    public Map<String, ResponseItem<PlcSubscriptionHandle>> getValues() {
+    public Map<String, PlcResponseItem<PlcSubscriptionHandle>> getValues() {
         return values;
     }
 
@@ -107,11 +107,14 @@ public class DefaultPlcSubscriptionResponse implements PlcSubscriptionResponse,
             ((Serializable) request).serialize(writeBuffer);
         }
         writeBuffer.pushContext("values");
-        for (Map.Entry<String, ResponseItem<PlcSubscriptionHandle>> valueEntry : values.entrySet()) {
+        for (Map.Entry<String, PlcResponseItem<PlcSubscriptionHandle>> valueEntry : values.entrySet()) {
             String tagName = valueEntry.getKey();
             writeBuffer.pushContext(tagName);
-            ResponseItem<PlcSubscriptionHandle> valueResponse = valueEntry.getValue();
-            valueResponse.serialize(writeBuffer);
+            PlcResponseItem<PlcSubscriptionHandle> valueResponse = valueEntry.getValue();
+            if (!(valueResponse instanceof Serializable)) {
+                throw new RuntimeException("Error serializing. PlcResponseItem doesn't implement Serializable");
+            }
+            ((Serializable) valueResponse).serialize(writeBuffer);
             writeBuffer.pushContext(tagName);
         }
         writeBuffer.popContext("values");
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcUnsubscriptionRequest.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcUnsubscriptionRequest.java
index a90aeea872..64570741f8 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcUnsubscriptionRequest.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcUnsubscriptionRequest.java
@@ -71,7 +71,7 @@ public class DefaultPlcUnsubscriptionRequest implements PlcUnsubscriptionRequest
         private final List<PlcSubscriptionHandle> plcSubscriptionHandles;
 
         public Builder(PlcSubscriber subscriber) {
-            this.subscriber = subscriber;
+            this.subscriber = Objects.requireNonNull(subscriber);
             plcSubscriptionHandles = new ArrayList<>();
         }
 
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcWriteRequest.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcWriteRequest.java
index d66d1f1c9c..64f3c21ec7 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcWriteRequest.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/DefaultPlcWriteRequest.java
@@ -18,20 +18,22 @@
  */
 package org.apache.plc4x.java.spi.messages;
 
-import org.apache.commons.lang3.tuple.Pair;
 import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
 import org.apache.plc4x.java.api.messages.PlcWriteRequest;
 import org.apache.plc4x.java.api.messages.PlcWriteResponse;
 import org.apache.plc4x.java.api.model.PlcTag;
+import org.apache.plc4x.java.api.types.PlcResponseCode;
 import org.apache.plc4x.java.api.value.PlcValue;
-import org.apache.plc4x.java.api.value.PlcValueHandler;
 import org.apache.plc4x.java.spi.codegen.WithOption;
 import org.apache.plc4x.java.spi.connection.PlcTagHandler;
 import org.apache.plc4x.java.spi.generation.SerializationException;
 import org.apache.plc4x.java.spi.generation.WriteBuffer;
-import org.apache.plc4x.java.spi.messages.utils.TagValueItem;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcTagErrorItem;
+import org.apache.plc4x.java.spi.messages.utils.DefaultPlcTagValueItem;
+import org.apache.plc4x.java.spi.messages.utils.PlcTagValueItem;
 import org.apache.plc4x.java.spi.utils.Serializable;
 import org.apache.plc4x.java.spi.values.PlcList;
+import org.apache.plc4x.java.spi.values.PlcValueHandler;
 
 import java.nio.charset.StandardCharsets;
 import java.util.*;
@@ -45,10 +47,10 @@ public class DefaultPlcWriteRequest implements PlcWriteRequest, Serializable {
 
     private final PlcWriter writer;
 
-    private final LinkedHashMap<String, TagValueItem> tags;
+    private final LinkedHashMap<String, PlcTagValueItem> tags;
 
     public DefaultPlcWriteRequest(PlcWriter writer,
-                                  LinkedHashMap<String, TagValueItem> tags) {
+                                  LinkedHashMap<String, PlcTagValueItem> tags) {
         this.writer = writer;
         this.tags = tags;
     }
@@ -69,6 +71,11 @@ public class DefaultPlcWriteRequest implements PlcWriteRequest, Serializable {
         return new LinkedHashSet<>(tags.keySet());
     }
 
+    @Override
+    public PlcResponseCode getTagResponseCode(String tagName) {
+        return tags.get(tagName).getResponseCode();
+    }
+
     @Override
     public PlcTag getTag(String name) {
         return tags.get(name).getTag();
@@ -76,7 +83,7 @@ public class DefaultPlcWriteRequest implements PlcWriteRequest, Serializable {
 
     @Override
     public List<PlcTag> getTags() {
-        return tags.values().stream().map(TagValueItem::getTag).collect(Collectors.toCollection(LinkedList::new));
+        return tags.values().stream().map(PlcTagValueItem::getTag).collect(Collectors.toCollection(LinkedList::new));
     }
 
     public PlcValue getPlcValue(String name) {
@@ -84,7 +91,7 @@ public class DefaultPlcWriteRequest implements PlcWriteRequest, Serializable {
     }
 
     public List<PlcValue> getPlcValues() {
-        return tags.values().stream().map(TagValueItem::getValue).collect(Collectors.toCollection(LinkedList::new));
+        return tags.values().stream().map(PlcTagValueItem::getValue).collect(Collectors.toCollection(LinkedList::new));
     }
 
     public PlcWriter getWriter() {
@@ -107,33 +114,19 @@ public class DefaultPlcWriteRequest implements PlcWriteRequest, Serializable {
 
         writeBuffer.pushContext("PlcTagRequest");
         writeBuffer.pushContext("tags", WithRenderAsList(true));
-        for (Map.Entry<String, TagValueItem> tagEntry : tags.entrySet()) {
-            TagValueItem tagValueItem = tagEntry.getValue();
+        for (Map.Entry<String, PlcTagValueItem> tagEntry : tags.entrySet()) {
             String tagName = tagEntry.getKey();
             writeBuffer.pushContext(tagName);
-            PlcTag tag = tagValueItem.getTag();
-            if (!(tag instanceof Serializable)) {
-                throw new RuntimeException("Error serializing. Tag doesn't implement Serializable");
+            PlcTagValueItem plcTagValueItem = tagEntry.getValue();
+            if (!(plcTagValueItem instanceof Serializable)) {
+                throw new RuntimeException("Error serializing. PlcTagValueItem doesn't implement Serializable");
             }
-            ((Serializable) tag).serialize(writeBuffer);
+            ((Serializable) plcTagValueItem).serialize(writeBuffer);
             writeBuffer.popContext(tagName);
         }
         writeBuffer.popContext("tags");
         writeBuffer.popContext("PlcTagRequest");
 
-        writeBuffer.pushContext("values", WithRenderAsList(true));
-        for (Map.Entry<String, TagValueItem> tagEntry : tags.entrySet()) {
-            TagValueItem tagValueItem = tagEntry.getValue();
-            String tagName = tagEntry.getKey();
-            writeBuffer.pushContext(tagName);
-            final PlcValue value = tagValueItem.getValue();
-            if (value != null) {
-                serializePlcValue(value, writeBuffer);
-            }
-            writeBuffer.popContext(tagName);
-        }
-        writeBuffer.popContext("values");
-
         writeBuffer.popContext("PlcWriteRequest");
     }
 
@@ -154,62 +147,62 @@ public class DefaultPlcWriteRequest implements PlcWriteRequest, Serializable {
         private final PlcWriter writer;
         private final PlcTagHandler tagHandler;
         private final PlcValueHandler valueHandler;
-        private final Map<String, Pair<Supplier<PlcTag>, Object[]>> tags;
+        private final Map<String, Supplier<PlcTagValueItem>> tagValues;
 
         public Builder(PlcWriter writer, PlcTagHandler tagHandler, PlcValueHandler valueHandler) {
-            this.writer = writer;
-            this.tagHandler = tagHandler;
-            this.valueHandler = valueHandler;
-            tags = new TreeMap<>();
+            this.writer = Objects.requireNonNull(writer);
+            this.tagHandler = Objects.requireNonNull(tagHandler);
+            this.valueHandler = Objects.requireNonNull(valueHandler);
+            tagValues = new TreeMap<>();
         }
 
         @Override
         public Builder addTagAddress(String name, String tagAddress, Object... values) {
-            if (tags.containsKey(name)) {
+            if (tagValues.containsKey(name)) {
                 throw new PlcRuntimeException("Duplicate tag definition '" + name + "'");
             }
-            tags.put(name, Pair.of(() -> tagHandler.parseTag(tagAddress), values));
+            tagValues.put(name, () -> {
+                try {
+                    PlcTag tag = tagHandler.parseTag(tagAddress);
+                    try {
+                        PlcValue plcValue = parsePlcValue(tag, values);
+                        return new DefaultPlcTagValueItem(tag, plcValue);
+                    } catch (Exception e) {
+                        return new DefaultPlcTagErrorItem(PlcResponseCode.INVALID_DATA);
+                    }
+                } catch (Exception e) {
+                    return new DefaultPlcTagErrorItem(PlcResponseCode.INVALID_ADDRESS);
+                }
+            });
             return this;
         }
 
         @Override
         public Builder addTag(String name, PlcTag tag, Object... values) {
-            if (tags.containsKey(name)) {
+            if (tagValues.containsKey(name)) {
                 throw new PlcRuntimeException("Duplicate tag definition '" + name + "'");
             }
-            tags.put(name, Pair.of(() -> tag, values));
+            tagValues.put(name, () -> {
+                try {
+                    PlcValue plcValue = parsePlcValue(tag, values);
+                    return new DefaultPlcTagValueItem(tag, plcValue);
+                } catch (Exception e) {
+                    return new DefaultPlcTagErrorItem(PlcResponseCode.INVALID_DATA);
+                }
+            });
             return this;
         }
 
+        protected PlcValue parsePlcValue(PlcTag tag, Object[] values) {
+            return valueHandler.newPlcValue(tag, values);
+        }
+
         @Override
         public PlcWriteRequest build() {
-            LinkedHashMap<String, TagValueItem> parsedTags = new LinkedHashMap<>();
-            tags.forEach((name, tagValues) -> {
-                // Compile the query string.
-                PlcTag tag = tagValues.getLeft().get();
-                PlcValue plcValue;
-                // If this is more than one element the value itself will definitely be a list.
-                if(tagValues.getRight().length > 1) {
-                    List<PlcValue> listItems = new ArrayList<>(tagValues.getRight().length);
-                    for (Object tagValue : tagValues.getRight()) {
-                        if(tagValue instanceof PlcValue) {
-                            listItems.add((PlcValue) tagValue);
-                        } else {
-                            PlcValue plcItemValue = valueHandler.newPlcValue(tag, tagValue);
-                            listItems.add(plcItemValue);
-                        }
-                    }
-                    plcValue = new PlcList(listItems);
-                }
-                // If the values are already PlcValues, just use them.
-                else if(tagValues.getRight()[0] instanceof PlcValue) {
-                    plcValue = (PlcValue) tagValues.getRight()[0];
-                }
-                // In all other cases use the value-handler.
-                else {
-                    plcValue = valueHandler.newPlcValue(tag, tagValues.getRight()[0]);
-                }
-                parsedTags.put(name, new TagValueItem(tag, plcValue));
+            LinkedHashMap<String, PlcTagValueItem> parsedTags = new LinkedHashMap<>();
+            tagValues.forEach((name, tagValueItemSupplier) -> {
+                PlcTagValueItem plcTagValueItem = tagValueItemSupplier.get();
+                parsedTags.put(name, plcTagValueItem);
             });
             return new DefaultPlcWriteRequest(writer, parsedTags);
         }
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/ResponseItem.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/DefaultPlcResponseItem.java
similarity index 88%
copy from plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/ResponseItem.java
copy to plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/DefaultPlcResponseItem.java
index b26e06c668..87e4dec387 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/ResponseItem.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/DefaultPlcResponseItem.java
@@ -26,27 +26,29 @@ import org.apache.plc4x.java.spi.utils.Serializable;
 
 import java.nio.charset.StandardCharsets;
 
-public class ResponseItem<T> implements Serializable {
+public class DefaultPlcResponseItem<T> implements Serializable, PlcResponseItem<T> {
 
     private final PlcResponseCode code;
     private final T value;
 
-    public ResponseItem(PlcResponseCode code, T value) {
+    public DefaultPlcResponseItem(PlcResponseCode code, T value) {
         this.code = code;
         this.value = value;
     }
 
+    @Override
     public PlcResponseCode getCode() {
         return code;
     }
 
+    @Override
     public T getValue() {
         return value;
     }
 
     @Override
     public void serialize(WriteBuffer writeBuffer) throws SerializationException {
-        writeBuffer.pushContext("ResponseItem");
+        writeBuffer.pushContext("PlcResponseItem");
         String codeName = code.name();
         writeBuffer.writeString("code",
             codeName.getBytes(StandardCharsets.UTF_8).length * 8,
@@ -59,7 +61,7 @@ public class ResponseItem<T> implements Serializable {
             ((Serializable) value).serialize(writeBuffer);
             writeBuffer.popContext("value");
         }
-        writeBuffer.popContext("ResponseItem");
+        writeBuffer.popContext("PlcResponseItem");
     }
 
 }
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcRawByteArray.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/DefaultPlcTagErrorItem.java
similarity index 52%
copy from plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcRawByteArray.java
copy to plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/DefaultPlcTagErrorItem.java
index 691f4e2edd..211497ec63 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcRawByteArray.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/DefaultPlcTagErrorItem.java
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *   https://www.apache.org/licenses/LICENSE-2.0
+ *   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
@@ -16,45 +16,31 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.plc4x.java.spi.values;
 
-import org.apache.commons.codec.binary.Hex;
-import org.apache.plc4x.java.api.types.PlcValueType;
+package org.apache.plc4x.java.spi.messages.utils;
+
+import org.apache.plc4x.java.api.types.PlcResponseCode;
 import org.apache.plc4x.java.spi.generation.SerializationException;
 import org.apache.plc4x.java.spi.generation.WriteBuffer;
+import org.apache.plc4x.java.spi.utils.Serializable;
 
-public class PlcRawByteArray extends PlcIECValue<byte[]> {
-
-    public static PlcRawByteArray of(Object value) {
-        if (value instanceof byte[]) {
-            return new PlcRawByteArray((byte[]) value);
-        }
-        throw new IllegalArgumentException("Only byte[] supported here");
-    }
+public class DefaultPlcTagErrorItem implements PlcTagItem, PlcTagValueItem, Serializable {
 
-    public PlcRawByteArray(byte[] value) {
-        this.value = value;
-        this.isNullable = false;
-    }
+    private final PlcResponseCode responseCode;
 
-    @Override
-    public PlcValueType getPlcValueType() {
-        return PlcValueType.RAW_BYTE_ARRAY;
+    public DefaultPlcTagErrorItem(PlcResponseCode responseCode) {
+        this.responseCode = responseCode;
     }
 
-    @Override
-    public byte[] getRaw() {
-        return value;
-    }
-    
-    @Override
-    public String toString() {
-        return Hex.encodeHexString(value);
+    public PlcResponseCode getResponseCode() {
+        return responseCode;
     }
 
     @Override
     public void serialize(WriteBuffer writeBuffer) throws SerializationException {
-        writeBuffer.writeByteArray(getClass().getSimpleName(), value);
+        writeBuffer.pushContext("PlcTagErrorItem");
+        writeBuffer.writeString("responseCode", responseCode.name().length() * 8, responseCode.name());
+        writeBuffer.popContext("PlcTagErrorItem");
     }
 
 }
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/TagValueItem.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/DefaultPlcTagItem.java
similarity index 57%
copy from plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/TagValueItem.java
copy to plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/DefaultPlcTagItem.java
index 14c9540af1..f1b15bb4a4 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/TagValueItem.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/messages/utils/DefaultPlcTagItem.java
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *   https://www.apache.org/licenses/LICENSE-2.0
+ *   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
@@ -16,27 +16,35 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
 package org.apache.plc4x.java.spi.messages.utils;
 
 import org.apache.plc4x.java.api.model.PlcTag;
-import org.apache.plc4x.java.api.value.PlcValue;
+import org.apache.plc4x.java.spi.generation.SerializationException;
+import org.apache.plc4x.java.spi.generation.WriteBuffer;
+import org.apache.plc4x.java.spi.utils.Serializable;
 
-public class TagValueItem {
+public class DefaultPlcTagItem implements PlcTagItem, Serializable {
 
     private final PlcTag tag;
-    private final PlcValue value;
 
-    public TagValueItem(PlcTag tag, PlcValue value) {
+    public DefaultPlcTagItem(PlcTag tag) {
         this.tag = tag;
-        this.value = value;
     }
 
     public PlcTag getTag() {
         return tag;
     }
 
-    public PlcValue getValue() {
-        return value;
+    @Override
+    public void serialize(WriteBuffer writeBuffer) throws SerializationException {
... 8825 lines suppressed ...