You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by jf...@apache.org on 2019/04/14 21:01:45 UTC

[incubator-plc4x] 01/01: PLC4X-111 Add initial implementation of the interop server.

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

jfeinauer pushed a commit to branch feature/PLC4X-111-interop-server
in repository https://gitbox.apache.org/repos/asf/incubator-plc4x.git

commit 2d245994f5ecb7211cced4401040643e689ceb0b
Author: Julian Feinauer <j....@pragmaticminds.de>
AuthorDate: Sun Apr 14 23:01:29 2019 +0200

    PLC4X-111 Add initial implementation of the interop server.
---
 plc4j/utils/interop/pom.xml                        |   46 +
 .../org/apache/plc4x/interop/ConnectionHandle.java |  372 +++
 .../org/apache/plc4x/interop/FieldResponse.java    |  802 ++++++
 .../org/apache/plc4x/interop/InteropServer.java    | 2989 ++++++++++++++++++++
 .../org/apache/plc4x/interop/PlcException.java     |  482 ++++
 .../org/apache/plc4x/interop/RESPONSE_CODE.java    |   58 +
 .../java/org/apache/plc4x/interop/Request.java     |  429 +++
 .../java/org/apache/plc4x/interop/Response.java    |  442 +++
 .../java/org/apache/plc4x/interop/impl/Client.java |   41 +
 .../org/apache/plc4x/interop/impl/Handler.java     |  143 +
 .../java/org/apache/plc4x/interop/impl/Server.java |   72 +
 .../org/apache/plc4x/interop/ConnectionHandle.cs   |  128 +
 .../org/apache/plc4x/interop/FieldResponse.cs      |  276 ++
 .../org/apache/plc4x/interop/InteropServer.cs      | 1177 ++++++++
 .../org/apache/plc4x/interop/PlcException.cs       |  164 ++
 .../org/apache/plc4x/interop/RESPONSE_CODE.cs      |   20 +
 .../gen-csharp/org/apache/plc4x/interop/Request.cs |  148 +
 .../org/apache/plc4x/interop/Response.cs           |  149 +
 .../org/apache/plc4x/interop/ConnectionHandle.java |  372 +++
 .../org/apache/plc4x/interop/FieldResponse.java    |  802 ++++++
 .../org/apache/plc4x/interop/InteropServer.java    | 2989 ++++++++++++++++++++
 .../org/apache/plc4x/interop/PlcException.java     |  482 ++++
 .../org/apache/plc4x/interop/RESPONSE_CODE.java    |   58 +
 .../gen-java/org/apache/plc4x/interop/Request.java |  429 +++
 .../org/apache/plc4x/interop/Response.java         |  442 +++
 .../interop/src/main/thrift/gen-py/__init__.py     |    0
 .../interop/src/main/thrift/gen-py/org/__init__.py |    0
 .../src/main/thrift/gen-py/org/apache/__init__.py  |    0
 .../thrift/gen-py/org/apache/plc4x/__init__.py     |    0
 .../org/apache/plc4x/interop/InteropServer-remote  |  131 +
 .../org/apache/plc4x/interop/InteropServer.py      |  651 +++++
 .../gen-py/org/apache/plc4x/interop/__init__.py    |    1 +
 .../gen-py/org/apache/plc4x/interop/constants.py   |   14 +
 .../gen-py/org/apache/plc4x/interop/ttypes.py      |  442 +++
 plc4j/utils/interop/src/main/thrift/interop.thrift |   94 +
 plc4j/utils/pom.xml                                |    1 +
 36 files changed, 14846 insertions(+)

diff --git a/plc4j/utils/interop/pom.xml b/plc4j/utils/interop/pom.xml
new file mode 100644
index 0000000..41136de
--- /dev/null
+++ b/plc4j/utils/interop/pom.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <parent>
+    <artifactId>plc4j-utils</artifactId>
+    <groupId>org.apache.plc4x</groupId>
+    <version>0.4.0-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>interop-server</artifactId>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.thrift</groupId>
+      <artifactId>libthrift</artifactId>
+      <version>0.12.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4j-api</artifactId>
+      <version>0.4.0-SNAPSHOT</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4j-protocol-driver-base-test</artifactId>
+      <version>0.4.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.plc4x</groupId>
+      <artifactId>plc4j-driver-s7</artifactId>
+      <version>0.4.0-SNAPSHOT</version>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>commons-lang</groupId>
+      <artifactId>commons-lang</artifactId>
+      <version>20030203.000129</version>
+      <scope>compile</scope>
+    </dependency>
+  </dependencies>
+
+
+</project>
\ No newline at end of file
diff --git a/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/ConnectionHandle.java b/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/ConnectionHandle.java
new file mode 100644
index 0000000..f500c3d
--- /dev/null
+++ b/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/ConnectionHandle.java
@@ -0,0 +1,372 @@
+/**
+ * Autogenerated by Thrift Compiler (0.12.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+package org.apache.plc4x.interop;
+
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.12.0)", date = "2019-04-14")
+public class ConnectionHandle implements org.apache.thrift.TBase<ConnectionHandle, ConnectionHandle._Fields>, java.io.Serializable, Cloneable, Comparable<ConnectionHandle> {
+  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("ConnectionHandle");
+
+  private static final org.apache.thrift.protocol.TField CONNECTION_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("connectionId", org.apache.thrift.protocol.TType.I64, (short)1);
+
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new ConnectionHandleStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new ConnectionHandleTupleSchemeFactory();
+
+  public long connectionId; // required
+
+  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+    CONNECTION_ID((short)1, "connectionId");
+
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
+
+    static {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
+        byName.put(field.getFieldName(), field);
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, or null if its not found.
+     */
+    @org.apache.thrift.annotation.Nullable
+    public static _Fields findByThriftId(int fieldId) {
+      switch(fieldId) {
+        case 1: // CONNECTION_ID
+          return CONNECTION_ID;
+        default:
+          return null;
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, throwing an exception
+     * if it is not found.
+     */
+    public static _Fields findByThriftIdOrThrow(int fieldId) {
+      _Fields fields = findByThriftId(fieldId);
+      if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      return fields;
+    }
+
+    /**
+     * Find the _Fields constant that matches name, or null if its not found.
+     */
+    @org.apache.thrift.annotation.Nullable
+    public static _Fields findByName(java.lang.String name) {
+      return byName.get(name);
+    }
+
+    private final short _thriftId;
+    private final java.lang.String _fieldName;
+
+    _Fields(short thriftId, java.lang.String fieldName) {
+      _thriftId = thriftId;
+      _fieldName = fieldName;
+    }
+
+    public short getThriftFieldId() {
+      return _thriftId;
+    }
+
+    public java.lang.String getFieldName() {
+      return _fieldName;
+    }
+  }
+
+  // isset id assignments
+  private static final int __CONNECTIONID_ISSET_ID = 0;
+  private byte __isset_bitfield = 0;
+  public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  static {
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+    tmpMap.put(_Fields.CONNECTION_ID, new org.apache.thrift.meta_data.FieldMetaData("connectionId", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(ConnectionHandle.class, metaDataMap);
+  }
+
+  public ConnectionHandle() {
+  }
+
+  public ConnectionHandle(
+    long connectionId)
+  {
+    this();
+    this.connectionId = connectionId;
+    setConnectionIdIsSet(true);
+  }
+
+  /**
+   * Performs a deep copy on <i>other</i>.
+   */
+  public ConnectionHandle(ConnectionHandle other) {
+    __isset_bitfield = other.__isset_bitfield;
+    this.connectionId = other.connectionId;
+  }
+
+  public ConnectionHandle deepCopy() {
+    return new ConnectionHandle(this);
+  }
+
+  @Override
+  public void clear() {
+    setConnectionIdIsSet(false);
+    this.connectionId = 0;
+  }
+
+  public long getConnectionId() {
+    return this.connectionId;
+  }
+
+  public ConnectionHandle setConnectionId(long connectionId) {
+    this.connectionId = connectionId;
+    setConnectionIdIsSet(true);
+    return this;
+  }
+
+  public void unsetConnectionId() {
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __CONNECTIONID_ISSET_ID);
+  }
+
+  /** Returns true if field connectionId is set (has been assigned a value) and false otherwise */
+  public boolean isSetConnectionId() {
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __CONNECTIONID_ISSET_ID);
+  }
+
+  public void setConnectionIdIsSet(boolean value) {
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __CONNECTIONID_ISSET_ID, value);
+  }
+
+  public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) {
+    switch (field) {
+    case CONNECTION_ID:
+      if (value == null) {
+        unsetConnectionId();
+      } else {
+        setConnectionId((java.lang.Long)value);
+      }
+      break;
+
+    }
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public java.lang.Object getFieldValue(_Fields field) {
+    switch (field) {
+    case CONNECTION_ID:
+      return getConnectionId();
+
+    }
+    throw new java.lang.IllegalStateException();
+  }
+
+  /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+  public boolean isSet(_Fields field) {
+    if (field == null) {
+      throw new java.lang.IllegalArgumentException();
+    }
+
+    switch (field) {
+    case CONNECTION_ID:
+      return isSetConnectionId();
+    }
+    throw new java.lang.IllegalStateException();
+  }
+
+  @Override
+  public boolean equals(java.lang.Object that) {
+    if (that == null)
+      return false;
+    if (that instanceof ConnectionHandle)
+      return this.equals((ConnectionHandle)that);
+    return false;
+  }
+
+  public boolean equals(ConnectionHandle that) {
+    if (that == null)
+      return false;
+    if (this == that)
+      return true;
+
+    boolean this_present_connectionId = true;
+    boolean that_present_connectionId = true;
+    if (this_present_connectionId || that_present_connectionId) {
+      if (!(this_present_connectionId && that_present_connectionId))
+        return false;
+      if (this.connectionId != that.connectionId)
+        return false;
+    }
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int hashCode = 1;
+
+    hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(connectionId);
+
+    return hashCode;
+  }
+
+  @Override
+  public int compareTo(ConnectionHandle other) {
+    if (!getClass().equals(other.getClass())) {
+      return getClass().getName().compareTo(other.getClass().getName());
+    }
+
+    int lastComparison = 0;
+
+    lastComparison = java.lang.Boolean.valueOf(isSetConnectionId()).compareTo(other.isSetConnectionId());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetConnectionId()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.connectionId, other.connectionId);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    return 0;
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public _Fields fieldForId(int fieldId) {
+    return _Fields.findByThriftId(fieldId);
+  }
+
+  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+    scheme(iprot).read(iprot, this);
+  }
+
+  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+    scheme(oprot).write(oprot, this);
+  }
+
+  @Override
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("ConnectionHandle(");
+    boolean first = true;
+
+    sb.append("connectionId:");
+    sb.append(this.connectionId);
+    first = false;
+    sb.append(")");
+    return sb.toString();
+  }
+
+  public void validate() throws org.apache.thrift.TException {
+    // check for required fields
+    // check for sub-struct validity
+  }
+
+  private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+    try {
+      write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
+    try {
+      // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
+      __isset_bitfield = 0;
+      read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private static class ConnectionHandleStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+    public ConnectionHandleStandardScheme getScheme() {
+      return new ConnectionHandleStandardScheme();
+    }
+  }
+
+  private static class ConnectionHandleStandardScheme extends org.apache.thrift.scheme.StandardScheme<ConnectionHandle> {
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot, ConnectionHandle struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TField schemeField;
+      iprot.readStructBegin();
+      while (true)
+      {
+        schemeField = iprot.readFieldBegin();
+        if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+          break;
+        }
+        switch (schemeField.id) {
+          case 1: // CONNECTION_ID
+            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
+              struct.connectionId = iprot.readI64();
+              struct.setConnectionIdIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          default:
+            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+        }
+        iprot.readFieldEnd();
+      }
+      iprot.readStructEnd();
+
+      // check for required fields of primitive type, which can't be checked in the validate method
+      struct.validate();
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot, ConnectionHandle struct) throws org.apache.thrift.TException {
+      struct.validate();
+
+      oprot.writeStructBegin(STRUCT_DESC);
+      oprot.writeFieldBegin(CONNECTION_ID_FIELD_DESC);
+      oprot.writeI64(struct.connectionId);
+      oprot.writeFieldEnd();
+      oprot.writeFieldStop();
+      oprot.writeStructEnd();
+    }
+
+  }
+
+  private static class ConnectionHandleTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+    public ConnectionHandleTupleScheme getScheme() {
+      return new ConnectionHandleTupleScheme();
+    }
+  }
+
+  private static class ConnectionHandleTupleScheme extends org.apache.thrift.scheme.TupleScheme<ConnectionHandle> {
+
+    @Override
+    public void write(org.apache.thrift.protocol.TProtocol prot, ConnectionHandle struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
+      if (struct.isSetConnectionId()) {
+        optionals.set(0);
+      }
+      oprot.writeBitSet(optionals, 1);
+      if (struct.isSetConnectionId()) {
+        oprot.writeI64(struct.connectionId);
+      }
+    }
+
+    @Override
+    public void read(org.apache.thrift.protocol.TProtocol prot, ConnectionHandle struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(1);
+      if (incoming.get(0)) {
+        struct.connectionId = iprot.readI64();
+        struct.setConnectionIdIsSet(true);
+      }
+    }
+  }
+
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+}
+
diff --git a/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/FieldResponse.java b/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/FieldResponse.java
new file mode 100644
index 0000000..01d615e
--- /dev/null
+++ b/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/FieldResponse.java
@@ -0,0 +1,802 @@
+/**
+ * Autogenerated by Thrift Compiler (0.12.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+package org.apache.plc4x.interop;
+
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.12.0)", date = "2019-04-14")
+public class FieldResponse implements org.apache.thrift.TBase<FieldResponse, FieldResponse._Fields>, java.io.Serializable, Cloneable, Comparable<FieldResponse> {
+  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("FieldResponse");
+
+  private static final org.apache.thrift.protocol.TField RESPONSE_CODE_FIELD_DESC = new org.apache.thrift.protocol.TField("responseCode", org.apache.thrift.protocol.TType.I32, (short)1);
+  private static final org.apache.thrift.protocol.TField BOOL_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("boolValue", org.apache.thrift.protocol.TType.BOOL, (short)2);
+  private static final org.apache.thrift.protocol.TField LONG_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("longValue", org.apache.thrift.protocol.TType.I64, (short)3);
+  private static final org.apache.thrift.protocol.TField DOUBLE_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("doubleValue", org.apache.thrift.protocol.TType.DOUBLE, (short)4);
+  private static final org.apache.thrift.protocol.TField STRING_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("stringValue", org.apache.thrift.protocol.TType.STRING, (short)5);
+
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new FieldResponseStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new FieldResponseTupleSchemeFactory();
+
+  /**
+   * 
+   * @see RESPONSE_CODE
+   */
+  public @org.apache.thrift.annotation.Nullable RESPONSE_CODE responseCode; // required
+  public boolean boolValue; // optional
+  public long longValue; // optional
+  public double doubleValue; // optional
+  public @org.apache.thrift.annotation.Nullable java.lang.String stringValue; // optional
+
+  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+    /**
+     * 
+     * @see RESPONSE_CODE
+     */
+    RESPONSE_CODE((short)1, "responseCode"),
+    BOOL_VALUE((short)2, "boolValue"),
+    LONG_VALUE((short)3, "longValue"),
+    DOUBLE_VALUE((short)4, "doubleValue"),
+    STRING_VALUE((short)5, "stringValue");
+
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
+
+    static {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
+        byName.put(field.getFieldName(), field);
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, or null if its not found.
+     */
+    @org.apache.thrift.annotation.Nullable
+    public static _Fields findByThriftId(int fieldId) {
+      switch(fieldId) {
+        case 1: // RESPONSE_CODE
+          return RESPONSE_CODE;
+        case 2: // BOOL_VALUE
+          return BOOL_VALUE;
+        case 3: // LONG_VALUE
+          return LONG_VALUE;
+        case 4: // DOUBLE_VALUE
+          return DOUBLE_VALUE;
+        case 5: // STRING_VALUE
+          return STRING_VALUE;
+        default:
+          return null;
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, throwing an exception
+     * if it is not found.
+     */
+    public static _Fields findByThriftIdOrThrow(int fieldId) {
+      _Fields fields = findByThriftId(fieldId);
+      if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      return fields;
+    }
+
+    /**
+     * Find the _Fields constant that matches name, or null if its not found.
+     */
+    @org.apache.thrift.annotation.Nullable
+    public static _Fields findByName(java.lang.String name) {
+      return byName.get(name);
+    }
+
+    private final short _thriftId;
+    private final java.lang.String _fieldName;
+
+    _Fields(short thriftId, java.lang.String fieldName) {
+      _thriftId = thriftId;
+      _fieldName = fieldName;
+    }
+
+    public short getThriftFieldId() {
+      return _thriftId;
+    }
+
+    public java.lang.String getFieldName() {
+      return _fieldName;
+    }
+  }
+
+  // isset id assignments
+  private static final int __BOOLVALUE_ISSET_ID = 0;
+  private static final int __LONGVALUE_ISSET_ID = 1;
+  private static final int __DOUBLEVALUE_ISSET_ID = 2;
+  private byte __isset_bitfield = 0;
+  private static final _Fields optionals[] = {_Fields.BOOL_VALUE,_Fields.LONG_VALUE,_Fields.DOUBLE_VALUE,_Fields.STRING_VALUE};
+  public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  static {
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+    tmpMap.put(_Fields.RESPONSE_CODE, new org.apache.thrift.meta_data.FieldMetaData("responseCode", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+        new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, RESPONSE_CODE.class)));
+    tmpMap.put(_Fields.BOOL_VALUE, new org.apache.thrift.meta_data.FieldMetaData("boolValue", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
+    tmpMap.put(_Fields.LONG_VALUE, new org.apache.thrift.meta_data.FieldMetaData("longValue", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
+    tmpMap.put(_Fields.DOUBLE_VALUE, new org.apache.thrift.meta_data.FieldMetaData("doubleValue", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.DOUBLE)));
+    tmpMap.put(_Fields.STRING_VALUE, new org.apache.thrift.meta_data.FieldMetaData("stringValue", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(FieldResponse.class, metaDataMap);
+  }
+
+  public FieldResponse() {
+  }
+
+  public FieldResponse(
+    RESPONSE_CODE responseCode)
+  {
+    this();
+    this.responseCode = responseCode;
+  }
+
+  /**
+   * Performs a deep copy on <i>other</i>.
+   */
+  public FieldResponse(FieldResponse other) {
+    __isset_bitfield = other.__isset_bitfield;
+    if (other.isSetResponseCode()) {
+      this.responseCode = other.responseCode;
+    }
+    this.boolValue = other.boolValue;
+    this.longValue = other.longValue;
+    this.doubleValue = other.doubleValue;
+    if (other.isSetStringValue()) {
+      this.stringValue = other.stringValue;
+    }
+  }
+
+  public FieldResponse deepCopy() {
+    return new FieldResponse(this);
+  }
+
+  @Override
+  public void clear() {
+    this.responseCode = null;
+    setBoolValueIsSet(false);
+    this.boolValue = false;
+    setLongValueIsSet(false);
+    this.longValue = 0;
+    setDoubleValueIsSet(false);
+    this.doubleValue = 0.0;
+    this.stringValue = null;
+  }
+
+  /**
+   * 
+   * @see RESPONSE_CODE
+   */
+  @org.apache.thrift.annotation.Nullable
+  public RESPONSE_CODE getResponseCode() {
+    return this.responseCode;
+  }
+
+  /**
+   * 
+   * @see RESPONSE_CODE
+   */
+  public FieldResponse setResponseCode(@org.apache.thrift.annotation.Nullable RESPONSE_CODE responseCode) {
+    this.responseCode = responseCode;
+    return this;
+  }
+
+  public void unsetResponseCode() {
+    this.responseCode = null;
+  }
+
+  /** Returns true if field responseCode is set (has been assigned a value) and false otherwise */
+  public boolean isSetResponseCode() {
+    return this.responseCode != null;
+  }
+
+  public void setResponseCodeIsSet(boolean value) {
+    if (!value) {
+      this.responseCode = null;
+    }
+  }
+
+  public boolean isBoolValue() {
+    return this.boolValue;
+  }
+
+  public FieldResponse setBoolValue(boolean boolValue) {
+    this.boolValue = boolValue;
+    setBoolValueIsSet(true);
+    return this;
+  }
+
+  public void unsetBoolValue() {
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __BOOLVALUE_ISSET_ID);
+  }
+
+  /** Returns true if field boolValue is set (has been assigned a value) and false otherwise */
+  public boolean isSetBoolValue() {
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __BOOLVALUE_ISSET_ID);
+  }
+
+  public void setBoolValueIsSet(boolean value) {
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __BOOLVALUE_ISSET_ID, value);
+  }
+
+  public long getLongValue() {
+    return this.longValue;
+  }
+
+  public FieldResponse setLongValue(long longValue) {
+    this.longValue = longValue;
+    setLongValueIsSet(true);
+    return this;
+  }
+
+  public void unsetLongValue() {
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __LONGVALUE_ISSET_ID);
+  }
+
+  /** Returns true if field longValue is set (has been assigned a value) and false otherwise */
+  public boolean isSetLongValue() {
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __LONGVALUE_ISSET_ID);
+  }
+
+  public void setLongValueIsSet(boolean value) {
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __LONGVALUE_ISSET_ID, value);
+  }
+
+  public double getDoubleValue() {
+    return this.doubleValue;
+  }
+
+  public FieldResponse setDoubleValue(double doubleValue) {
+    this.doubleValue = doubleValue;
+    setDoubleValueIsSet(true);
+    return this;
+  }
+
+  public void unsetDoubleValue() {
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __DOUBLEVALUE_ISSET_ID);
+  }
+
+  /** Returns true if field doubleValue is set (has been assigned a value) and false otherwise */
+  public boolean isSetDoubleValue() {
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __DOUBLEVALUE_ISSET_ID);
+  }
+
+  public void setDoubleValueIsSet(boolean value) {
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __DOUBLEVALUE_ISSET_ID, value);
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public java.lang.String getStringValue() {
+    return this.stringValue;
+  }
+
+  public FieldResponse setStringValue(@org.apache.thrift.annotation.Nullable java.lang.String stringValue) {
+    this.stringValue = stringValue;
+    return this;
+  }
+
+  public void unsetStringValue() {
+    this.stringValue = null;
+  }
+
+  /** Returns true if field stringValue is set (has been assigned a value) and false otherwise */
+  public boolean isSetStringValue() {
+    return this.stringValue != null;
+  }
+
+  public void setStringValueIsSet(boolean value) {
+    if (!value) {
+      this.stringValue = null;
+    }
+  }
+
+  public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) {
+    switch (field) {
+    case RESPONSE_CODE:
+      if (value == null) {
+        unsetResponseCode();
+      } else {
+        setResponseCode((RESPONSE_CODE)value);
+      }
+      break;
+
+    case BOOL_VALUE:
+      if (value == null) {
+        unsetBoolValue();
+      } else {
+        setBoolValue((java.lang.Boolean)value);
+      }
+      break;
+
+    case LONG_VALUE:
+      if (value == null) {
+        unsetLongValue();
+      } else {
+        setLongValue((java.lang.Long)value);
+      }
+      break;
+
+    case DOUBLE_VALUE:
+      if (value == null) {
+        unsetDoubleValue();
+      } else {
+        setDoubleValue((java.lang.Double)value);
+      }
+      break;
+
+    case STRING_VALUE:
+      if (value == null) {
+        unsetStringValue();
+      } else {
+        setStringValue((java.lang.String)value);
+      }
+      break;
+
+    }
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public java.lang.Object getFieldValue(_Fields field) {
+    switch (field) {
+    case RESPONSE_CODE:
+      return getResponseCode();
+
+    case BOOL_VALUE:
+      return isBoolValue();
+
+    case LONG_VALUE:
+      return getLongValue();
+
+    case DOUBLE_VALUE:
+      return getDoubleValue();
+
+    case STRING_VALUE:
+      return getStringValue();
+
+    }
+    throw new java.lang.IllegalStateException();
+  }
+
+  /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+  public boolean isSet(_Fields field) {
+    if (field == null) {
+      throw new java.lang.IllegalArgumentException();
+    }
+
+    switch (field) {
+    case RESPONSE_CODE:
+      return isSetResponseCode();
+    case BOOL_VALUE:
+      return isSetBoolValue();
+    case LONG_VALUE:
+      return isSetLongValue();
+    case DOUBLE_VALUE:
+      return isSetDoubleValue();
+    case STRING_VALUE:
+      return isSetStringValue();
+    }
+    throw new java.lang.IllegalStateException();
+  }
+
+  @Override
+  public boolean equals(java.lang.Object that) {
+    if (that == null)
+      return false;
+    if (that instanceof FieldResponse)
+      return this.equals((FieldResponse)that);
+    return false;
+  }
+
+  public boolean equals(FieldResponse that) {
+    if (that == null)
+      return false;
+    if (this == that)
+      return true;
+
+    boolean this_present_responseCode = true && this.isSetResponseCode();
+    boolean that_present_responseCode = true && that.isSetResponseCode();
+    if (this_present_responseCode || that_present_responseCode) {
+      if (!(this_present_responseCode && that_present_responseCode))
+        return false;
+      if (!this.responseCode.equals(that.responseCode))
+        return false;
+    }
+
+    boolean this_present_boolValue = true && this.isSetBoolValue();
+    boolean that_present_boolValue = true && that.isSetBoolValue();
+    if (this_present_boolValue || that_present_boolValue) {
+      if (!(this_present_boolValue && that_present_boolValue))
+        return false;
+      if (this.boolValue != that.boolValue)
+        return false;
+    }
+
+    boolean this_present_longValue = true && this.isSetLongValue();
+    boolean that_present_longValue = true && that.isSetLongValue();
+    if (this_present_longValue || that_present_longValue) {
+      if (!(this_present_longValue && that_present_longValue))
+        return false;
+      if (this.longValue != that.longValue)
+        return false;
+    }
+
+    boolean this_present_doubleValue = true && this.isSetDoubleValue();
+    boolean that_present_doubleValue = true && that.isSetDoubleValue();
+    if (this_present_doubleValue || that_present_doubleValue) {
+      if (!(this_present_doubleValue && that_present_doubleValue))
+        return false;
+      if (this.doubleValue != that.doubleValue)
+        return false;
+    }
+
+    boolean this_present_stringValue = true && this.isSetStringValue();
+    boolean that_present_stringValue = true && that.isSetStringValue();
+    if (this_present_stringValue || that_present_stringValue) {
+      if (!(this_present_stringValue && that_present_stringValue))
+        return false;
+      if (!this.stringValue.equals(that.stringValue))
+        return false;
+    }
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int hashCode = 1;
+
+    hashCode = hashCode * 8191 + ((isSetResponseCode()) ? 131071 : 524287);
+    if (isSetResponseCode())
+      hashCode = hashCode * 8191 + responseCode.getValue();
+
+    hashCode = hashCode * 8191 + ((isSetBoolValue()) ? 131071 : 524287);
+    if (isSetBoolValue())
+      hashCode = hashCode * 8191 + ((boolValue) ? 131071 : 524287);
+
+    hashCode = hashCode * 8191 + ((isSetLongValue()) ? 131071 : 524287);
+    if (isSetLongValue())
+      hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(longValue);
+
+    hashCode = hashCode * 8191 + ((isSetDoubleValue()) ? 131071 : 524287);
+    if (isSetDoubleValue())
+      hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(doubleValue);
+
+    hashCode = hashCode * 8191 + ((isSetStringValue()) ? 131071 : 524287);
+    if (isSetStringValue())
+      hashCode = hashCode * 8191 + stringValue.hashCode();
+
+    return hashCode;
+  }
+
+  @Override
+  public int compareTo(FieldResponse other) {
+    if (!getClass().equals(other.getClass())) {
+      return getClass().getName().compareTo(other.getClass().getName());
+    }
+
+    int lastComparison = 0;
+
+    lastComparison = java.lang.Boolean.valueOf(isSetResponseCode()).compareTo(other.isSetResponseCode());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetResponseCode()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.responseCode, other.responseCode);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    lastComparison = java.lang.Boolean.valueOf(isSetBoolValue()).compareTo(other.isSetBoolValue());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetBoolValue()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.boolValue, other.boolValue);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    lastComparison = java.lang.Boolean.valueOf(isSetLongValue()).compareTo(other.isSetLongValue());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetLongValue()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.longValue, other.longValue);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    lastComparison = java.lang.Boolean.valueOf(isSetDoubleValue()).compareTo(other.isSetDoubleValue());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetDoubleValue()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.doubleValue, other.doubleValue);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    lastComparison = java.lang.Boolean.valueOf(isSetStringValue()).compareTo(other.isSetStringValue());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetStringValue()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.stringValue, other.stringValue);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    return 0;
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public _Fields fieldForId(int fieldId) {
+    return _Fields.findByThriftId(fieldId);
+  }
+
+  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+    scheme(iprot).read(iprot, this);
+  }
+
+  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+    scheme(oprot).write(oprot, this);
+  }
+
+  @Override
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("FieldResponse(");
+    boolean first = true;
+
+    sb.append("responseCode:");
+    if (this.responseCode == null) {
+      sb.append("null");
+    } else {
+      sb.append(this.responseCode);
+    }
+    first = false;
+    if (isSetBoolValue()) {
+      if (!first) sb.append(", ");
+      sb.append("boolValue:");
+      sb.append(this.boolValue);
+      first = false;
+    }
+    if (isSetLongValue()) {
+      if (!first) sb.append(", ");
+      sb.append("longValue:");
+      sb.append(this.longValue);
+      first = false;
+    }
+    if (isSetDoubleValue()) {
+      if (!first) sb.append(", ");
+      sb.append("doubleValue:");
+      sb.append(this.doubleValue);
+      first = false;
+    }
+    if (isSetStringValue()) {
+      if (!first) sb.append(", ");
+      sb.append("stringValue:");
+      if (this.stringValue == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.stringValue);
+      }
+      first = false;
+    }
+    sb.append(")");
+    return sb.toString();
+  }
+
+  public void validate() throws org.apache.thrift.TException {
+    // check for required fields
+    // check for sub-struct validity
+  }
+
+  private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+    try {
+      write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
+    try {
+      // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
+      __isset_bitfield = 0;
+      read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private static class FieldResponseStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+    public FieldResponseStandardScheme getScheme() {
+      return new FieldResponseStandardScheme();
+    }
+  }
+
+  private static class FieldResponseStandardScheme extends org.apache.thrift.scheme.StandardScheme<FieldResponse> {
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot, FieldResponse struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TField schemeField;
+      iprot.readStructBegin();
+      while (true)
+      {
+        schemeField = iprot.readFieldBegin();
+        if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+          break;
+        }
+        switch (schemeField.id) {
+          case 1: // RESPONSE_CODE
+            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+              struct.responseCode = org.apache.plc4x.interop.RESPONSE_CODE.findByValue(iprot.readI32());
+              struct.setResponseCodeIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          case 2: // BOOL_VALUE
+            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
+              struct.boolValue = iprot.readBool();
+              struct.setBoolValueIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          case 3: // LONG_VALUE
+            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
+              struct.longValue = iprot.readI64();
+              struct.setLongValueIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          case 4: // DOUBLE_VALUE
+            if (schemeField.type == org.apache.thrift.protocol.TType.DOUBLE) {
+              struct.doubleValue = iprot.readDouble();
+              struct.setDoubleValueIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          case 5: // STRING_VALUE
+            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+              struct.stringValue = iprot.readString();
+              struct.setStringValueIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          default:
+            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+        }
+        iprot.readFieldEnd();
+      }
+      iprot.readStructEnd();
+
+      // check for required fields of primitive type, which can't be checked in the validate method
+      struct.validate();
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot, FieldResponse struct) throws org.apache.thrift.TException {
+      struct.validate();
+
+      oprot.writeStructBegin(STRUCT_DESC);
+      if (struct.responseCode != null) {
+        oprot.writeFieldBegin(RESPONSE_CODE_FIELD_DESC);
+        oprot.writeI32(struct.responseCode.getValue());
+        oprot.writeFieldEnd();
+      }
+      if (struct.isSetBoolValue()) {
+        oprot.writeFieldBegin(BOOL_VALUE_FIELD_DESC);
+        oprot.writeBool(struct.boolValue);
+        oprot.writeFieldEnd();
+      }
+      if (struct.isSetLongValue()) {
+        oprot.writeFieldBegin(LONG_VALUE_FIELD_DESC);
+        oprot.writeI64(struct.longValue);
+        oprot.writeFieldEnd();
+      }
+      if (struct.isSetDoubleValue()) {
+        oprot.writeFieldBegin(DOUBLE_VALUE_FIELD_DESC);
+        oprot.writeDouble(struct.doubleValue);
+        oprot.writeFieldEnd();
+      }
+      if (struct.stringValue != null) {
+        if (struct.isSetStringValue()) {
+          oprot.writeFieldBegin(STRING_VALUE_FIELD_DESC);
+          oprot.writeString(struct.stringValue);
+          oprot.writeFieldEnd();
+        }
+      }
+      oprot.writeFieldStop();
+      oprot.writeStructEnd();
+    }
+
+  }
+
+  private static class FieldResponseTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+    public FieldResponseTupleScheme getScheme() {
+      return new FieldResponseTupleScheme();
+    }
+  }
+
+  private static class FieldResponseTupleScheme extends org.apache.thrift.scheme.TupleScheme<FieldResponse> {
+
+    @Override
+    public void write(org.apache.thrift.protocol.TProtocol prot, FieldResponse struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
+      if (struct.isSetResponseCode()) {
+        optionals.set(0);
+      }
+      if (struct.isSetBoolValue()) {
+        optionals.set(1);
+      }
+      if (struct.isSetLongValue()) {
+        optionals.set(2);
+      }
+      if (struct.isSetDoubleValue()) {
+        optionals.set(3);
+      }
+      if (struct.isSetStringValue()) {
+        optionals.set(4);
+      }
+      oprot.writeBitSet(optionals, 5);
+      if (struct.isSetResponseCode()) {
+        oprot.writeI32(struct.responseCode.getValue());
+      }
+      if (struct.isSetBoolValue()) {
+        oprot.writeBool(struct.boolValue);
+      }
+      if (struct.isSetLongValue()) {
+        oprot.writeI64(struct.longValue);
+      }
+      if (struct.isSetDoubleValue()) {
+        oprot.writeDouble(struct.doubleValue);
+      }
+      if (struct.isSetStringValue()) {
+        oprot.writeString(struct.stringValue);
+      }
+    }
+
+    @Override
+    public void read(org.apache.thrift.protocol.TProtocol prot, FieldResponse struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(5);
+      if (incoming.get(0)) {
+        struct.responseCode = org.apache.plc4x.interop.RESPONSE_CODE.findByValue(iprot.readI32());
+        struct.setResponseCodeIsSet(true);
+      }
+      if (incoming.get(1)) {
+        struct.boolValue = iprot.readBool();
+        struct.setBoolValueIsSet(true);
+      }
+      if (incoming.get(2)) {
+        struct.longValue = iprot.readI64();
+        struct.setLongValueIsSet(true);
+      }
+      if (incoming.get(3)) {
+        struct.doubleValue = iprot.readDouble();
+        struct.setDoubleValueIsSet(true);
+      }
+      if (incoming.get(4)) {
+        struct.stringValue = iprot.readString();
+        struct.setStringValueIsSet(true);
+      }
+    }
+  }
+
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+}
+
diff --git a/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/InteropServer.java b/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/InteropServer.java
new file mode 100644
index 0000000..1cc5341
--- /dev/null
+++ b/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/InteropServer.java
@@ -0,0 +1,2989 @@
+/**
+ * Autogenerated by Thrift Compiler (0.12.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+package org.apache.plc4x.interop;
+
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.12.0)", date = "2019-04-14")
+public class InteropServer {
+
+  public interface Iface {
+
+    public ConnectionHandle connect(java.lang.String connectionString) throws PlcException, org.apache.thrift.TException;
+
+    public Response execute(ConnectionHandle handle, Request request) throws PlcException, org.apache.thrift.TException;
+
+    public void close(ConnectionHandle handle) throws org.apache.thrift.TException;
+
+  }
+
+  public interface AsyncIface {
+
+    public void connect(java.lang.String connectionString, org.apache.thrift.async.AsyncMethodCallback<ConnectionHandle> resultHandler) throws org.apache.thrift.TException;
+
+    public void execute(ConnectionHandle handle, Request request, org.apache.thrift.async.AsyncMethodCallback<Response> resultHandler) throws org.apache.thrift.TException;
+
+    public void close(ConnectionHandle handle, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
+
+  }
+
+  public static class Client extends org.apache.thrift.TServiceClient implements Iface {
+    public static class Factory implements org.apache.thrift.TServiceClientFactory<Client> {
+      public Factory() {}
+      public Client getClient(org.apache.thrift.protocol.TProtocol prot) {
+        return new Client(prot);
+      }
+      public Client getClient(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
+        return new Client(iprot, oprot);
+      }
+    }
+
+    public Client(org.apache.thrift.protocol.TProtocol prot)
+    {
+      super(prot, prot);
+    }
+
+    public Client(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
+      super(iprot, oprot);
+    }
+
+    public ConnectionHandle connect(java.lang.String connectionString) throws PlcException, org.apache.thrift.TException
+    {
+      send_connect(connectionString);
+      return recv_connect();
+    }
+
+    public void send_connect(java.lang.String connectionString) throws org.apache.thrift.TException
+    {
+      connect_args args = new connect_args();
+      args.setConnectionString(connectionString);
+      sendBase("connect", args);
+    }
+
+    public ConnectionHandle recv_connect() throws PlcException, org.apache.thrift.TException
+    {
+      connect_result result = new connect_result();
+      receiveBase(result, "connect");
+      if (result.isSetSuccess()) {
+        return result.success;
+      }
+      if (result.connectionException != null) {
+        throw result.connectionException;
+      }
+      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "connect failed: unknown result");
+    }
+
+    public Response execute(ConnectionHandle handle, Request request) throws PlcException, org.apache.thrift.TException
+    {
+      send_execute(handle, request);
+      return recv_execute();
+    }
+
+    public void send_execute(ConnectionHandle handle, Request request) throws org.apache.thrift.TException
+    {
+      execute_args args = new execute_args();
+      args.setHandle(handle);
+      args.setRequest(request);
+      sendBase("execute", args);
+    }
+
+    public Response recv_execute() throws PlcException, org.apache.thrift.TException
+    {
+      execute_result result = new execute_result();
+      receiveBase(result, "execute");
+      if (result.isSetSuccess()) {
+        return result.success;
+      }
+      if (result.executionException != null) {
+        throw result.executionException;
+      }
+      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "execute failed: unknown result");
+    }
+
+    public void close(ConnectionHandle handle) throws org.apache.thrift.TException
+    {
+      send_close(handle);
+      recv_close();
+    }
+
+    public void send_close(ConnectionHandle handle) throws org.apache.thrift.TException
+    {
+      close_args args = new close_args();
+      args.setHandle(handle);
+      sendBase("close", args);
+    }
+
+    public void recv_close() throws org.apache.thrift.TException
+    {
+      close_result result = new close_result();
+      receiveBase(result, "close");
+      return;
+    }
+
+  }
+  public static class AsyncClient extends org.apache.thrift.async.TAsyncClient implements AsyncIface {
+    public static class Factory implements org.apache.thrift.async.TAsyncClientFactory<AsyncClient> {
+      private org.apache.thrift.async.TAsyncClientManager clientManager;
+      private org.apache.thrift.protocol.TProtocolFactory protocolFactory;
+      public Factory(org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.protocol.TProtocolFactory protocolFactory) {
+        this.clientManager = clientManager;
+        this.protocolFactory = protocolFactory;
+      }
+      public AsyncClient getAsyncClient(org.apache.thrift.transport.TNonblockingTransport transport) {
+        return new AsyncClient(protocolFactory, clientManager, transport);
+      }
+    }
+
+    public AsyncClient(org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.transport.TNonblockingTransport transport) {
+      super(protocolFactory, clientManager, transport);
+    }
+
+    public void connect(java.lang.String connectionString, org.apache.thrift.async.AsyncMethodCallback<ConnectionHandle> resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      connect_call method_call = new connect_call(connectionString, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class connect_call extends org.apache.thrift.async.TAsyncMethodCall<ConnectionHandle> {
+      private java.lang.String connectionString;
+      public connect_call(java.lang.String connectionString, org.apache.thrift.async.AsyncMethodCallback<ConnectionHandle> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.connectionString = connectionString;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("connect", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        connect_args args = new connect_args();
+        args.setConnectionString(connectionString);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public ConnectionHandle getResult() throws PlcException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new java.lang.IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return (new Client(prot)).recv_connect();
+      }
+    }
+
+    public void execute(ConnectionHandle handle, Request request, org.apache.thrift.async.AsyncMethodCallback<Response> resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      execute_call method_call = new execute_call(handle, request, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class execute_call extends org.apache.thrift.async.TAsyncMethodCall<Response> {
+      private ConnectionHandle handle;
+      private Request request;
+      public execute_call(ConnectionHandle handle, Request request, org.apache.thrift.async.AsyncMethodCallback<Response> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.handle = handle;
+        this.request = request;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("execute", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        execute_args args = new execute_args();
+        args.setHandle(handle);
+        args.setRequest(request);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public Response getResult() throws PlcException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new java.lang.IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return (new Client(prot)).recv_execute();
+      }
+    }
+
+    public void close(ConnectionHandle handle, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      close_call method_call = new close_call(handle, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class close_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private ConnectionHandle handle;
+      public close_call(ConnectionHandle handle, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.handle = handle;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("close", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        close_args args = new close_args();
+        args.setHandle(handle);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public Void getResult() throws org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new java.lang.IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return null;
+      }
+    }
+
+  }
+
+  public static class Processor<I extends Iface> extends org.apache.thrift.TBaseProcessor<I> implements org.apache.thrift.TProcessor {
+    private static final org.slf4j.Logger _LOGGER = org.slf4j.LoggerFactory.getLogger(Processor.class.getName());
+    public Processor(I iface) {
+      super(iface, getProcessMap(new java.util.HashMap<java.lang.String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>>()));
+    }
+
+    protected Processor(I iface, java.util.Map<java.lang.String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> processMap) {
+      super(iface, getProcessMap(processMap));
+    }
+
+    private static <I extends Iface> java.util.Map<java.lang.String,  org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> getProcessMap(java.util.Map<java.lang.String, org.apache.thrift.ProcessFunction<I, ? extends  org.apache.thrift.TBase>> processMap) {
+      processMap.put("connect", new connect());
+      processMap.put("execute", new execute());
+      processMap.put("close", new close());
+      return processMap;
+    }
+
+    public static class connect<I extends Iface> extends org.apache.thrift.ProcessFunction<I, connect_args> {
+      public connect() {
+        super("connect");
+      }
+
+      public connect_args getEmptyArgsInstance() {
+        return new connect_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      @Override
+      protected boolean rethrowUnhandledExceptions() {
+        return false;
+      }
+
+      public connect_result getResult(I iface, connect_args args) throws org.apache.thrift.TException {
+        connect_result result = new connect_result();
+        try {
+          result.success = iface.connect(args.connectionString);
+        } catch (PlcException connectionException) {
+          result.connectionException = connectionException;
+        }
+        return result;
+      }
+    }
+
+    public static class execute<I extends Iface> extends org.apache.thrift.ProcessFunction<I, execute_args> {
+      public execute() {
+        super("execute");
+      }
+
+      public execute_args getEmptyArgsInstance() {
+        return new execute_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      @Override
+      protected boolean rethrowUnhandledExceptions() {
+        return false;
+      }
+
+      public execute_result getResult(I iface, execute_args args) throws org.apache.thrift.TException {
+        execute_result result = new execute_result();
+        try {
+          result.success = iface.execute(args.handle, args.request);
+        } catch (PlcException executionException) {
+          result.executionException = executionException;
+        }
+        return result;
+      }
+    }
+
+    public static class close<I extends Iface> extends org.apache.thrift.ProcessFunction<I, close_args> {
+      public close() {
+        super("close");
+      }
+
+      public close_args getEmptyArgsInstance() {
+        return new close_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      @Override
+      protected boolean rethrowUnhandledExceptions() {
+        return false;
+      }
+
+      public close_result getResult(I iface, close_args args) throws org.apache.thrift.TException {
+        close_result result = new close_result();
+        iface.close(args.handle);
+        return result;
+      }
+    }
+
+  }
+
+  public static class AsyncProcessor<I extends AsyncIface> extends org.apache.thrift.TBaseAsyncProcessor<I> {
+    private static final org.slf4j.Logger _LOGGER = org.slf4j.LoggerFactory.getLogger(AsyncProcessor.class.getName());
+    public AsyncProcessor(I iface) {
+      super(iface, getProcessMap(new java.util.HashMap<java.lang.String, org.apache.thrift.AsyncProcessFunction<I, ? extends org.apache.thrift.TBase, ?>>()));
+    }
+
+    protected AsyncProcessor(I iface, java.util.Map<java.lang.String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase, ?>> processMap) {
+      super(iface, getProcessMap(processMap));
+    }
+
+    private static <I extends AsyncIface> java.util.Map<java.lang.String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase,?>> getProcessMap(java.util.Map<java.lang.String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase, ?>> processMap) {
+      processMap.put("connect", new connect());
+      processMap.put("execute", new execute());
+      processMap.put("close", new close());
+      return processMap;
+    }
+
+    public static class connect<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, connect_args, ConnectionHandle> {
+      public connect() {
+        super("connect");
+      }
+
+      public connect_args getEmptyArgsInstance() {
+        return new connect_args();
+      }
+
+      public org.apache.thrift.async.AsyncMethodCallback<ConnectionHandle> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new org.apache.thrift.async.AsyncMethodCallback<ConnectionHandle>() { 
+          public void onComplete(ConnectionHandle o) {
+            connect_result result = new connect_result();
+            result.success = o;
+            try {
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
+            }
+          }
+          public void onError(java.lang.Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TSerializable msg;
+            connect_result result = new connect_result();
+            if (e instanceof PlcException) {
+              result.connectionException = (PlcException) e;
+              result.setConnectionExceptionIsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
+            }
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, connect_args args, org.apache.thrift.async.AsyncMethodCallback<ConnectionHandle> resultHandler) throws org.apache.thrift.TException {
+        iface.connect(args.connectionString,resultHandler);
+      }
+    }
+
+    public static class execute<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, execute_args, Response> {
+      public execute() {
+        super("execute");
+      }
+
+      public execute_args getEmptyArgsInstance() {
+        return new execute_args();
+      }
+
+      public org.apache.thrift.async.AsyncMethodCallback<Response> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new org.apache.thrift.async.AsyncMethodCallback<Response>() { 
+          public void onComplete(Response o) {
+            execute_result result = new execute_result();
+            result.success = o;
+            try {
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
+            }
+          }
+          public void onError(java.lang.Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TSerializable msg;
+            execute_result result = new execute_result();
+            if (e instanceof PlcException) {
+              result.executionException = (PlcException) e;
+              result.setExecutionExceptionIsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
+            }
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, execute_args args, org.apache.thrift.async.AsyncMethodCallback<Response> resultHandler) throws org.apache.thrift.TException {
+        iface.execute(args.handle, args.request,resultHandler);
+      }
+    }
+
+    public static class close<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, close_args, Void> {
+      public close() {
+        super("close");
+      }
+
+      public close_args getEmptyArgsInstance() {
+        return new close_args();
+      }
+
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
+          public void onComplete(Void o) {
+            close_result result = new close_result();
+            try {
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
+            }
+          }
+          public void onError(java.lang.Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TSerializable msg;
+            close_result result = new close_result();
+            if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
+            }
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, close_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
+        iface.close(args.handle,resultHandler);
+      }
+    }
+
+  }
+
+  public static class connect_args implements org.apache.thrift.TBase<connect_args, connect_args._Fields>, java.io.Serializable, Cloneable, Comparable<connect_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("connect_args");
+
+    private static final org.apache.thrift.protocol.TField CONNECTION_STRING_FIELD_DESC = new org.apache.thrift.protocol.TField("connectionString", org.apache.thrift.protocol.TType.STRING, (short)1);
+
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new connect_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new connect_argsTupleSchemeFactory();
+
+    public @org.apache.thrift.annotation.Nullable java.lang.String connectionString; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      CONNECTION_STRING((short)1, "connectionString");
+
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
+
+      static {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      @org.apache.thrift.annotation.Nullable
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // CONNECTION_STRING
+            return CONNECTION_STRING;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      @org.apache.thrift.annotation.Nullable
+      public static _Fields findByName(java.lang.String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final java.lang.String _fieldName;
+
+      _Fields(short thriftId, java.lang.String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public java.lang.String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.CONNECTION_STRING, new org.apache.thrift.meta_data.FieldMetaData("connectionString", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(connect_args.class, metaDataMap);
+    }
+
+    public connect_args() {
+    }
+
+    public connect_args(
+      java.lang.String connectionString)
+    {
+      this();
+      this.connectionString = connectionString;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public connect_args(connect_args other) {
+      if (other.isSetConnectionString()) {
+        this.connectionString = other.connectionString;
+      }
+    }
+
+    public connect_args deepCopy() {
+      return new connect_args(this);
+    }
+
+    @Override
+    public void clear() {
+      this.connectionString = null;
+    }
+
+    @org.apache.thrift.annotation.Nullable
+    public java.lang.String getConnectionString() {
+      return this.connectionString;
+    }
+
+    public connect_args setConnectionString(@org.apache.thrift.annotation.Nullable java.lang.String connectionString) {
+      this.connectionString = connectionString;
+      return this;
+    }
+
+    public void unsetConnectionString() {
+      this.connectionString = null;
+    }
+
+    /** Returns true if field connectionString is set (has been assigned a value) and false otherwise */
+    public boolean isSetConnectionString() {
+      return this.connectionString != null;
+    }
+
+    public void setConnectionStringIsSet(boolean value) {
+      if (!value) {
+        this.connectionString = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) {
+      switch (field) {
+      case CONNECTION_STRING:
+        if (value == null) {
+          unsetConnectionString();
+        } else {
+          setConnectionString((java.lang.String)value);
+        }
+        break;
+
+      }
+    }
+
+    @org.apache.thrift.annotation.Nullable
+    public java.lang.Object getFieldValue(_Fields field) {
+      switch (field) {
+      case CONNECTION_STRING:
+        return getConnectionString();
+
+      }
+      throw new java.lang.IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new java.lang.IllegalArgumentException();
+      }
+
+      switch (field) {
+      case CONNECTION_STRING:
+        return isSetConnectionString();
+      }
+      throw new java.lang.IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(java.lang.Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof connect_args)
+        return this.equals((connect_args)that);
+      return false;
+    }
+
+    public boolean equals(connect_args that) {
+      if (that == null)
+        return false;
+      if (this == that)
+        return true;
+
+      boolean this_present_connectionString = true && this.isSetConnectionString();
+      boolean that_present_connectionString = true && that.isSetConnectionString();
+      if (this_present_connectionString || that_present_connectionString) {
+        if (!(this_present_connectionString && that_present_connectionString))
+          return false;
+        if (!this.connectionString.equals(that.connectionString))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      int hashCode = 1;
+
+      hashCode = hashCode * 8191 + ((isSetConnectionString()) ? 131071 : 524287);
+      if (isSetConnectionString())
+        hashCode = hashCode * 8191 + connectionString.hashCode();
+
+      return hashCode;
+    }
+
+    @Override
+    public int compareTo(connect_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = java.lang.Boolean.valueOf(isSetConnectionString()).compareTo(other.isSetConnectionString());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetConnectionString()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.connectionString, other.connectionString);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    @org.apache.thrift.annotation.Nullable
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      scheme(iprot).read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      scheme(oprot).write(oprot, this);
+    }
+
+    @Override
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("connect_args(");
+      boolean first = true;
+
+      sb.append("connectionString:");
+      if (this.connectionString == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.connectionString);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class connect_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public connect_argsStandardScheme getScheme() {
+        return new connect_argsStandardScheme();
+      }
+    }
+
+    private static class connect_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<connect_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, connect_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // CONNECTION_STRING
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.connectionString = iprot.readString();
+                struct.setConnectionStringIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, connect_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.connectionString != null) {
+          oprot.writeFieldBegin(CONNECTION_STRING_FIELD_DESC);
+          oprot.writeString(struct.connectionString);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class connect_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public connect_argsTupleScheme getScheme() {
+        return new connect_argsTupleScheme();
+      }
+    }
+
+    private static class connect_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<connect_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, connect_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
+        if (struct.isSetConnectionString()) {
+          optionals.set(0);
+        }
+        oprot.writeBitSet(optionals, 1);
+        if (struct.isSetConnectionString()) {
+          oprot.writeString(struct.connectionString);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, connect_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(1);
+        if (incoming.get(0)) {
+          struct.connectionString = iprot.readString();
+          struct.setConnectionStringIsSet(true);
+        }
+      }
+    }
+
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
+  }
+
+  public static class connect_result implements org.apache.thrift.TBase<connect_result, connect_result._Fields>, java.io.Serializable, Cloneable, Comparable<connect_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("connect_result");
+
+    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRUCT, (short)0);
+    private static final org.apache.thrift.protocol.TField CONNECTION_EXCEPTION_FIELD_DESC = new org.apache.thrift.protocol.TField("connectionException", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new connect_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new connect_resultTupleSchemeFactory();
+
+    public @org.apache.thrift.annotation.Nullable ConnectionHandle success; // required
+    public @org.apache.thrift.annotation.Nullable PlcException connectionException; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      SUCCESS((short)0, "success"),
+      CONNECTION_EXCEPTION((short)1, "connectionException");
+
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
+
+      static {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      @org.apache.thrift.annotation.Nullable
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 0: // SUCCESS
+            return SUCCESS;
+          case 1: // CONNECTION_EXCEPTION
+            return CONNECTION_EXCEPTION;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      @org.apache.thrift.annotation.Nullable
+      public static _Fields findByName(java.lang.String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final java.lang.String _fieldName;
+
+      _Fields(short thriftId, java.lang.String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public java.lang.String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ConnectionHandle.class)));
+      tmpMap.put(_Fields.CONNECTION_EXCEPTION, new org.apache.thrift.meta_data.FieldMetaData("connectionException", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, PlcException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(connect_result.class, metaDataMap);
+    }
+
+    public connect_result() {
+    }
+
+    public connect_result(
+      ConnectionHandle success,
+      PlcException connectionException)
+    {
+      this();
+      this.success = success;
+      this.connectionException = connectionException;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public connect_result(connect_result other) {
+      if (other.isSetSuccess()) {
+        this.success = new ConnectionHandle(other.success);
+      }
+      if (other.isSetConnectionException()) {
+        this.connectionException = new PlcException(other.connectionException);
+      }
+    }
+
+    public connect_result deepCopy() {
+      return new connect_result(this);
+    }
+
+    @Override
+    public void clear() {
+      this.success = null;
+      this.connectionException = null;
+    }
+
+    @org.apache.thrift.annotation.Nullable
+    public ConnectionHandle getSuccess() {
+      return this.success;
+    }
+
+    public connect_result setSuccess(@org.apache.thrift.annotation.Nullable ConnectionHandle success) {
+      this.success = success;
+      return this;
+    }
+
+    public void unsetSuccess() {
+      this.success = null;
+    }
+
+    /** Returns true if field success is set (has been assigned a value) and false otherwise */
+    public boolean isSetSuccess() {
+      return this.success != null;
+    }
+
+    public void setSuccessIsSet(boolean value) {
+      if (!value) {
+        this.success = null;
+      }
+    }
+
+    @org.apache.thrift.annotation.Nullable
+    public PlcException getConnectionException() {
+      return this.connectionException;
+    }
+
+    public connect_result setConnectionException(@org.apache.thrift.annotation.Nullable PlcException connectionException) {
+      this.connectionException = connectionException;
+      return this;
+    }
+
+    public void unsetConnectionException() {
+      this.connectionException = null;
+    }
+
+    /** Returns true if field connectionException is set (has been assigned a value) and false otherwise */
+    public boolean isSetConnectionException() {
+      return this.connectionException != null;
+    }
+
+    public void setConnectionExceptionIsSet(boolean value) {
+      if (!value) {
+        this.connectionException = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((ConnectionHandle)value);
+        }
+        break;
+
+      case CONNECTION_EXCEPTION:
+        if (value == null) {
+          unsetConnectionException();
+        } else {
+          setConnectionException((PlcException)value);
+        }
+        break;
+
+      }
+    }
+
+    @org.apache.thrift.annotation.Nullable
+    public java.lang.Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      case CONNECTION_EXCEPTION:
+        return getConnectionException();
+
+      }
+      throw new java.lang.IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new java.lang.IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case CONNECTION_EXCEPTION:
+        return isSetConnectionException();
+      }
+      throw new java.lang.IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(java.lang.Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof connect_result)
+        return this.equals((connect_result)that);
+      return false;
+    }
+
+    public boolean equals(connect_result that) {
+      if (that == null)
+        return false;
+      if (this == that)
+        return true;
+
+      boolean this_present_success = true && this.isSetSuccess();
+      boolean that_present_success = true && that.isSetSuccess();
+      if (this_present_success || that_present_success) {
+        if (!(this_present_success && that_present_success))
+          return false;
+        if (!this.success.equals(that.success))
+          return false;
+      }
+
+      boolean this_present_connectionException = true && this.isSetConnectionException();
+      boolean that_present_connectionException = true && that.isSetConnectionException();
+      if (this_present_connectionException || that_present_connectionException) {
+        if (!(this_present_connectionException && that_present_connectionException))
+          return false;
+        if (!this.connectionException.equals(that.connectionException))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      int hashCode = 1;
+
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
+
+      hashCode = hashCode * 8191 + ((isSetConnectionException()) ? 131071 : 524287);
+      if (isSetConnectionException())
+        hashCode = hashCode * 8191 + connectionException.hashCode();
+
+      return hashCode;
+    }
+
+    @Override
+    public int compareTo(connect_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetSuccess()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = java.lang.Boolean.valueOf(isSetConnectionException()).compareTo(other.isSetConnectionException());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetConnectionException()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.connectionException, other.connectionException);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    @org.apache.thrift.annotation.Nullable
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      scheme(iprot).read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      scheme(oprot).write(oprot, this);
+      }
+
+    @Override
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("connect_result(");
+      boolean first = true;
+
+      sb.append("success:");
+      if (this.success == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.success);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("connectionException:");
+      if (this.connectionException == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.connectionException);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+      if (success != null) {
+        success.validate();
+      }
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class connect_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public connect_resultStandardScheme getScheme() {
+        return new connect_resultStandardScheme();
+      }
+    }
+
+    private static class connect_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<connect_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, connect_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 0: // SUCCESS
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.success = new ConnectionHandle();
+                struct.success.read(iprot);
+                struct.setSuccessIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 1: // CONNECTION_EXCEPTION
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.connectionException = new PlcException();
+                struct.connectionException.read(iprot);
+                struct.setConnectionExceptionIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, connect_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.success != null) {
+          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
+          struct.success.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.connectionException != null) {
+          oprot.writeFieldBegin(CONNECTION_EXCEPTION_FIELD_DESC);
+          struct.connectionException.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class connect_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public connect_resultTupleScheme getScheme() {
+        return new connect_resultTupleScheme();
+      }
+    }
+
+    private static class connect_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<connect_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, connect_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
+        if (struct.isSetSuccess()) {
+          optionals.set(0);
+        }
+        if (struct.isSetConnectionException()) {
+          optionals.set(1);
+        }
+        oprot.writeBitSet(optionals, 2);
+        if (struct.isSetSuccess()) {
+          struct.success.write(oprot);
+        }
+        if (struct.isSetConnectionException()) {
+          struct.connectionException.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, connect_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
+        if (incoming.get(0)) {
+          struct.success = new ConnectionHandle();
+          struct.success.read(iprot);
+          struct.setSuccessIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.connectionException = new PlcException();
+          struct.connectionException.read(iprot);
+          struct.setConnectionExceptionIsSet(true);
+        }
+      }
+    }
+
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
+  }
+
+  public static class execute_args implements org.apache.thrift.TBase<execute_args, execute_args._Fields>, java.io.Serializable, Cloneable, Comparable<execute_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("execute_args");
+
+    private static final org.apache.thrift.protocol.TField HANDLE_FIELD_DESC = new org.apache.thrift.protocol.TField("handle", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+    private static final org.apache.thrift.protocol.TField REQUEST_FIELD_DESC = new org.apache.thrift.protocol.TField("request", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new execute_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new execute_argsTupleSchemeFactory();
+
+    public @org.apache.thrift.annotation.Nullable ConnectionHandle handle; // required
+    public @org.apache.thrift.annotation.Nullable Request request; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      HANDLE((short)1, "handle"),
+      REQUEST((short)2, "request");
+
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
+
+      static {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      @org.apache.thrift.annotation.Nullable
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // HANDLE
+            return HANDLE;
+          case 2: // REQUEST
+            return REQUEST;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      @org.apache.thrift.annotation.Nullable
+      public static _Fields findByName(java.lang.String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final java.lang.String _fieldName;
+
+      _Fields(short thriftId, java.lang.String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public java.lang.String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.HANDLE, new org.apache.thrift.meta_data.FieldMetaData("handle", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ConnectionHandle.class)));
+      tmpMap.put(_Fields.REQUEST, new org.apache.thrift.meta_data.FieldMetaData("request", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, Request.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(execute_args.class, metaDataMap);
+    }
+
+    public execute_args() {
+    }
+
+    public execute_args(
+      ConnectionHandle handle,
+      Request request)
+    {
+      this();
+      this.handle = handle;
+      this.request = request;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public execute_args(execute_args other) {
+      if (other.isSetHandle()) {
+        this.handle = new ConnectionHandle(other.handle);
+      }
+      if (other.isSetRequest()) {
+        this.request = new Request(other.request);
+      }
+    }
+
+    public execute_args deepCopy() {
+      return new execute_args(this);
+    }
+
+    @Override
+    public void clear() {
+      this.handle = null;
+      this.request = null;
+    }
+
+    @org.apache.thrift.annotation.Nullable
+    public ConnectionHandle getHandle() {
+      return this.handle;
+    }
+
+    public execute_args setHandle(@org.apache.thrift.annotation.Nullable ConnectionHandle handle) {
+      this.handle = handle;
+      return this;
+    }
+
+    public void unsetHandle() {
+      this.handle = null;
+    }
+
+    /** Returns true if field handle is set (has been assigned a value) and false otherwise */
+    public boolean isSetHandle() {
+      return this.handle != null;
+    }
+
+    public void setHandleIsSet(boolean value) {
+      if (!value) {
+        this.handle = null;
+      }
+    }
+
+    @org.apache.thrift.annotation.Nullable
+    public Request getRequest() {
+      return this.request;
+    }
+
+    public execute_args setRequest(@org.apache.thrift.annotation.Nullable Request request) {
+      this.request = request;
+      return this;
+    }
+
+    public void unsetRequest() {
+      this.request = null;
+    }
+
+    /** Returns true if field request is set (has been assigned a value) and false otherwise */
+    public boolean isSetRequest() {
+      return this.request != null;
+    }
+
+    public void setRequestIsSet(boolean value) {
+      if (!value) {
+        this.request = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) {
+      switch (field) {
+      case HANDLE:
+        if (value == null) {
+          unsetHandle();
+        } else {
+          setHandle((ConnectionHandle)value);
+        }
+        break;
+
+      case REQUEST:
+        if (value == null) {
+          unsetRequest();
+        } else {
+          setRequest((Request)value);
+        }
+        break;
+
+      }
+    }
+
+    @org.apache.thrift.annotation.Nullable
+    public java.lang.Object getFieldValue(_Fields field) {
+      switch (field) {
+      case HANDLE:
+        return getHandle();
+
+      case REQUEST:
+        return getRequest();
+
+      }
+      throw new java.lang.IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new java.lang.IllegalArgumentException();
+      }
+
+      switch (field) {
+      case HANDLE:
+        return isSetHandle();
+      case REQUEST:
+        return isSetRequest();
+      }
+      throw new java.lang.IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(java.lang.Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof execute_args)
+        return this.equals((execute_args)that);
+      return false;
+    }
+
+    public boolean equals(execute_args that) {
+      if (that == null)
+        return false;
+      if (this == that)
+        return true;
+
+      boolean this_present_handle = true && this.isSetHandle();
+      boolean that_present_handle = true && that.isSetHandle();
+      if (this_present_handle || that_present_handle) {
+        if (!(this_present_handle && that_present_handle))
+          return false;
+        if (!this.handle.equals(that.handle))
+          return false;
+      }
+
+      boolean this_present_request = true && this.isSetRequest();
+      boolean that_present_request = true && that.isSetRequest();
+      if (this_present_request || that_present_request) {
+        if (!(this_present_request && that_present_request))
+          return false;
+        if (!this.request.equals(that.request))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      int hashCode = 1;
+
+      hashCode = hashCode * 8191 + ((isSetHandle()) ? 131071 : 524287);
+      if (isSetHandle())
+        hashCode = hashCode * 8191 + handle.hashCode();
+
+      hashCode = hashCode * 8191 + ((isSetRequest()) ? 131071 : 524287);
+      if (isSetRequest())
+        hashCode = hashCode * 8191 + request.hashCode();
+
+      return hashCode;
+    }
+
+    @Override
+    public int compareTo(execute_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = java.lang.Boolean.valueOf(isSetHandle()).compareTo(other.isSetHandle());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetHandle()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.handle, other.handle);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = java.lang.Boolean.valueOf(isSetRequest()).compareTo(other.isSetRequest());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetRequest()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.request, other.request);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    @org.apache.thrift.annotation.Nullable
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      scheme(iprot).read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      scheme(oprot).write(oprot, this);
+    }
+
+    @Override
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("execute_args(");
+      boolean first = true;
+
+      sb.append("handle:");
+      if (this.handle == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.handle);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("request:");
+      if (this.request == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.request);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+      if (handle != null) {
+        handle.validate();
+      }
+      if (request != null) {
+        request.validate();
+      }
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class execute_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public execute_argsStandardScheme getScheme() {
+        return new execute_argsStandardScheme();
+      }
+    }
+
+    private static class execute_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<execute_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, execute_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // HANDLE
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.handle = new ConnectionHandle();
+                struct.handle.read(iprot);
+                struct.setHandleIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // REQUEST
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.request = new Request();
+                struct.request.read(iprot);
+                struct.setRequestIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, execute_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.handle != null) {
+          oprot.writeFieldBegin(HANDLE_FIELD_DESC);
+          struct.handle.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.request != null) {
+          oprot.writeFieldBegin(REQUEST_FIELD_DESC);
+          struct.request.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class execute_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public execute_argsTupleScheme getScheme() {
+        return new execute_argsTupleScheme();
+      }
+    }
+
+    private static class execute_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<execute_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, execute_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
+        if (struct.isSetHandle()) {
+          optionals.set(0);
+        }
+        if (struct.isSetRequest()) {
+          optionals.set(1);
+        }
+        oprot.writeBitSet(optionals, 2);
+        if (struct.isSetHandle()) {
+          struct.handle.write(oprot);
+        }
+        if (struct.isSetRequest()) {
+          struct.request.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, execute_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
+        if (incoming.get(0)) {
+          struct.handle = new ConnectionHandle();
+          struct.handle.read(iprot);
+          struct.setHandleIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.request = new Request();
+          struct.request.read(iprot);
+          struct.setRequestIsSet(true);
+        }
+      }
+    }
+
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
+  }
+
+  public static class execute_result implements org.apache.thrift.TBase<execute_result, execute_result._Fields>, java.io.Serializable, Cloneable, Comparable<execute_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("execute_result");
+
+    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRUCT, (short)0);
+    private static final org.apache.thrift.protocol.TField EXECUTION_EXCEPTION_FIELD_DESC = new org.apache.thrift.protocol.TField("executionException", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new execute_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new execute_resultTupleSchemeFactory();
+
+    public @org.apache.thrift.annotation.Nullable Response success; // required
+    public @org.apache.thrift.annotation.Nullable PlcException executionException; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      SUCCESS((short)0, "success"),
+      EXECUTION_EXCEPTION((short)1, "executionException");
+
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
+
+      static {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      @org.apache.thrift.annotation.Nullable
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 0: // SUCCESS
+            return SUCCESS;
+          case 1: // EXECUTION_EXCEPTION
+            return EXECUTION_EXCEPTION;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      @org.apache.thrift.annotation.Nullable
+      public static _Fields findByName(java.lang.String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final java.lang.String _fieldName;
+
+      _Fields(short thriftId, java.lang.String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public java.lang.String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, Response.class)));
+      tmpMap.put(_Fields.EXECUTION_EXCEPTION, new org.apache.thrift.meta_data.FieldMetaData("executionException", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, PlcException.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(execute_result.class, metaDataMap);
+    }
+
+    public execute_result() {
+    }
+
+    public execute_result(
+      Response success,
+      PlcException executionException)
+    {
+      this();
+      this.success = success;
+      this.executionException = executionException;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public execute_result(execute_result other) {
+      if (other.isSetSuccess()) {
+        this.success = new Response(other.success);
+      }
+      if (other.isSetExecutionException()) {
+        this.executionException = new PlcException(other.executionException);
+      }
+    }
+
+    public execute_result deepCopy() {
+      return new execute_result(this);
+    }
+
+    @Override
+    public void clear() {
+      this.success = null;
+      this.executionException = null;
+    }
+
+    @org.apache.thrift.annotation.Nullable
+    public Response getSuccess() {
+      return this.success;
+    }
+
+    public execute_result setSuccess(@org.apache.thrift.annotation.Nullable Response success) {
+      this.success = success;
+      return this;
+    }
+
+    public void unsetSuccess() {
+      this.success = null;
+    }
+
+    /** Returns true if field success is set (has been assigned a value) and false otherwise */
+    public boolean isSetSuccess() {
+      return this.success != null;
+    }
+
+    public void setSuccessIsSet(boolean value) {
+      if (!value) {
+        this.success = null;
+      }
+    }
+
+    @org.apache.thrift.annotation.Nullable
+    public PlcException getExecutionException() {
+      return this.executionException;
+    }
+
+    public execute_result setExecutionException(@org.apache.thrift.annotation.Nullable PlcException executionException) {
+      this.executionException = executionException;
+      return this;
+    }
+
+    public void unsetExecutionException() {
+      this.executionException = null;
+    }
+
+    /** Returns true if field executionException is set (has been assigned a value) and false otherwise */
+    public boolean isSetExecutionException() {
+      return this.executionException != null;
+    }
+
+    public void setExecutionExceptionIsSet(boolean value) {
+      if (!value) {
+        this.executionException = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((Response)value);
+        }
+        break;
+
+      case EXECUTION_EXCEPTION:
+        if (value == null) {
+          unsetExecutionException();
+        } else {
+          setExecutionException((PlcException)value);
+        }
+        break;
+
+      }
+    }
+
+    @org.apache.thrift.annotation.Nullable
+    public java.lang.Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      case EXECUTION_EXCEPTION:
+        return getExecutionException();
+
+      }
+      throw new java.lang.IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new java.lang.IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case EXECUTION_EXCEPTION:
+        return isSetExecutionException();
+      }
+      throw new java.lang.IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(java.lang.Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof execute_result)
+        return this.equals((execute_result)that);
+      return false;
+    }
+
+    public boolean equals(execute_result that) {
+      if (that == null)
+        return false;
+      if (this == that)
+        return true;
+
+      boolean this_present_success = true && this.isSetSuccess();
+      boolean that_present_success = true && that.isSetSuccess();
+      if (this_present_success || that_present_success) {
+        if (!(this_present_success && that_present_success))
+          return false;
+        if (!this.success.equals(that.success))
+          return false;
+      }
+
+      boolean this_present_executionException = true && this.isSetExecutionException();
+      boolean that_present_executionException = true && that.isSetExecutionException();
+      if (this_present_executionException || that_present_executionException) {
+        if (!(this_present_executionException && that_present_executionException))
+          return false;
+        if (!this.executionException.equals(that.executionException))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      int hashCode = 1;
+
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.hashCode();
+
+      hashCode = hashCode * 8191 + ((isSetExecutionException()) ? 131071 : 524287);
+      if (isSetExecutionException())
+        hashCode = hashCode * 8191 + executionException.hashCode();
+
+      return hashCode;
+    }
+
+    @Override
+    public int compareTo(execute_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetSuccess()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = java.lang.Boolean.valueOf(isSetExecutionException()).compareTo(other.isSetExecutionException());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetExecutionException()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.executionException, other.executionException);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    @org.apache.thrift.annotation.Nullable
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      scheme(iprot).read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      scheme(oprot).write(oprot, this);
+      }
+
+    @Override
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("execute_result(");
+      boolean first = true;
+
+      sb.append("success:");
+      if (this.success == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.success);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("executionException:");
+      if (this.executionException == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.executionException);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+      if (success != null) {
+        success.validate();
+      }
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class execute_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public execute_resultStandardScheme getScheme() {
+        return new execute_resultStandardScheme();
+      }
+    }
+
+    private static class execute_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<execute_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, execute_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 0: // SUCCESS
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.success = new Response();
+                struct.success.read(iprot);
+                struct.setSuccessIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 1: // EXECUTION_EXCEPTION
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.executionException = new PlcException();
+                struct.executionException.read(iprot);
+                struct.setExecutionExceptionIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, execute_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.success != null) {
+          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
+          struct.success.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.executionException != null) {
+          oprot.writeFieldBegin(EXECUTION_EXCEPTION_FIELD_DESC);
+          struct.executionException.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class execute_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public execute_resultTupleScheme getScheme() {
+        return new execute_resultTupleScheme();
+      }
+    }
+
+    private static class execute_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<execute_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, execute_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
+        if (struct.isSetSuccess()) {
+          optionals.set(0);
+        }
+        if (struct.isSetExecutionException()) {
+          optionals.set(1);
+        }
+        oprot.writeBitSet(optionals, 2);
+        if (struct.isSetSuccess()) {
+          struct.success.write(oprot);
+        }
+        if (struct.isSetExecutionException()) {
+          struct.executionException.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, execute_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
+        if (incoming.get(0)) {
+          struct.success = new Response();
+          struct.success.read(iprot);
+          struct.setSuccessIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.executionException = new PlcException();
+          struct.executionException.read(iprot);
+          struct.setExecutionExceptionIsSet(true);
+        }
+      }
+    }
+
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
+  }
+
+  public static class close_args implements org.apache.thrift.TBase<close_args, close_args._Fields>, java.io.Serializable, Cloneable, Comparable<close_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("close_args");
+
+    private static final org.apache.thrift.protocol.TField HANDLE_FIELD_DESC = new org.apache.thrift.protocol.TField("handle", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new close_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new close_argsTupleSchemeFactory();
+
+    public @org.apache.thrift.annotation.Nullable ConnectionHandle handle; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      HANDLE((short)1, "handle");
+
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
+
+      static {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      @org.apache.thrift.annotation.Nullable
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // HANDLE
+            return HANDLE;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      @org.apache.thrift.annotation.Nullable
+      public static _Fields findByName(java.lang.String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final java.lang.String _fieldName;
+
+      _Fields(short thriftId, java.lang.String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public java.lang.String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.HANDLE, new org.apache.thrift.meta_data.FieldMetaData("handle", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ConnectionHandle.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(close_args.class, metaDataMap);
+    }
+
+    public close_args() {
+    }
+
+    public close_args(
+      ConnectionHandle handle)
+    {
+      this();
+      this.handle = handle;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public close_args(close_args other) {
+      if (other.isSetHandle()) {
+        this.handle = new ConnectionHandle(other.handle);
+      }
+    }
+
+    public close_args deepCopy() {
+      return new close_args(this);
+    }
+
+    @Override
+    public void clear() {
+      this.handle = null;
+    }
+
+    @org.apache.thrift.annotation.Nullable
+    public ConnectionHandle getHandle() {
+      return this.handle;
+    }
+
+    public close_args setHandle(@org.apache.thrift.annotation.Nullable ConnectionHandle handle) {
+      this.handle = handle;
+      return this;
+    }
+
+    public void unsetHandle() {
+      this.handle = null;
+    }
+
+    /** Returns true if field handle is set (has been assigned a value) and false otherwise */
+    public boolean isSetHandle() {
+      return this.handle != null;
+    }
+
+    public void setHandleIsSet(boolean value) {
+      if (!value) {
+        this.handle = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) {
+      switch (field) {
+      case HANDLE:
+        if (value == null) {
+          unsetHandle();
+        } else {
+          setHandle((ConnectionHandle)value);
+        }
+        break;
+
+      }
+    }
+
+    @org.apache.thrift.annotation.Nullable
+    public java.lang.Object getFieldValue(_Fields field) {
+      switch (field) {
+      case HANDLE:
+        return getHandle();
+
+      }
+      throw new java.lang.IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new java.lang.IllegalArgumentException();
+      }
+
+      switch (field) {
+      case HANDLE:
+        return isSetHandle();
+      }
+      throw new java.lang.IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(java.lang.Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof close_args)
+        return this.equals((close_args)that);
+      return false;
+    }
+
+    public boolean equals(close_args that) {
+      if (that == null)
+        return false;
+      if (this == that)
+        return true;
+
+      boolean this_present_handle = true && this.isSetHandle();
+      boolean that_present_handle = true && that.isSetHandle();
+      if (this_present_handle || that_present_handle) {
+        if (!(this_present_handle && that_present_handle))
+          return false;
+        if (!this.handle.equals(that.handle))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      int hashCode = 1;
+
+      hashCode = hashCode * 8191 + ((isSetHandle()) ? 131071 : 524287);
+      if (isSetHandle())
+        hashCode = hashCode * 8191 + handle.hashCode();
+
+      return hashCode;
+    }
+
+    @Override
+    public int compareTo(close_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = java.lang.Boolean.valueOf(isSetHandle()).compareTo(other.isSetHandle());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetHandle()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.handle, other.handle);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    @org.apache.thrift.annotation.Nullable
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      scheme(iprot).read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      scheme(oprot).write(oprot, this);
+    }
+
+    @Override
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("close_args(");
+      boolean first = true;
+
+      sb.append("handle:");
+      if (this.handle == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.handle);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+      if (handle != null) {
+        handle.validate();
+      }
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class close_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public close_argsStandardScheme getScheme() {
+        return new close_argsStandardScheme();
+      }
+    }
+
+    private static class close_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<close_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, close_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // HANDLE
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.handle = new ConnectionHandle();
+                struct.handle.read(iprot);
+                struct.setHandleIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, close_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.handle != null) {
+          oprot.writeFieldBegin(HANDLE_FIELD_DESC);
+          struct.handle.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class close_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public close_argsTupleScheme getScheme() {
+        return new close_argsTupleScheme();
+      }
+    }
+
+    private static class close_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<close_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, close_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
+        if (struct.isSetHandle()) {
+          optionals.set(0);
+        }
+        oprot.writeBitSet(optionals, 1);
+        if (struct.isSetHandle()) {
+          struct.handle.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, close_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(1);
+        if (incoming.get(0)) {
+          struct.handle = new ConnectionHandle();
+          struct.handle.read(iprot);
+          struct.setHandleIsSet(true);
+        }
+      }
+    }
+
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
+  }
+
+  public static class close_result implements org.apache.thrift.TBase<close_result, close_result._Fields>, java.io.Serializable, Cloneable, Comparable<close_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("close_result");
+
+
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new close_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new close_resultTupleSchemeFactory();
+
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+;
+
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
+
+      static {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      @org.apache.thrift.annotation.Nullable
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      @org.apache.thrift.annotation.Nullable
+      public static _Fields findByName(java.lang.String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final java.lang.String _fieldName;
+
+      _Fields(short thriftId, java.lang.String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public java.lang.String getFieldName() {
+        return _fieldName;
+      }
+    }
+    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(close_result.class, metaDataMap);
+    }
+
+    public close_result() {
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public close_result(close_result other) {
+    }
+
+    public close_result deepCopy() {
+      return new close_result(this);
+    }
+
+    @Override
+    public void clear() {
+    }
+
+    public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) {
+      switch (field) {
+      }
+    }
+
+    @org.apache.thrift.annotation.Nullable
+    public java.lang.Object getFieldValue(_Fields field) {
+      switch (field) {
+      }
+      throw new java.lang.IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new java.lang.IllegalArgumentException();
+      }
+
+      switch (field) {
+      }
+      throw new java.lang.IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(java.lang.Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof close_result)
+        return this.equals((close_result)that);
+      return false;
+    }
+
+    public boolean equals(close_result that) {
+      if (that == null)
+        return false;
+      if (this == that)
+        return true;
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      int hashCode = 1;
+
+      return hashCode;
+    }
+
+    @Override
+    public int compareTo(close_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      return 0;
+    }
+
+    @org.apache.thrift.annotation.Nullable
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      scheme(iprot).read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      scheme(oprot).write(oprot, this);
+      }
+
+    @Override
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("close_result(");
+      boolean first = true;
+
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class close_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public close_resultStandardScheme getScheme() {
+        return new close_resultStandardScheme();
+      }
+    }
+
+    private static class close_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<close_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, close_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, close_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class close_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public close_resultTupleScheme getScheme() {
+        return new close_resultTupleScheme();
+      }
+    }
+
+    private static class close_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<close_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, close_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, close_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      }
+    }
+
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
+  }
+
+}
diff --git a/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/PlcException.java b/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/PlcException.java
new file mode 100644
index 0000000..521235a
--- /dev/null
+++ b/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/PlcException.java
@@ -0,0 +1,482 @@
+/**
+ * Autogenerated by Thrift Compiler (0.12.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+package org.apache.plc4x.interop;
+
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.12.0)", date = "2019-04-14")
+public class PlcException extends org.apache.thrift.TException implements org.apache.thrift.TBase<PlcException, PlcException._Fields>, java.io.Serializable, Cloneable, Comparable<PlcException> {
+  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("PlcException");
+
+  private static final org.apache.thrift.protocol.TField URL_FIELD_DESC = new org.apache.thrift.protocol.TField("url", org.apache.thrift.protocol.TType.STRING, (short)1);
+  private static final org.apache.thrift.protocol.TField EXCEPTION_STRING_FIELD_DESC = new org.apache.thrift.protocol.TField("exceptionString", org.apache.thrift.protocol.TType.STRING, (short)2);
+
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new PlcExceptionStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new PlcExceptionTupleSchemeFactory();
+
+  public @org.apache.thrift.annotation.Nullable java.lang.String url; // required
+  public @org.apache.thrift.annotation.Nullable java.lang.String exceptionString; // required
+
+  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+    URL((short)1, "url"),
+    EXCEPTION_STRING((short)2, "exceptionString");
+
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
+
+    static {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
+        byName.put(field.getFieldName(), field);
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, or null if its not found.
+     */
+    @org.apache.thrift.annotation.Nullable
+    public static _Fields findByThriftId(int fieldId) {
+      switch(fieldId) {
+        case 1: // URL
+          return URL;
+        case 2: // EXCEPTION_STRING
+          return EXCEPTION_STRING;
+        default:
+          return null;
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, throwing an exception
+     * if it is not found.
+     */
+    public static _Fields findByThriftIdOrThrow(int fieldId) {
+      _Fields fields = findByThriftId(fieldId);
+      if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      return fields;
+    }
+
+    /**
+     * Find the _Fields constant that matches name, or null if its not found.
+     */
+    @org.apache.thrift.annotation.Nullable
+    public static _Fields findByName(java.lang.String name) {
+      return byName.get(name);
+    }
+
+    private final short _thriftId;
+    private final java.lang.String _fieldName;
+
+    _Fields(short thriftId, java.lang.String fieldName) {
+      _thriftId = thriftId;
+      _fieldName = fieldName;
+    }
+
+    public short getThriftFieldId() {
+      return _thriftId;
+    }
+
+    public java.lang.String getFieldName() {
+      return _fieldName;
+    }
+  }
+
+  // isset id assignments
+  public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  static {
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+    tmpMap.put(_Fields.URL, new org.apache.thrift.meta_data.FieldMetaData("url", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+    tmpMap.put(_Fields.EXCEPTION_STRING, new org.apache.thrift.meta_data.FieldMetaData("exceptionString", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(PlcException.class, metaDataMap);
+  }
+
+  public PlcException() {
+  }
+
+  public PlcException(
+    java.lang.String url,
+    java.lang.String exceptionString)
+  {
+    this();
+    this.url = url;
+    this.exceptionString = exceptionString;
+  }
+
+  /**
+   * Performs a deep copy on <i>other</i>.
+   */
+  public PlcException(PlcException other) {
+    if (other.isSetUrl()) {
+      this.url = other.url;
+    }
+    if (other.isSetExceptionString()) {
+      this.exceptionString = other.exceptionString;
+    }
+  }
+
+  public PlcException deepCopy() {
+    return new PlcException(this);
+  }
+
+  @Override
+  public void clear() {
+    this.url = null;
+    this.exceptionString = null;
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public java.lang.String getUrl() {
+    return this.url;
+  }
+
+  public PlcException setUrl(@org.apache.thrift.annotation.Nullable java.lang.String url) {
+    this.url = url;
+    return this;
+  }
+
+  public void unsetUrl() {
+    this.url = null;
+  }
+
+  /** Returns true if field url is set (has been assigned a value) and false otherwise */
+  public boolean isSetUrl() {
+    return this.url != null;
+  }
+
+  public void setUrlIsSet(boolean value) {
+    if (!value) {
+      this.url = null;
+    }
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public java.lang.String getExceptionString() {
+    return this.exceptionString;
+  }
+
+  public PlcException setExceptionString(@org.apache.thrift.annotation.Nullable java.lang.String exceptionString) {
+    this.exceptionString = exceptionString;
+    return this;
+  }
+
+  public void unsetExceptionString() {
+    this.exceptionString = null;
+  }
+
+  /** Returns true if field exceptionString is set (has been assigned a value) and false otherwise */
+  public boolean isSetExceptionString() {
+    return this.exceptionString != null;
+  }
+
+  public void setExceptionStringIsSet(boolean value) {
+    if (!value) {
+      this.exceptionString = null;
+    }
+  }
+
+  public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) {
+    switch (field) {
+    case URL:
+      if (value == null) {
+        unsetUrl();
+      } else {
+        setUrl((java.lang.String)value);
+      }
+      break;
+
+    case EXCEPTION_STRING:
+      if (value == null) {
+        unsetExceptionString();
+      } else {
+        setExceptionString((java.lang.String)value);
+      }
+      break;
+
+    }
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public java.lang.Object getFieldValue(_Fields field) {
+    switch (field) {
+    case URL:
+      return getUrl();
+
+    case EXCEPTION_STRING:
+      return getExceptionString();
+
+    }
+    throw new java.lang.IllegalStateException();
+  }
+
+  /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+  public boolean isSet(_Fields field) {
+    if (field == null) {
+      throw new java.lang.IllegalArgumentException();
+    }
+
+    switch (field) {
+    case URL:
+      return isSetUrl();
+    case EXCEPTION_STRING:
+      return isSetExceptionString();
+    }
+    throw new java.lang.IllegalStateException();
+  }
+
+  @Override
+  public boolean equals(java.lang.Object that) {
+    if (that == null)
+      return false;
+    if (that instanceof PlcException)
+      return this.equals((PlcException)that);
+    return false;
+  }
+
+  public boolean equals(PlcException that) {
+    if (that == null)
+      return false;
+    if (this == that)
+      return true;
+
+    boolean this_present_url = true && this.isSetUrl();
+    boolean that_present_url = true && that.isSetUrl();
+    if (this_present_url || that_present_url) {
+      if (!(this_present_url && that_present_url))
+        return false;
+      if (!this.url.equals(that.url))
+        return false;
+    }
+
+    boolean this_present_exceptionString = true && this.isSetExceptionString();
+    boolean that_present_exceptionString = true && that.isSetExceptionString();
+    if (this_present_exceptionString || that_present_exceptionString) {
+      if (!(this_present_exceptionString && that_present_exceptionString))
+        return false;
+      if (!this.exceptionString.equals(that.exceptionString))
+        return false;
+    }
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int hashCode = 1;
+
+    hashCode = hashCode * 8191 + ((isSetUrl()) ? 131071 : 524287);
+    if (isSetUrl())
+      hashCode = hashCode * 8191 + url.hashCode();
+
+    hashCode = hashCode * 8191 + ((isSetExceptionString()) ? 131071 : 524287);
+    if (isSetExceptionString())
+      hashCode = hashCode * 8191 + exceptionString.hashCode();
+
+    return hashCode;
+  }
+
+  @Override
+  public int compareTo(PlcException other) {
+    if (!getClass().equals(other.getClass())) {
+      return getClass().getName().compareTo(other.getClass().getName());
+    }
+
+    int lastComparison = 0;
+
+    lastComparison = java.lang.Boolean.valueOf(isSetUrl()).compareTo(other.isSetUrl());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetUrl()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.url, other.url);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    lastComparison = java.lang.Boolean.valueOf(isSetExceptionString()).compareTo(other.isSetExceptionString());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetExceptionString()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.exceptionString, other.exceptionString);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    return 0;
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public _Fields fieldForId(int fieldId) {
+    return _Fields.findByThriftId(fieldId);
+  }
+
+  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+    scheme(iprot).read(iprot, this);
+  }
+
+  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+    scheme(oprot).write(oprot, this);
+  }
+
+  @Override
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("PlcException(");
+    boolean first = true;
+
+    sb.append("url:");
+    if (this.url == null) {
+      sb.append("null");
+    } else {
+      sb.append(this.url);
+    }
+    first = false;
+    if (!first) sb.append(", ");
+    sb.append("exceptionString:");
+    if (this.exceptionString == null) {
+      sb.append("null");
+    } else {
+      sb.append(this.exceptionString);
+    }
+    first = false;
+    sb.append(")");
+    return sb.toString();
+  }
+
+  public void validate() throws org.apache.thrift.TException {
+    // check for required fields
+    // check for sub-struct validity
+  }
+
+  private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+    try {
+      write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
+    try {
+      read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private static class PlcExceptionStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+    public PlcExceptionStandardScheme getScheme() {
+      return new PlcExceptionStandardScheme();
+    }
+  }
+
+  private static class PlcExceptionStandardScheme extends org.apache.thrift.scheme.StandardScheme<PlcException> {
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot, PlcException struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TField schemeField;
+      iprot.readStructBegin();
+      while (true)
+      {
+        schemeField = iprot.readFieldBegin();
+        if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+          break;
+        }
+        switch (schemeField.id) {
+          case 1: // URL
+            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+              struct.url = iprot.readString();
+              struct.setUrlIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          case 2: // EXCEPTION_STRING
+            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+              struct.exceptionString = iprot.readString();
+              struct.setExceptionStringIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          default:
+            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+        }
+        iprot.readFieldEnd();
+      }
+      iprot.readStructEnd();
+
+      // check for required fields of primitive type, which can't be checked in the validate method
+      struct.validate();
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot, PlcException struct) throws org.apache.thrift.TException {
+      struct.validate();
+
+      oprot.writeStructBegin(STRUCT_DESC);
+      if (struct.url != null) {
+        oprot.writeFieldBegin(URL_FIELD_DESC);
+        oprot.writeString(struct.url);
+        oprot.writeFieldEnd();
+      }
+      if (struct.exceptionString != null) {
+        oprot.writeFieldBegin(EXCEPTION_STRING_FIELD_DESC);
+        oprot.writeString(struct.exceptionString);
+        oprot.writeFieldEnd();
+      }
+      oprot.writeFieldStop();
+      oprot.writeStructEnd();
+    }
+
+  }
+
+  private static class PlcExceptionTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+    public PlcExceptionTupleScheme getScheme() {
+      return new PlcExceptionTupleScheme();
+    }
+  }
+
+  private static class PlcExceptionTupleScheme extends org.apache.thrift.scheme.TupleScheme<PlcException> {
+
+    @Override
+    public void write(org.apache.thrift.protocol.TProtocol prot, PlcException struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
+      if (struct.isSetUrl()) {
+        optionals.set(0);
+      }
+      if (struct.isSetExceptionString()) {
+        optionals.set(1);
+      }
+      oprot.writeBitSet(optionals, 2);
+      if (struct.isSetUrl()) {
+        oprot.writeString(struct.url);
+      }
+      if (struct.isSetExceptionString()) {
+        oprot.writeString(struct.exceptionString);
+      }
+    }
+
+    @Override
+    public void read(org.apache.thrift.protocol.TProtocol prot, PlcException struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(2);
+      if (incoming.get(0)) {
+        struct.url = iprot.readString();
+        struct.setUrlIsSet(true);
+      }
+      if (incoming.get(1)) {
+        struct.exceptionString = iprot.readString();
+        struct.setExceptionStringIsSet(true);
+      }
+    }
+  }
+
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+}
+
diff --git a/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/RESPONSE_CODE.java b/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/RESPONSE_CODE.java
new file mode 100644
index 0000000..09756c3
--- /dev/null
+++ b/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/RESPONSE_CODE.java
@@ -0,0 +1,58 @@
+/**
+ * Autogenerated by Thrift Compiler (0.12.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+package org.apache.plc4x.interop;
+
+
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.12.0)", date = "2019-04-14")
+public enum RESPONSE_CODE implements org.apache.thrift.TEnum {
+  OK(1),
+  NOT_FOUND(2),
+  ACCESS_DENIED(3),
+  INVALID_ADDRESS(4),
+  INVALID_DATATYPE(5),
+  INTERNAL_ERROR(6),
+  RESPONSE_PENDING(7);
+
+  private final int value;
+
+  private RESPONSE_CODE(int value) {
+    this.value = value;
+  }
+
+  /**
+   * Get the integer value of this enum value, as defined in the Thrift IDL.
+   */
+  public int getValue() {
+    return value;
+  }
+
+  /**
+   * Find a the enum type by its integer value, as defined in the Thrift IDL.
+   * @return null if the value is not found.
+   */
+  @org.apache.thrift.annotation.Nullable
+  public static RESPONSE_CODE findByValue(int value) { 
+    switch (value) {
+      case 1:
+        return OK;
+      case 2:
+        return NOT_FOUND;
+      case 3:
+        return ACCESS_DENIED;
+      case 4:
+        return INVALID_ADDRESS;
+      case 5:
+        return INVALID_DATATYPE;
+      case 6:
+        return INTERNAL_ERROR;
+      case 7:
+        return RESPONSE_PENDING;
+      default:
+        return null;
+    }
+  }
+}
diff --git a/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/Request.java b/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/Request.java
new file mode 100644
index 0000000..13b48d7
--- /dev/null
+++ b/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/Request.java
@@ -0,0 +1,429 @@
+/**
+ * Autogenerated by Thrift Compiler (0.12.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+package org.apache.plc4x.interop;
+
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.12.0)", date = "2019-04-14")
+public class Request implements org.apache.thrift.TBase<Request, Request._Fields>, java.io.Serializable, Cloneable, Comparable<Request> {
+  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("Request");
+
+  private static final org.apache.thrift.protocol.TField FIELDS_FIELD_DESC = new org.apache.thrift.protocol.TField("fields", org.apache.thrift.protocol.TType.MAP, (short)1);
+
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new RequestStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new RequestTupleSchemeFactory();
+
+  public @org.apache.thrift.annotation.Nullable java.util.Map<java.lang.String,java.lang.String> fields; // required
+
+  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+    FIELDS((short)1, "fields");
+
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
+
+    static {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
+        byName.put(field.getFieldName(), field);
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, or null if its not found.
+     */
+    @org.apache.thrift.annotation.Nullable
+    public static _Fields findByThriftId(int fieldId) {
+      switch(fieldId) {
+        case 1: // FIELDS
+          return FIELDS;
+        default:
+          return null;
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, throwing an exception
+     * if it is not found.
+     */
+    public static _Fields findByThriftIdOrThrow(int fieldId) {
+      _Fields fields = findByThriftId(fieldId);
+      if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      return fields;
+    }
+
+    /**
+     * Find the _Fields constant that matches name, or null if its not found.
+     */
+    @org.apache.thrift.annotation.Nullable
+    public static _Fields findByName(java.lang.String name) {
+      return byName.get(name);
+    }
+
+    private final short _thriftId;
+    private final java.lang.String _fieldName;
+
+    _Fields(short thriftId, java.lang.String fieldName) {
+      _thriftId = thriftId;
+      _fieldName = fieldName;
+    }
+
+    public short getThriftFieldId() {
+      return _thriftId;
+    }
+
+    public java.lang.String getFieldName() {
+      return _fieldName;
+    }
+  }
+
+  // isset id assignments
+  public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  static {
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+    tmpMap.put(_Fields.FIELDS, new org.apache.thrift.meta_data.FieldMetaData("fields", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+        new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
+            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING), 
+            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))));
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(Request.class, metaDataMap);
+  }
+
+  public Request() {
+  }
+
+  public Request(
+    java.util.Map<java.lang.String,java.lang.String> fields)
+  {
+    this();
+    this.fields = fields;
+  }
+
+  /**
+   * Performs a deep copy on <i>other</i>.
+   */
+  public Request(Request other) {
+    if (other.isSetFields()) {
+      java.util.Map<java.lang.String,java.lang.String> __this__fields = new java.util.HashMap<java.lang.String,java.lang.String>(other.fields);
+      this.fields = __this__fields;
+    }
+  }
+
+  public Request deepCopy() {
+    return new Request(this);
+  }
+
+  @Override
+  public void clear() {
+    this.fields = null;
+  }
+
+  public int getFieldsSize() {
+    return (this.fields == null) ? 0 : this.fields.size();
+  }
+
+  public void putToFields(java.lang.String key, java.lang.String val) {
+    if (this.fields == null) {
+      this.fields = new java.util.HashMap<java.lang.String,java.lang.String>();
+    }
+    this.fields.put(key, val);
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public java.util.Map<java.lang.String,java.lang.String> getFields() {
+    return this.fields;
+  }
+
+  public Request setFields(@org.apache.thrift.annotation.Nullable java.util.Map<java.lang.String,java.lang.String> fields) {
+    this.fields = fields;
+    return this;
+  }
+
+  public void unsetFields() {
+    this.fields = null;
+  }
+
+  /** Returns true if field fields is set (has been assigned a value) and false otherwise */
+  public boolean isSetFields() {
+    return this.fields != null;
+  }
+
+  public void setFieldsIsSet(boolean value) {
+    if (!value) {
+      this.fields = null;
+    }
+  }
+
+  public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) {
+    switch (field) {
+    case FIELDS:
+      if (value == null) {
+        unsetFields();
+      } else {
+        setFields((java.util.Map<java.lang.String,java.lang.String>)value);
+      }
+      break;
+
+    }
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public java.lang.Object getFieldValue(_Fields field) {
+    switch (field) {
+    case FIELDS:
+      return getFields();
+
+    }
+    throw new java.lang.IllegalStateException();
+  }
+
+  /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+  public boolean isSet(_Fields field) {
+    if (field == null) {
+      throw new java.lang.IllegalArgumentException();
+    }
+
+    switch (field) {
+    case FIELDS:
+      return isSetFields();
+    }
+    throw new java.lang.IllegalStateException();
+  }
+
+  @Override
+  public boolean equals(java.lang.Object that) {
+    if (that == null)
+      return false;
+    if (that instanceof Request)
+      return this.equals((Request)that);
+    return false;
+  }
+
+  public boolean equals(Request that) {
+    if (that == null)
+      return false;
+    if (this == that)
+      return true;
+
+    boolean this_present_fields = true && this.isSetFields();
+    boolean that_present_fields = true && that.isSetFields();
+    if (this_present_fields || that_present_fields) {
+      if (!(this_present_fields && that_present_fields))
+        return false;
+      if (!this.fields.equals(that.fields))
+        return false;
+    }
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int hashCode = 1;
+
+    hashCode = hashCode * 8191 + ((isSetFields()) ? 131071 : 524287);
+    if (isSetFields())
+      hashCode = hashCode * 8191 + fields.hashCode();
+
+    return hashCode;
+  }
+
+  @Override
+  public int compareTo(Request other) {
+    if (!getClass().equals(other.getClass())) {
+      return getClass().getName().compareTo(other.getClass().getName());
+    }
+
+    int lastComparison = 0;
+
+    lastComparison = java.lang.Boolean.valueOf(isSetFields()).compareTo(other.isSetFields());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetFields()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.fields, other.fields);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    return 0;
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public _Fields fieldForId(int fieldId) {
+    return _Fields.findByThriftId(fieldId);
+  }
+
+  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+    scheme(iprot).read(iprot, this);
+  }
+
+  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+    scheme(oprot).write(oprot, this);
+  }
+
+  @Override
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("Request(");
+    boolean first = true;
+
+    sb.append("fields:");
+    if (this.fields == null) {
+      sb.append("null");
+    } else {
+      sb.append(this.fields);
+    }
+    first = false;
+    sb.append(")");
+    return sb.toString();
+  }
+
+  public void validate() throws org.apache.thrift.TException {
+    // check for required fields
+    // check for sub-struct validity
+  }
+
+  private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+    try {
+      write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
+    try {
+      read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private static class RequestStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+    public RequestStandardScheme getScheme() {
+      return new RequestStandardScheme();
+    }
+  }
+
+  private static class RequestStandardScheme extends org.apache.thrift.scheme.StandardScheme<Request> {
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot, Request struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TField schemeField;
+      iprot.readStructBegin();
+      while (true)
+      {
+        schemeField = iprot.readFieldBegin();
+        if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+          break;
+        }
+        switch (schemeField.id) {
+          case 1: // FIELDS
+            if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
+              {
+                org.apache.thrift.protocol.TMap _map0 = iprot.readMapBegin();
+                struct.fields = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map0.size);
+                @org.apache.thrift.annotation.Nullable java.lang.String _key1;
+                @org.apache.thrift.annotation.Nullable java.lang.String _val2;
+                for (int _i3 = 0; _i3 < _map0.size; ++_i3)
+                {
+                  _key1 = iprot.readString();
+                  _val2 = iprot.readString();
+                  struct.fields.put(_key1, _val2);
+                }
+                iprot.readMapEnd();
+              }
+              struct.setFieldsIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          default:
+            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+        }
+        iprot.readFieldEnd();
+      }
+      iprot.readStructEnd();
+
+      // check for required fields of primitive type, which can't be checked in the validate method
+      struct.validate();
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot, Request struct) throws org.apache.thrift.TException {
+      struct.validate();
+
+      oprot.writeStructBegin(STRUCT_DESC);
+      if (struct.fields != null) {
+        oprot.writeFieldBegin(FIELDS_FIELD_DESC);
+        {
+          oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, struct.fields.size()));
+          for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter4 : struct.fields.entrySet())
+          {
+            oprot.writeString(_iter4.getKey());
+            oprot.writeString(_iter4.getValue());
+          }
+          oprot.writeMapEnd();
+        }
+        oprot.writeFieldEnd();
+      }
+      oprot.writeFieldStop();
+      oprot.writeStructEnd();
+    }
+
+  }
+
+  private static class RequestTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+    public RequestTupleScheme getScheme() {
+      return new RequestTupleScheme();
+    }
+  }
+
+  private static class RequestTupleScheme extends org.apache.thrift.scheme.TupleScheme<Request> {
+
+    @Override
+    public void write(org.apache.thrift.protocol.TProtocol prot, Request struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
+      if (struct.isSetFields()) {
+        optionals.set(0);
+      }
+      oprot.writeBitSet(optionals, 1);
+      if (struct.isSetFields()) {
+        {
+          oprot.writeI32(struct.fields.size());
+          for (java.util.Map.Entry<java.lang.String, java.lang.String> _iter5 : struct.fields.entrySet())
+          {
+            oprot.writeString(_iter5.getKey());
+            oprot.writeString(_iter5.getValue());
+          }
+        }
+      }
+    }
+
+    @Override
+    public void read(org.apache.thrift.protocol.TProtocol prot, Request struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(1);
+      if (incoming.get(0)) {
+        {
+          org.apache.thrift.protocol.TMap _map6 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRING, iprot.readI32());
+          struct.fields = new java.util.HashMap<java.lang.String,java.lang.String>(2*_map6.size);
+          @org.apache.thrift.annotation.Nullable java.lang.String _key7;
+          @org.apache.thrift.annotation.Nullable java.lang.String _val8;
+          for (int _i9 = 0; _i9 < _map6.size; ++_i9)
+          {
+            _key7 = iprot.readString();
+            _val8 = iprot.readString();
+            struct.fields.put(_key7, _val8);
+          }
+        }
+        struct.setFieldsIsSet(true);
+      }
+    }
+  }
+
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+}
+
diff --git a/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/Response.java b/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/Response.java
new file mode 100644
index 0000000..8bdbb6e
--- /dev/null
+++ b/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/Response.java
@@ -0,0 +1,442 @@
+/**
+ * Autogenerated by Thrift Compiler (0.12.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+package org.apache.plc4x.interop;
+
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.12.0)", date = "2019-04-14")
+public class Response implements org.apache.thrift.TBase<Response, Response._Fields>, java.io.Serializable, Cloneable, Comparable<Response> {
+  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("Response");
+
+  private static final org.apache.thrift.protocol.TField FIELDS_FIELD_DESC = new org.apache.thrift.protocol.TField("fields", org.apache.thrift.protocol.TType.MAP, (short)1);
+
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new ResponseStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new ResponseTupleSchemeFactory();
+
+  public @org.apache.thrift.annotation.Nullable java.util.Map<java.lang.String,FieldResponse> fields; // required
+
+  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+    FIELDS((short)1, "fields");
+
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
+
+    static {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
+        byName.put(field.getFieldName(), field);
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, or null if its not found.
+     */
+    @org.apache.thrift.annotation.Nullable
+    public static _Fields findByThriftId(int fieldId) {
+      switch(fieldId) {
+        case 1: // FIELDS
+          return FIELDS;
+        default:
+          return null;
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, throwing an exception
+     * if it is not found.
+     */
+    public static _Fields findByThriftIdOrThrow(int fieldId) {
+      _Fields fields = findByThriftId(fieldId);
+      if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      return fields;
+    }
+
+    /**
+     * Find the _Fields constant that matches name, or null if its not found.
+     */
+    @org.apache.thrift.annotation.Nullable
+    public static _Fields findByName(java.lang.String name) {
+      return byName.get(name);
+    }
+
+    private final short _thriftId;
+    private final java.lang.String _fieldName;
+
+    _Fields(short thriftId, java.lang.String fieldName) {
+      _thriftId = thriftId;
+      _fieldName = fieldName;
+    }
+
+    public short getThriftFieldId() {
+      return _thriftId;
+    }
+
+    public java.lang.String getFieldName() {
+      return _fieldName;
+    }
+  }
+
+  // isset id assignments
+  public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  static {
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+    tmpMap.put(_Fields.FIELDS, new org.apache.thrift.meta_data.FieldMetaData("fields", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+        new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
+            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING), 
+            new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, FieldResponse.class))));
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(Response.class, metaDataMap);
+  }
+
+  public Response() {
+  }
+
+  public Response(
+    java.util.Map<java.lang.String,FieldResponse> fields)
+  {
+    this();
+    this.fields = fields;
+  }
+
+  /**
+   * Performs a deep copy on <i>other</i>.
+   */
+  public Response(Response other) {
+    if (other.isSetFields()) {
+      java.util.Map<java.lang.String,FieldResponse> __this__fields = new java.util.HashMap<java.lang.String,FieldResponse>(other.fields.size());
+      for (java.util.Map.Entry<java.lang.String, FieldResponse> other_element : other.fields.entrySet()) {
+
+        java.lang.String other_element_key = other_element.getKey();
+        FieldResponse other_element_value = other_element.getValue();
+
+        java.lang.String __this__fields_copy_key = other_element_key;
+
+        FieldResponse __this__fields_copy_value = new FieldResponse(other_element_value);
+
+        __this__fields.put(__this__fields_copy_key, __this__fields_copy_value);
+      }
+      this.fields = __this__fields;
+    }
+  }
+
+  public Response deepCopy() {
+    return new Response(this);
+  }
+
+  @Override
+  public void clear() {
+    this.fields = null;
+  }
+
+  public int getFieldsSize() {
+    return (this.fields == null) ? 0 : this.fields.size();
+  }
+
+  public void putToFields(java.lang.String key, FieldResponse val) {
+    if (this.fields == null) {
+      this.fields = new java.util.HashMap<java.lang.String,FieldResponse>();
+    }
+    this.fields.put(key, val);
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public java.util.Map<java.lang.String,FieldResponse> getFields() {
+    return this.fields;
+  }
+
+  public Response setFields(@org.apache.thrift.annotation.Nullable java.util.Map<java.lang.String,FieldResponse> fields) {
+    this.fields = fields;
+    return this;
+  }
+
+  public void unsetFields() {
+    this.fields = null;
+  }
+
+  /** Returns true if field fields is set (has been assigned a value) and false otherwise */
+  public boolean isSetFields() {
+    return this.fields != null;
+  }
+
+  public void setFieldsIsSet(boolean value) {
+    if (!value) {
+      this.fields = null;
+    }
+  }
+
+  public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) {
+    switch (field) {
+    case FIELDS:
+      if (value == null) {
+        unsetFields();
+      } else {
+        setFields((java.util.Map<java.lang.String,FieldResponse>)value);
+      }
+      break;
+
+    }
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public java.lang.Object getFieldValue(_Fields field) {
+    switch (field) {
+    case FIELDS:
+      return getFields();
+
+    }
+    throw new java.lang.IllegalStateException();
+  }
+
+  /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+  public boolean isSet(_Fields field) {
+    if (field == null) {
+      throw new java.lang.IllegalArgumentException();
+    }
+
+    switch (field) {
+    case FIELDS:
+      return isSetFields();
+    }
+    throw new java.lang.IllegalStateException();
+  }
+
+  @Override
+  public boolean equals(java.lang.Object that) {
+    if (that == null)
+      return false;
+    if (that instanceof Response)
+      return this.equals((Response)that);
+    return false;
+  }
+
+  public boolean equals(Response that) {
+    if (that == null)
+      return false;
+    if (this == that)
+      return true;
+
+    boolean this_present_fields = true && this.isSetFields();
+    boolean that_present_fields = true && that.isSetFields();
+    if (this_present_fields || that_present_fields) {
+      if (!(this_present_fields && that_present_fields))
+        return false;
+      if (!this.fields.equals(that.fields))
+        return false;
+    }
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int hashCode = 1;
+
+    hashCode = hashCode * 8191 + ((isSetFields()) ? 131071 : 524287);
+    if (isSetFields())
+      hashCode = hashCode * 8191 + fields.hashCode();
+
+    return hashCode;
+  }
+
+  @Override
+  public int compareTo(Response other) {
+    if (!getClass().equals(other.getClass())) {
+      return getClass().getName().compareTo(other.getClass().getName());
+    }
+
+    int lastComparison = 0;
+
+    lastComparison = java.lang.Boolean.valueOf(isSetFields()).compareTo(other.isSetFields());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetFields()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.fields, other.fields);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    return 0;
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public _Fields fieldForId(int fieldId) {
+    return _Fields.findByThriftId(fieldId);
+  }
+
+  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+    scheme(iprot).read(iprot, this);
+  }
+
+  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+    scheme(oprot).write(oprot, this);
+  }
+
+  @Override
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("Response(");
+    boolean first = true;
+
+    sb.append("fields:");
+    if (this.fields == null) {
+      sb.append("null");
+    } else {
+      sb.append(this.fields);
+    }
+    first = false;
+    sb.append(")");
+    return sb.toString();
+  }
+
+  public void validate() throws org.apache.thrift.TException {
+    // check for required fields
+    // check for sub-struct validity
+  }
+
+  private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+    try {
+      write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
+    try {
+      read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private static class ResponseStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+    public ResponseStandardScheme getScheme() {
+      return new ResponseStandardScheme();
+    }
+  }
+
+  private static class ResponseStandardScheme extends org.apache.thrift.scheme.StandardScheme<Response> {
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot, Response struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TField schemeField;
+      iprot.readStructBegin();
+      while (true)
+      {
+        schemeField = iprot.readFieldBegin();
+        if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+          break;
+        }
+        switch (schemeField.id) {
+          case 1: // FIELDS
+            if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
+              {
+                org.apache.thrift.protocol.TMap _map10 = iprot.readMapBegin();
+                struct.fields = new java.util.HashMap<java.lang.String,FieldResponse>(2*_map10.size);
+                @org.apache.thrift.annotation.Nullable java.lang.String _key11;
+                @org.apache.thrift.annotation.Nullable FieldResponse _val12;
+                for (int _i13 = 0; _i13 < _map10.size; ++_i13)
+                {
+                  _key11 = iprot.readString();
+                  _val12 = new FieldResponse();
+                  _val12.read(iprot);
+                  struct.fields.put(_key11, _val12);
+                }
+                iprot.readMapEnd();
+              }
+              struct.setFieldsIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          default:
+            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+        }
+        iprot.readFieldEnd();
+      }
+      iprot.readStructEnd();
+
+      // check for required fields of primitive type, which can't be checked in the validate method
+      struct.validate();
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot, Response struct) throws org.apache.thrift.TException {
+      struct.validate();
+
+      oprot.writeStructBegin(STRUCT_DESC);
+      if (struct.fields != null) {
+        oprot.writeFieldBegin(FIELDS_FIELD_DESC);
+        {
+          oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRUCT, struct.fields.size()));
+          for (java.util.Map.Entry<java.lang.String, FieldResponse> _iter14 : struct.fields.entrySet())
+          {
+            oprot.writeString(_iter14.getKey());
+            _iter14.getValue().write(oprot);
+          }
+          oprot.writeMapEnd();
+        }
+        oprot.writeFieldEnd();
+      }
+      oprot.writeFieldStop();
+      oprot.writeStructEnd();
+    }
+
+  }
+
+  private static class ResponseTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+    public ResponseTupleScheme getScheme() {
+      return new ResponseTupleScheme();
+    }
+  }
+
+  private static class ResponseTupleScheme extends org.apache.thrift.scheme.TupleScheme<Response> {
+
+    @Override
+    public void write(org.apache.thrift.protocol.TProtocol prot, Response struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
+      if (struct.isSetFields()) {
+        optionals.set(0);
+      }
+      oprot.writeBitSet(optionals, 1);
+      if (struct.isSetFields()) {
+        {
+          oprot.writeI32(struct.fields.size());
+          for (java.util.Map.Entry<java.lang.String, FieldResponse> _iter15 : struct.fields.entrySet())
+          {
+            oprot.writeString(_iter15.getKey());
+            _iter15.getValue().write(oprot);
+          }
+        }
+      }
+    }
+
+    @Override
+    public void read(org.apache.thrift.protocol.TProtocol prot, Response struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(1);
+      if (incoming.get(0)) {
+        {
+          org.apache.thrift.protocol.TMap _map16 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
+          struct.fields = new java.util.HashMap<java.lang.String,FieldResponse>(2*_map16.size);
+          @org.apache.thrift.annotation.Nullable java.lang.String _key17;
+          @org.apache.thrift.annotation.Nullable FieldResponse _val18;
+          for (int _i19 = 0; _i19 < _map16.size; ++_i19)
+          {
+            _key17 = iprot.readString();
+            _val18 = new FieldResponse();
+            _val18.read(iprot);
+            struct.fields.put(_key17, _val18);
+          }
+        }
+        struct.setFieldsIsSet(true);
+      }
+    }
+  }
+
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+}
+
diff --git a/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/impl/Client.java b/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/impl/Client.java
new file mode 100644
index 0000000..2375de9
--- /dev/null
+++ b/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/impl/Client.java
@@ -0,0 +1,41 @@
+package org.apache.plc4x.interop.impl;
+
+import org.apache.plc4x.interop.ConnectionHandle;
+import org.apache.plc4x.interop.InteropServer;
+import org.apache.plc4x.interop.Request;
+import org.apache.plc4x.interop.Response;
+import org.apache.thrift.TException;
+import org.apache.thrift.protocol.TBinaryProtocol;
+import org.apache.thrift.protocol.TProtocol;
+import org.apache.thrift.transport.TSocket;
+import org.apache.thrift.transport.TTransport;
+
+import java.util.Collections;
+
+public class Client {
+
+    public static void main(String[] args) throws TException {
+        try (TTransport transport = new TSocket("localhost", 9090)) {
+
+            transport.open();
+
+            TProtocol protocol = new TBinaryProtocol(transport);
+
+            final InteropServer.Client client = new InteropServer.Client(protocol);
+
+//            final ConnectionHandle connection = client.connect("mock:a");
+//            final Response result = client.execute(connection, new Request(Collections.singletonMap("field_1", "DB.field.qry")));
+//            System.out.println("Got response: " + result);
+
+            for (int i = 1; i <= 100; i++) {
+                final ConnectionHandle connection = client.connect("s7://192.168.167.210/0/1");
+                final Response result = client.execute(connection, new Request(Collections.singletonMap("field_1", "%M0:USINT")));
+                System.out.println("Got response: " + result);
+
+                client.close(connection);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/impl/Handler.java b/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/impl/Handler.java
new file mode 100644
index 0000000..02ed94d
--- /dev/null
+++ b/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/impl/Handler.java
@@ -0,0 +1,143 @@
+package org.apache.plc4x.interop.impl;
+
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.apache.commons.lang3.NotImplementedException;
+import org.apache.plc4x.interop.ConnectionHandle;
+import org.apache.plc4x.interop.FieldResponse;
+import org.apache.plc4x.interop.InteropServer;
+import org.apache.plc4x.interop.PlcException;
+import org.apache.plc4x.interop.RESPONSE_CODE;
+import org.apache.plc4x.interop.Request;
+import org.apache.plc4x.interop.Response;
+import org.apache.plc4x.java.PlcDriverManager;
+import org.apache.plc4x.java.api.PlcConnection;
+import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
+import org.apache.plc4x.java.api.messages.PlcReadRequest;
+import org.apache.plc4x.java.api.messages.PlcReadResponse;
+import org.apache.plc4x.java.api.types.PlcResponseCode;
+import org.apache.thrift.TException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+
+public class Handler implements InteropServer.Iface {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(Handler.class);
+
+    private final AtomicLong connectionCounter = new AtomicLong(0);
+
+    private final PlcDriverManager driverManager;
+    private final Map<Long, String> connectionStrings;
+    private final Map<Long, PlcConnection> connections;
+
+    public Handler(PlcDriverManager driverManager) {
+        this.driverManager = driverManager;
+        this.connections = new ConcurrentHashMap<>();
+        this.connectionStrings = new ConcurrentHashMap<>();
+    }
+
+
+    @Override public ConnectionHandle connect(String connectionString) throws PlcException, TException {
+        LOGGER.debug("Receiving new connect request to '{}'", connectionString);
+        try {
+            long id = connectionCounter.getAndIncrement();
+
+            final PlcConnection connection = driverManager.getConnection(connectionString);
+            connection.connect();
+
+            LOGGER.debug("Established connection to '{}' with handle {}", connectionString, id);
+
+            this.connections.put(id, connection);
+            this.connectionStrings.put(id, connectionString);
+            return new ConnectionHandle(id);
+        } catch (PlcConnectionException e) {
+            LOGGER.warn("Unable to start a connection to url '" + connectionString + "'", e);
+            throw new PlcException(connectionString, e.getMessage());
+        }
+    }
+
+    @Override public void close(ConnectionHandle handle) throws TException {
+        LOGGER.debug("Receiving new close request for handle {}", handle.getConnectionId());
+        try {
+            connections.get(handle).close();
+            connections.remove(handle);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+    }
+
+
+    @Override public Response execute(ConnectionHandle handle, Request request) throws PlcException, TException {
+        LOGGER.debug("Executing " + request);
+        if (request.getFields() == null) {
+            throw new PlcException(
+                connectionStrings.get(handle.getConnectionId()),
+                "No fields given in the request!");
+        }
+        try {
+            final PlcReadRequest.Builder builder = connections.get(handle.getConnectionId()).readRequestBuilder();
+            for (Map.Entry<String, String> entry : request.getFields().entrySet()) {
+                builder.addItem(entry.getKey(), entry.getValue());
+            }
+            final PlcReadResponse response = builder.build().execute().get(1_000L, TimeUnit.MILLISECONDS);
+
+            final HashMap<String, FieldResponse> resultMap = new HashMap<>();
+            for (String key : request.getFields().keySet()) {
+                final PlcResponseCode responseCode = response.getResponseCode(key);
+
+                final FieldResponse fieldResponse = new FieldResponse(convertResponseCode(responseCode));
+
+                if (PlcResponseCode.OK.equals(responseCode)) {
+                    if (response.isValidBoolean(key)) {
+                        fieldResponse.setBoolValue(response.getBoolean(key));
+                    }
+                    if (response.isValidLong(key)) {
+                        fieldResponse.setLongValue(response.getLong(key));
+                    }
+                    if (response.isValidDouble(key)) {
+                        fieldResponse.setDoubleValue(response.getDouble(key));
+                    }
+                    if (response.isValidString(key)) {
+                        fieldResponse.setStringValue(response.getString(key));
+                    }
+                }
+
+                resultMap.put(key, fieldResponse);
+            }
+            return new Response(resultMap);
+        } catch (Exception e) {
+            LOGGER.warn("Exception during execution of request '" + request + "' for handle " + handle.getConnectionId(), e);
+            throw new PlcException(
+                connectionStrings.get(handle.getConnectionId()),
+                ExceptionUtils.getStackTrace(e));
+        }
+    }
+
+    private RESPONSE_CODE convertResponseCode(PlcResponseCode responseCode) {
+        switch (responseCode) {
+            case OK:
+                return RESPONSE_CODE.OK;
+            case NOT_FOUND:
+                return RESPONSE_CODE.NOT_FOUND;
+            case ACCESS_DENIED:
+                return RESPONSE_CODE.ACCESS_DENIED;
+            case INTERNAL_ERROR:
+                return RESPONSE_CODE.INTERNAL_ERROR;
+            case INVALID_ADDRESS:
+                return RESPONSE_CODE.INVALID_ADDRESS;
+            case INVALID_DATATYPE:
+                return RESPONSE_CODE.INVALID_DATATYPE;
+            case RESPONSE_PENDING:
+                return RESPONSE_CODE.RESPONSE_PENDING;
+            default:
+                throw new NotImplementedException("This response code is not implemented!");
+        }
+    }
+
+}
diff --git a/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/impl/Server.java b/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/impl/Server.java
new file mode 100644
index 0000000..01274ae
--- /dev/null
+++ b/plc4j/utils/interop/src/main/java/org/apache/plc4x/interop/impl/Server.java
@@ -0,0 +1,72 @@
+package org.apache.plc4x.interop.impl;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.plc4x.interop.InteropServer;
+import org.apache.plc4x.java.PlcDriverManager;
+import org.apache.plc4x.java.api.exceptions.PlcConnectionException;
+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.base.messages.items.BaseDefaultFieldItem;
+import org.apache.plc4x.java.base.messages.items.DefaultLongFieldItem;
+import org.apache.plc4x.java.mock.MockDevice;
+import org.apache.plc4x.java.mock.PlcMockConnection;
+import org.apache.thrift.server.TServer;
+import org.apache.thrift.server.TSimpleServer;
+import org.apache.thrift.transport.TServerSocket;
+import org.apache.thrift.transport.TServerTransport;
+
+import java.util.Collection;
+import java.util.function.Consumer;
+
+public class Server {
+
+    public static void main(String[] args) throws PlcConnectionException {
+        final PlcDriverManager driverManager = new PlcDriverManager();
+
+        // Do some mocking
+        final PlcMockConnection mockConnection = (PlcMockConnection) driverManager.getConnection("mock:a");
+
+        mockConnection.setDevice(new MyMockDevice());
+
+        final Handler handler = new Handler(driverManager);
+        final InteropServer.Processor<Handler> processor = new InteropServer.Processor<>(handler);
+
+        try {
+            TServerTransport serverTransport = new TServerSocket(9090);
+            TServer server = new TSimpleServer(new TServer.Args(serverTransport).processor(processor));
+
+            System.out.println("Starting the simple server...");
+            server.serve();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    private static class MyMockDevice implements MockDevice {
+        @Override public Pair<PlcResponseCode, BaseDefaultFieldItem> read(String fieldQuery) {
+            return Pair.of(PlcResponseCode.OK, new DefaultLongFieldItem(100L));
+        }
+
+        @Override public PlcResponseCode write(String fieldQuery, Object value) {
+            return null;
+        }
+
+        @Override public Pair<PlcResponseCode, PlcSubscriptionHandle> subscribe(String fieldQuery) {
+            return null;
+        }
+
+        @Override public void unsubscribe() {
+
+        }
+
+        @Override public PlcConsumerRegistration register(Consumer<PlcSubscriptionEvent> consumer, Collection<PlcSubscriptionHandle> handles) {
+            return null;
+        }
+
+        @Override public void unregister(PlcConsumerRegistration registration) {
+
+        }
+    }
+}
diff --git a/plc4j/utils/interop/src/main/thrift/gen-csharp/org/apache/plc4x/interop/ConnectionHandle.cs b/plc4j/utils/interop/src/main/thrift/gen-csharp/org/apache/plc4x/interop/ConnectionHandle.cs
new file mode 100644
index 0000000..f137fef
--- /dev/null
+++ b/plc4j/utils/interop/src/main/thrift/gen-csharp/org/apache/plc4x/interop/ConnectionHandle.cs
@@ -0,0 +1,128 @@
+/**
+ * Autogenerated by Thrift Compiler (0.12.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+using Thrift;
+using Thrift.Collections;
+using System.Runtime.Serialization;
+using Thrift.Protocol;
+using Thrift.Transport;
+
+namespace org.apache.plc4x.interop
+{
+
+  #if !SILVERLIGHT
+  [Serializable]
+  #endif
+  public partial class ConnectionHandle : TBase
+  {
+    private long _connectionId;
+
+    public long ConnectionId
+    {
+      get
+      {
+        return _connectionId;
+      }
+      set
+      {
+        __isset.connectionId = true;
+        this._connectionId = value;
+      }
+    }
+
+
+    public Isset __isset;
+    #if !SILVERLIGHT
+    [Serializable]
+    #endif
+    public struct Isset {
+      public bool connectionId;
+    }
+
+    public ConnectionHandle() {
+    }
+
+    public void Read (TProtocol iprot)
+    {
+      iprot.IncrementRecursionDepth();
+      try
+      {
+        TField field;
+        iprot.ReadStructBegin();
+        while (true)
+        {
+          field = iprot.ReadFieldBegin();
+          if (field.Type == TType.Stop) { 
+            break;
+          }
+          switch (field.ID)
+          {
+            case 1:
+              if (field.Type == TType.I64) {
+                ConnectionId = iprot.ReadI64();
+              } else { 
+                TProtocolUtil.Skip(iprot, field.Type);
+              }
+              break;
+            default: 
+              TProtocolUtil.Skip(iprot, field.Type);
+              break;
+          }
+          iprot.ReadFieldEnd();
+        }
+        iprot.ReadStructEnd();
+      }
+      finally
+      {
+        iprot.DecrementRecursionDepth();
+      }
+    }
+
+    public void Write(TProtocol oprot) {
+      oprot.IncrementRecursionDepth();
+      try
+      {
+        TStruct struc = new TStruct("ConnectionHandle");
+        oprot.WriteStructBegin(struc);
+        TField field = new TField();
+        if (__isset.connectionId) {
+          field.Name = "connectionId";
+          field.Type = TType.I64;
+          field.ID = 1;
+          oprot.WriteFieldBegin(field);
+          oprot.WriteI64(ConnectionId);
+          oprot.WriteFieldEnd();
+        }
+        oprot.WriteFieldStop();
+        oprot.WriteStructEnd();
+      }
+      finally
+      {
+        oprot.DecrementRecursionDepth();
+      }
+    }
+
+    public override string ToString() {
+      StringBuilder __sb = new StringBuilder("ConnectionHandle(");
+      bool __first = true;
+      if (__isset.connectionId) {
+        if(!__first) { __sb.Append(", "); }
+        __first = false;
+        __sb.Append("ConnectionId: ");
+        __sb.Append(ConnectionId);
+      }
+      __sb.Append(")");
+      return __sb.ToString();
+    }
+
+  }
+
+}
diff --git a/plc4j/utils/interop/src/main/thrift/gen-csharp/org/apache/plc4x/interop/FieldResponse.cs b/plc4j/utils/interop/src/main/thrift/gen-csharp/org/apache/plc4x/interop/FieldResponse.cs
new file mode 100644
index 0000000..d06ff13
--- /dev/null
+++ b/plc4j/utils/interop/src/main/thrift/gen-csharp/org/apache/plc4x/interop/FieldResponse.cs
@@ -0,0 +1,276 @@
+/**
+ * Autogenerated by Thrift Compiler (0.12.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+using Thrift;
+using Thrift.Collections;
+using System.Runtime.Serialization;
+using Thrift.Protocol;
+using Thrift.Transport;
+
+namespace org.apache.plc4x.interop
+{
+
+  #if !SILVERLIGHT
+  [Serializable]
+  #endif
+  public partial class FieldResponse : TBase
+  {
+    private RESPONSE_CODE _responseCode;
+    private bool _boolValue;
+    private long _longValue;
+    private double _doubleValue;
+    private string _stringValue;
+
+    /// <summary>
+    /// 
+    /// <seealso cref="RESPONSE_CODE"/>
+    /// </summary>
+    public RESPONSE_CODE ResponseCode
+    {
+      get
+      {
+        return _responseCode;
+      }
+      set
+      {
+        __isset.responseCode = true;
+        this._responseCode = value;
+      }
+    }
+
+    public bool BoolValue
+    {
+      get
+      {
+        return _boolValue;
+      }
+      set
+      {
+        __isset.boolValue = true;
+        this._boolValue = value;
+      }
+    }
+
+    public long LongValue
+    {
+      get
+      {
+        return _longValue;
+      }
+      set
+      {
+        __isset.longValue = true;
+        this._longValue = value;
+      }
+    }
+
+    public double DoubleValue
+    {
+      get
+      {
+        return _doubleValue;
+      }
+      set
+      {
+        __isset.doubleValue = true;
+        this._doubleValue = value;
+      }
+    }
+
+    public string StringValue
+    {
+      get
+      {
+        return _stringValue;
+      }
+      set
+      {
+        __isset.stringValue = true;
+        this._stringValue = value;
+      }
+    }
+
+
+    public Isset __isset;
+    #if !SILVERLIGHT
+    [Serializable]
+    #endif
+    public struct Isset {
+      public bool responseCode;
+      public bool boolValue;
+      public bool longValue;
+      public bool doubleValue;
+      public bool stringValue;
+    }
+
+    public FieldResponse() {
+    }
+
+    public void Read (TProtocol iprot)
+    {
+      iprot.IncrementRecursionDepth();
+      try
+      {
+        TField field;
+        iprot.ReadStructBegin();
+        while (true)
+        {
+          field = iprot.ReadFieldBegin();
+          if (field.Type == TType.Stop) { 
+            break;
+          }
+          switch (field.ID)
+          {
+            case 1:
+              if (field.Type == TType.I32) {
+                ResponseCode = (RESPONSE_CODE)iprot.ReadI32();
+              } else { 
+                TProtocolUtil.Skip(iprot, field.Type);
+              }
+              break;
+            case 2:
+              if (field.Type == TType.Bool) {
+                BoolValue = iprot.ReadBool();
+              } else { 
+                TProtocolUtil.Skip(iprot, field.Type);
+              }
+              break;
+            case 3:
+              if (field.Type == TType.I64) {
+                LongValue = iprot.ReadI64();
+              } else { 
+                TProtocolUtil.Skip(iprot, field.Type);
+              }
+              break;
+            case 4:
+              if (field.Type == TType.Double) {
+                DoubleValue = iprot.ReadDouble();
+              } else { 
+                TProtocolUtil.Skip(iprot, field.Type);
+              }
+              break;
+            case 5:
+              if (field.Type == TType.String) {
+                StringValue = iprot.ReadString();
+              } else { 
+                TProtocolUtil.Skip(iprot, field.Type);
+              }
+              break;
+            default: 
+              TProtocolUtil.Skip(iprot, field.Type);
+              break;
+          }
+          iprot.ReadFieldEnd();
+        }
+        iprot.ReadStructEnd();
+      }
+      finally
+      {
+        iprot.DecrementRecursionDepth();
+      }
+    }
+
+    public void Write(TProtocol oprot) {
+      oprot.IncrementRecursionDepth();
+      try
+      {
+        TStruct struc = new TStruct("FieldResponse");
+        oprot.WriteStructBegin(struc);
+        TField field = new TField();
+        if (__isset.responseCode) {
+          field.Name = "responseCode";
+          field.Type = TType.I32;
+          field.ID = 1;
+          oprot.WriteFieldBegin(field);
+          oprot.WriteI32((int)ResponseCode);
+          oprot.WriteFieldEnd();
+        }
+        if (__isset.boolValue) {
+          field.Name = "boolValue";
+          field.Type = TType.Bool;
+          field.ID = 2;
+          oprot.WriteFieldBegin(field);
+          oprot.WriteBool(BoolValue);
+          oprot.WriteFieldEnd();
+        }
+        if (__isset.longValue) {
+          field.Name = "longValue";
+          field.Type = TType.I64;
+          field.ID = 3;
+          oprot.WriteFieldBegin(field);
+          oprot.WriteI64(LongValue);
+          oprot.WriteFieldEnd();
+        }
+        if (__isset.doubleValue) {
+          field.Name = "doubleValue";
+          field.Type = TType.Double;
+          field.ID = 4;
+          oprot.WriteFieldBegin(field);
+          oprot.WriteDouble(DoubleValue);
+          oprot.WriteFieldEnd();
+        }
+        if (StringValue != null && __isset.stringValue) {
+          field.Name = "stringValue";
+          field.Type = TType.String;
+          field.ID = 5;
+          oprot.WriteFieldBegin(field);
+          oprot.WriteString(StringValue);
+          oprot.WriteFieldEnd();
+        }
+        oprot.WriteFieldStop();
+        oprot.WriteStructEnd();
+      }
+      finally
+      {
+        oprot.DecrementRecursionDepth();
+      }
+    }
+
+    public override string ToString() {
+      StringBuilder __sb = new StringBuilder("FieldResponse(");
+      bool __first = true;
+      if (__isset.responseCode) {
+        if(!__first) { __sb.Append(", "); }
+        __first = false;
+        __sb.Append("ResponseCode: ");
+        __sb.Append(ResponseCode);
+      }
+      if (__isset.boolValue) {
+        if(!__first) { __sb.Append(", "); }
+        __first = false;
+        __sb.Append("BoolValue: ");
+        __sb.Append(BoolValue);
+      }
+      if (__isset.longValue) {
+        if(!__first) { __sb.Append(", "); }
+        __first = false;
+        __sb.Append("LongValue: ");
+        __sb.Append(LongValue);
+      }
+      if (__isset.doubleValue) {
+        if(!__first) { __sb.Append(", "); }
+        __first = false;
+        __sb.Append("DoubleValue: ");
+        __sb.Append(DoubleValue);
+      }
+      if (StringValue != null && __isset.stringValue) {
+        if(!__first) { __sb.Append(", "); }
+        __first = false;
+        __sb.Append("StringValue: ");
+        __sb.Append(StringValue);
+      }
+      __sb.Append(")");
+      return __sb.ToString();
+    }
+
+  }
+
+}
diff --git a/plc4j/utils/interop/src/main/thrift/gen-csharp/org/apache/plc4x/interop/InteropServer.cs b/plc4j/utils/interop/src/main/thrift/gen-csharp/org/apache/plc4x/interop/InteropServer.cs
new file mode 100644
index 0000000..6fc0857
--- /dev/null
+++ b/plc4j/utils/interop/src/main/thrift/gen-csharp/org/apache/plc4x/interop/InteropServer.cs
@@ -0,0 +1,1177 @@
+/**
+ * Autogenerated by Thrift Compiler (0.12.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+using Thrift;
+using Thrift.Collections;
+using System.Runtime.Serialization;
+using Thrift.Protocol;
+using Thrift.Transport;
+
+namespace org.apache.plc4x.interop
+{
+  public partial class InteropServer {
+    public interface ISync {
+      ConnectionHandle connect(string connectionString);
+      Response execute(ConnectionHandle handle, Request request);
+      void close(ConnectionHandle handle);
+    }
+
+    public interface Iface : ISync {
+      #if SILVERLIGHT
+      IAsyncResult Begin_connect(AsyncCallback callback, object state, string connectionString);
+      ConnectionHandle End_connect(IAsyncResult asyncResult);
+      #endif
+      #if SILVERLIGHT
+      IAsyncResult Begin_execute(AsyncCallback callback, object state, ConnectionHandle handle, Request request);
+      Response End_execute(IAsyncResult asyncResult);
+      #endif
+      #if SILVERLIGHT
+      IAsyncResult Begin_close(AsyncCallback callback, object state, ConnectionHandle handle);
+      void End_close(IAsyncResult asyncResult);
+      #endif
+    }
+
+    public class Client : IDisposable, Iface {
+      public Client(TProtocol prot) : this(prot, prot)
+      {
+      }
+
+      public Client(TProtocol iprot, TProtocol oprot)
+      {
+        iprot_ = iprot;
+        oprot_ = oprot;
+      }
+
+      protected TProtocol iprot_;
+      protected TProtocol oprot_;
+      protected int seqid_;
+
+      public TProtocol InputProtocol
+      {
+        get { return iprot_; }
+      }
+      public TProtocol OutputProtocol
+      {
+        get { return oprot_; }
+      }
+
+
+      #region " IDisposable Support "
+      private bool _IsDisposed;
+
+      // IDisposable
+      public void Dispose()
+      {
+        Dispose(true);
+      }
+      
+
+      protected virtual void Dispose(bool disposing)
+      {
+        if (!_IsDisposed)
+        {
+          if (disposing)
+          {
+            if (iprot_ != null)
+            {
+              ((IDisposable)iprot_).Dispose();
+            }
+            if (oprot_ != null)
+            {
+              ((IDisposable)oprot_).Dispose();
+            }
+          }
+        }
+        _IsDisposed = true;
+      }
+      #endregion
+
+
+      
+      #if SILVERLIGHT
+      
+      public IAsyncResult Begin_connect(AsyncCallback callback, object state, string connectionString)
+      {
+        return send_connect(callback, state, connectionString);
+      }
+
+      public ConnectionHandle End_connect(IAsyncResult asyncResult)
+      {
+        oprot_.Transport.EndFlush(asyncResult);
+        return recv_connect();
+      }
+
+      #endif
+
+      public ConnectionHandle connect(string connectionString)
+      {
+        #if SILVERLIGHT
+        var asyncResult = Begin_connect(null, null, connectionString);
+        return End_connect(asyncResult);
+
+        #else
+        send_connect(connectionString);
+        return recv_connect();
+
+        #endif
+      }
+      #if SILVERLIGHT
+      public IAsyncResult send_connect(AsyncCallback callback, object state, string connectionString)
+      {
+        oprot_.WriteMessageBegin(new TMessage("connect", TMessageType.Call, seqid_));
+        connect_args args = new connect_args();
+        args.ConnectionString = connectionString;
+        args.Write(oprot_);
+        oprot_.WriteMessageEnd();
+        return oprot_.Transport.BeginFlush(callback, state);
+      }
+
+      #else
+
+      public void send_connect(string connectionString)
+      {
+        oprot_.WriteMessageBegin(new TMessage("connect", TMessageType.Call, seqid_));
+        connect_args args = new connect_args();
+        args.ConnectionString = connectionString;
+        args.Write(oprot_);
+        oprot_.WriteMessageEnd();
+        oprot_.Transport.Flush();
+      }
+      #endif
+
+      public ConnectionHandle recv_connect()
+      {
+        TMessage msg = iprot_.ReadMessageBegin();
+        if (msg.Type == TMessageType.Exception) {
+          TApplicationException x = TApplicationException.Read(iprot_);
+          iprot_.ReadMessageEnd();
+          throw x;
+        }
+        connect_result result = new connect_result();
+        result.Read(iprot_);
+        iprot_.ReadMessageEnd();
+        if (result.__isset.success) {
+          return result.Success;
+        }
+        if (result.__isset.connectionException) {
+          throw result.ConnectionException;
+        }
+        throw new TApplicationException(TApplicationException.ExceptionType.MissingResult, "connect failed: unknown result");
+      }
+
+      
+      #if SILVERLIGHT
+      
+      public IAsyncResult Begin_execute(AsyncCallback callback, object state, ConnectionHandle handle, Request request)
+      {
+        return send_execute(callback, state, handle, request);
+      }
+
+      public Response End_execute(IAsyncResult asyncResult)
+      {
+        oprot_.Transport.EndFlush(asyncResult);
+        return recv_execute();
+      }
+
+      #endif
+
+      public Response execute(ConnectionHandle handle, Request request)
+      {
+        #if SILVERLIGHT
+        var asyncResult = Begin_execute(null, null, handle, request);
+        return End_execute(asyncResult);
+
+        #else
+        send_execute(handle, request);
+        return recv_execute();
+
+        #endif
+      }
+      #if SILVERLIGHT
+      public IAsyncResult send_execute(AsyncCallback callback, object state, ConnectionHandle handle, Request request)
+      {
+        oprot_.WriteMessageBegin(new TMessage("execute", TMessageType.Call, seqid_));
+        execute_args args = new execute_args();
+        args.Handle = handle;
+        args.Request = request;
+        args.Write(oprot_);
+        oprot_.WriteMessageEnd();
+        return oprot_.Transport.BeginFlush(callback, state);
+      }
+
+      #else
+
+      public void send_execute(ConnectionHandle handle, Request request)
+      {
+        oprot_.WriteMessageBegin(new TMessage("execute", TMessageType.Call, seqid_));
+        execute_args args = new execute_args();
+        args.Handle = handle;
+        args.Request = request;
+        args.Write(oprot_);
+        oprot_.WriteMessageEnd();
+        oprot_.Transport.Flush();
+      }
+      #endif
+
+      public Response recv_execute()
+      {
+        TMessage msg = iprot_.ReadMessageBegin();
+        if (msg.Type == TMessageType.Exception) {
+          TApplicationException x = TApplicationException.Read(iprot_);
+          iprot_.ReadMessageEnd();
+          throw x;
+        }
+        execute_result result = new execute_result();
+        result.Read(iprot_);
+        iprot_.ReadMessageEnd();
+        if (result.__isset.success) {
+          return result.Success;
+        }
+        if (result.__isset.executionException) {
+          throw result.ExecutionException;
+        }
+        throw new TApplicationException(TApplicationException.ExceptionType.MissingResult, "execute failed: unknown result");
+      }
+
+      
+      #if SILVERLIGHT
+      
+      public IAsyncResult Begin_close(AsyncCallback callback, object state, ConnectionHandle handle)
+      {
+        return send_close(callback, state, handle);
+      }
+
+      public void End_close(IAsyncResult asyncResult)
+      {
+        oprot_.Transport.EndFlush(asyncResult);
+        recv_close();
+      }
+
+      #endif
+
+      public void close(ConnectionHandle handle)
+      {
+        #if SILVERLIGHT
+        var asyncResult = Begin_close(null, null, handle);
+        End_close(asyncResult);
+
+        #else
+        send_close(handle);
+        recv_close();
+
+        #endif
+      }
+      #if SILVERLIGHT
+      public IAsyncResult send_close(AsyncCallback callback, object state, ConnectionHandle handle)
+      {
+        oprot_.WriteMessageBegin(new TMessage("close", TMessageType.Call, seqid_));
+        close_args args = new close_args();
+        args.Handle = handle;
+        args.Write(oprot_);
+        oprot_.WriteMessageEnd();
+        return oprot_.Transport.BeginFlush(callback, state);
+      }
+
+      #else
+
+      public void send_close(ConnectionHandle handle)
+      {
+        oprot_.WriteMessageBegin(new TMessage("close", TMessageType.Call, seqid_));
+        close_args args = new close_args();
+        args.Handle = handle;
+        args.Write(oprot_);
+        oprot_.WriteMessageEnd();
+        oprot_.Transport.Flush();
+      }
+      #endif
+
+      public void recv_close()
+      {
+        TMessage msg = iprot_.ReadMessageBegin();
+        if (msg.Type == TMessageType.Exception) {
+          TApplicationException x = TApplicationException.Read(iprot_);
+          iprot_.ReadMessageEnd();
+          throw x;
+        }
+        close_result result = new close_result();
+        result.Read(iprot_);
+        iprot_.ReadMessageEnd();
+        return;
+      }
+
+    }
+    public class Processor : TProcessor {
+      public Processor(ISync iface)
+      {
+        iface_ = iface;
+        processMap_["connect"] = connect_Process;
+        processMap_["execute"] = execute_Process;
+        processMap_["close"] = close_Process;
+      }
+
+      protected delegate void ProcessFunction(int seqid, TProtocol iprot, TProtocol oprot);
+      private ISync iface_;
+      protected Dictionary<string, ProcessFunction> processMap_ = new Dictionary<string, ProcessFunction>();
+
+      public bool Process(TProtocol iprot, TProtocol oprot)
+      {
+        try
+        {
+          TMessage msg = iprot.ReadMessageBegin();
+          ProcessFunction fn;
+          processMap_.TryGetValue(msg.Name, out fn);
+          if (fn == null) {
+            TProtocolUtil.Skip(iprot, TType.Struct);
+            iprot.ReadMessageEnd();
+            TApplicationException x = new TApplicationException (TApplicationException.ExceptionType.UnknownMethod, "Invalid method name: '" + msg.Name + "'");
+            oprot.WriteMessageBegin(new TMessage(msg.Name, TMessageType.Exception, msg.SeqID));
+            x.Write(oprot);
+            oprot.WriteMessageEnd();
+            oprot.Transport.Flush();
+            return true;
+          }
+          fn(msg.SeqID, iprot, oprot);
+        }
+        catch (IOException)
+        {
+          return false;
+        }
+        return true;
+      }
+
+      public void connect_Process(int seqid, TProtocol iprot, TProtocol oprot)
+      {
+        connect_args args = new connect_args();
+        args.Read(iprot);
+        iprot.ReadMessageEnd();
+        connect_result result = new connect_result();
+        try
+        {
+          try
+          {
+            result.Success = iface_.connect(args.ConnectionString);
+          }
+          catch (PlcException connectionException)
+          {
+            result.ConnectionException = connectionException;
+          }
+          oprot.WriteMessageBegin(new TMessage("connect", TMessageType.Reply, seqid)); 
+          result.Write(oprot);
+        }
+        catch (TTransportException)
+        {
+          throw;
+        }
+        catch (Exception ex)
+        {
+          Console.Error.WriteLine("Error occurred in processor:");
+          Console.Error.WriteLine(ex.ToString());
+          TApplicationException x = new TApplicationException        (TApplicationException.ExceptionType.InternalError," Internal error.");
+          oprot.WriteMessageBegin(new TMessage("connect", TMessageType.Exception, seqid));
+          x.Write(oprot);
+        }
+        oprot.WriteMessageEnd();
+        oprot.Transport.Flush();
+      }
+
+      public void execute_Process(int seqid, TProtocol iprot, TProtocol oprot)
+      {
+        execute_args args = new execute_args();
+        args.Read(iprot);
+        iprot.ReadMessageEnd();
+        execute_result result = new execute_result();
+        try
+        {
+          try
+          {
+            result.Success = iface_.execute(args.Handle, args.Request);
+          }
+          catch (PlcException executionException)
+          {
+            result.ExecutionException = executionException;
+          }
+          oprot.WriteMessageBegin(new TMessage("execute", TMessageType.Reply, seqid)); 
+          result.Write(oprot);
+        }
+        catch (TTransportException)
+        {
+          throw;
+        }
+        catch (Exception ex)
+        {
+          Console.Error.WriteLine("Error occurred in processor:");
+          Console.Error.WriteLine(ex.ToString());
+          TApplicationException x = new TApplicationException        (TApplicationException.ExceptionType.InternalError," Internal error.");
+          oprot.WriteMessageBegin(new TMessage("execute", TMessageType.Exception, seqid));
+          x.Write(oprot);
+        }
+        oprot.WriteMessageEnd();
+        oprot.Transport.Flush();
+      }
+
+      public void close_Process(int seqid, TProtocol iprot, TProtocol oprot)
+      {
+        close_args args = new close_args();
+        args.Read(iprot);
+        iprot.ReadMessageEnd();
+        close_result result = new close_result();
+        try
+        {
+          iface_.close(args.Handle);
+          oprot.WriteMessageBegin(new TMessage("close", TMessageType.Reply, seqid)); 
+          result.Write(oprot);
+        }
+        catch (TTransportException)
+        {
+          throw;
+        }
+        catch (Exception ex)
+        {
+          Console.Error.WriteLine("Error occurred in processor:");
+          Console.Error.WriteLine(ex.ToString());
+          TApplicationException x = new TApplicationException        (TApplicationException.ExceptionType.InternalError," Internal error.");
+          oprot.WriteMessageBegin(new TMessage("close", TMessageType.Exception, seqid));
+          x.Write(oprot);
+        }
+        oprot.WriteMessageEnd();
+        oprot.Transport.Flush();
+      }
+
+    }
+
+
+    #if !SILVERLIGHT
+    [Serializable]
+    #endif
+    public partial class connect_args : TBase
+    {
+      private string _connectionString;
+
+      public string ConnectionString
+      {
+        get
+        {
+          return _connectionString;
+        }
+        set
+        {
+          __isset.connectionString = true;
+          this._connectionString = value;
+        }
+      }
+
+
+      public Isset __isset;
+      #if !SILVERLIGHT
+      [Serializable]
+      #endif
+      public struct Isset {
+        public bool connectionString;
+      }
+
+      public connect_args() {
+      }
+
+      public void Read (TProtocol iprot)
+      {
+        iprot.IncrementRecursionDepth();
+        try
+        {
+          TField field;
+          iprot.ReadStructBegin();
+          while (true)
+          {
+            field = iprot.ReadFieldBegin();
+            if (field.Type == TType.Stop) { 
+              break;
+            }
+            switch (field.ID)
+            {
+              case 1:
+                if (field.Type == TType.String) {
+                  ConnectionString = iprot.ReadString();
+                } else { 
+                  TProtocolUtil.Skip(iprot, field.Type);
+                }
+                break;
+              default: 
+                TProtocolUtil.Skip(iprot, field.Type);
+                break;
+            }
+            iprot.ReadFieldEnd();
+          }
+          iprot.ReadStructEnd();
+        }
+        finally
+        {
+          iprot.DecrementRecursionDepth();
+        }
+      }
+
+      public void Write(TProtocol oprot) {
+        oprot.IncrementRecursionDepth();
+        try
+        {
+          TStruct struc = new TStruct("connect_args");
+          oprot.WriteStructBegin(struc);
+          TField field = new TField();
+          if (ConnectionString != null && __isset.connectionString) {
+            field.Name = "connectionString";
+            field.Type = TType.String;
+            field.ID = 1;
+            oprot.WriteFieldBegin(field);
+            oprot.WriteString(ConnectionString);
+            oprot.WriteFieldEnd();
+          }
+          oprot.WriteFieldStop();
+          oprot.WriteStructEnd();
+        }
+        finally
+        {
+          oprot.DecrementRecursionDepth();
+        }
+      }
+
+      public override string ToString() {
+        StringBuilder __sb = new StringBuilder("connect_args(");
+        bool __first = true;
+        if (ConnectionString != null && __isset.connectionString) {
+          if(!__first) { __sb.Append(", "); }
+          __first = false;
+          __sb.Append("ConnectionString: ");
+          __sb.Append(ConnectionString);
+        }
+        __sb.Append(")");
+        return __sb.ToString();
+      }
+
+    }
+
+
+    #if !SILVERLIGHT
+    [Serializable]
+    #endif
+    public partial class connect_result : TBase
+    {
+      private ConnectionHandle _success;
+      private PlcException _connectionException;
+
+      public ConnectionHandle Success
+      {
+        get
+        {
+          return _success;
+        }
+        set
+        {
+          __isset.success = true;
+          this._success = value;
+        }
+      }
+
+      public PlcException ConnectionException
+      {
+        get
+        {
+          return _connectionException;
+        }
+        set
+        {
+          __isset.connectionException = true;
+          this._connectionException = value;
+        }
+      }
+
+
+      public Isset __isset;
+      #if !SILVERLIGHT
+      [Serializable]
+      #endif
+      public struct Isset {
+        public bool success;
+        public bool connectionException;
+      }
+
+      public connect_result() {
+      }
+
+      public void Read (TProtocol iprot)
+      {
+        iprot.IncrementRecursionDepth();
+        try
+        {
+          TField field;
+          iprot.ReadStructBegin();
+          while (true)
+          {
+            field = iprot.ReadFieldBegin();
+            if (field.Type == TType.Stop) { 
+              break;
+            }
+            switch (field.ID)
+            {
+              case 0:
+                if (field.Type == TType.Struct) {
+                  Success = new ConnectionHandle();
+                  Success.Read(iprot);
+                } else { 
+                  TProtocolUtil.Skip(iprot, field.Type);
+                }
+                break;
+              case 1:
+                if (field.Type == TType.Struct) {
+                  ConnectionException = new PlcException();
+                  ConnectionException.Read(iprot);
+                } else { 
+                  TProtocolUtil.Skip(iprot, field.Type);
+                }
+                break;
+              default: 
+                TProtocolUtil.Skip(iprot, field.Type);
+                break;
+            }
+            iprot.ReadFieldEnd();
+          }
+          iprot.ReadStructEnd();
+        }
+        finally
+        {
+          iprot.DecrementRecursionDepth();
+        }
+      }
+
+      public void Write(TProtocol oprot) {
+        oprot.IncrementRecursionDepth();
+        try
+        {
+          TStruct struc = new TStruct("connect_result");
+          oprot.WriteStructBegin(struc);
+          TField field = new TField();
+
+          if (this.__isset.success) {
+            if (Success != null) {
+              field.Name = "Success";
+              field.Type = TType.Struct;
+              field.ID = 0;
+              oprot.WriteFieldBegin(field);
+              Success.Write(oprot);
+              oprot.WriteFieldEnd();
+            }
+          } else if (this.__isset.connectionException) {
+            if (ConnectionException != null) {
+              field.Name = "ConnectionException";
+              field.Type = TType.Struct;
+              field.ID = 1;
+              oprot.WriteFieldBegin(field);
+              ConnectionException.Write(oprot);
+              oprot.WriteFieldEnd();
+            }
+          }
+          oprot.WriteFieldStop();
+          oprot.WriteStructEnd();
+        }
+        finally
+        {
+          oprot.DecrementRecursionDepth();
+        }
+      }
+
+      public override string ToString() {
+        StringBuilder __sb = new StringBuilder("connect_result(");
+        bool __first = true;
+        if (Success != null && __isset.success) {
+          if(!__first) { __sb.Append(", "); }
+          __first = false;
+          __sb.Append("Success: ");
+          __sb.Append(Success== null ? "<null>" : Success.ToString());
+        }
+        if (ConnectionException != null && __isset.connectionException) {
+          if(!__first) { __sb.Append(", "); }
+          __first = false;
+          __sb.Append("ConnectionException: ");
+          __sb.Append(ConnectionException== null ? "<null>" : ConnectionException.ToString());
+        }
+        __sb.Append(")");
+        return __sb.ToString();
+      }
+
+    }
+
+
+    #if !SILVERLIGHT
+    [Serializable]
+    #endif
+    public partial class execute_args : TBase
+    {
+      private ConnectionHandle _handle;
+      private Request _request;
+
+      public ConnectionHandle Handle
+      {
+        get
+        {
+          return _handle;
+        }
+        set
+        {
+          __isset.handle = true;
+          this._handle = value;
+        }
+      }
+
+      public Request Request
+      {
+        get
+        {
+          return _request;
+        }
+        set
+        {
+          __isset.request = true;
+          this._request = value;
+        }
+      }
+
+
+      public Isset __isset;
+      #if !SILVERLIGHT
+      [Serializable]
+      #endif
+      public struct Isset {
+        public bool handle;
+        public bool request;
+      }
+
+      public execute_args() {
+      }
+
+      public void Read (TProtocol iprot)
+      {
+        iprot.IncrementRecursionDepth();
+        try
+        {
+          TField field;
+          iprot.ReadStructBegin();
+          while (true)
+          {
+            field = iprot.ReadFieldBegin();
+            if (field.Type == TType.Stop) { 
+              break;
+            }
+            switch (field.ID)
+            {
+              case 1:
+                if (field.Type == TType.Struct) {
+                  Handle = new ConnectionHandle();
+                  Handle.Read(iprot);
+                } else { 
+                  TProtocolUtil.Skip(iprot, field.Type);
+                }
+                break;
+              case 2:
+                if (field.Type == TType.Struct) {
+                  Request = new Request();
+                  Request.Read(iprot);
+                } else { 
+                  TProtocolUtil.Skip(iprot, field.Type);
+                }
+                break;
+              default: 
+                TProtocolUtil.Skip(iprot, field.Type);
+                break;
+            }
+            iprot.ReadFieldEnd();
+          }
+          iprot.ReadStructEnd();
+        }
+        finally
+        {
+          iprot.DecrementRecursionDepth();
+        }
+      }
+
+      public void Write(TProtocol oprot) {
+        oprot.IncrementRecursionDepth();
+        try
+        {
+          TStruct struc = new TStruct("execute_args");
+          oprot.WriteStructBegin(struc);
+          TField field = new TField();
+          if (Handle != null && __isset.handle) {
+            field.Name = "handle";
+            field.Type = TType.Struct;
+            field.ID = 1;
+            oprot.WriteFieldBegin(field);
+            Handle.Write(oprot);
+            oprot.WriteFieldEnd();
+          }
+          if (Request != null && __isset.request) {
+            field.Name = "request";
+            field.Type = TType.Struct;
+            field.ID = 2;
+            oprot.WriteFieldBegin(field);
+            Request.Write(oprot);
+            oprot.WriteFieldEnd();
+          }
+          oprot.WriteFieldStop();
+          oprot.WriteStructEnd();
+        }
+        finally
+        {
+          oprot.DecrementRecursionDepth();
+        }
+      }
+
+      public override string ToString() {
+        StringBuilder __sb = new StringBuilder("execute_args(");
+        bool __first = true;
+        if (Handle != null && __isset.handle) {
+          if(!__first) { __sb.Append(", "); }
+          __first = false;
+          __sb.Append("Handle: ");
+          __sb.Append(Handle== null ? "<null>" : Handle.ToString());
+        }
+        if (Request != null && __isset.request) {
+          if(!__first) { __sb.Append(", "); }
+          __first = false;
+          __sb.Append("Request: ");
+          __sb.Append(Request== null ? "<null>" : Request.ToString());
+        }
+        __sb.Append(")");
+        return __sb.ToString();
+      }
+
+    }
+
+
+    #if !SILVERLIGHT
+    [Serializable]
+    #endif
+    public partial class execute_result : TBase
+    {
+      private Response _success;
+      private PlcException _executionException;
+
+      public Response Success
+      {
+        get
+        {
+          return _success;
+        }
+        set
+        {
+          __isset.success = true;
+          this._success = value;
+        }
+      }
+
+      public PlcException ExecutionException
+      {
+        get
+        {
+          return _executionException;
+        }
+        set
+        {
+          __isset.executionException = true;
+          this._executionException = value;
+        }
+      }
+
+
+      public Isset __isset;
+      #if !SILVERLIGHT
+      [Serializable]
+      #endif
+      public struct Isset {
+        public bool success;
+        public bool executionException;
+      }
+
+      public execute_result() {
+      }
+
+      public void Read (TProtocol iprot)
+      {
+        iprot.IncrementRecursionDepth();
+        try
+        {
+          TField field;
+          iprot.ReadStructBegin();
+          while (true)
+          {
+            field = iprot.ReadFieldBegin();
+            if (field.Type == TType.Stop) { 
+              break;
+            }
+            switch (field.ID)
+            {
+              case 0:
+                if (field.Type == TType.Struct) {
+                  Success = new Response();
+                  Success.Read(iprot);
+                } else { 
+                  TProtocolUtil.Skip(iprot, field.Type);
+                }
+                break;
+              case 1:
+                if (field.Type == TType.Struct) {
+                  ExecutionException = new PlcException();
+                  ExecutionException.Read(iprot);
+                } else { 
+                  TProtocolUtil.Skip(iprot, field.Type);
+                }
+                break;
+              default: 
+                TProtocolUtil.Skip(iprot, field.Type);
+                break;
+            }
+            iprot.ReadFieldEnd();
+          }
+          iprot.ReadStructEnd();
+        }
+        finally
+        {
+          iprot.DecrementRecursionDepth();
+        }
+      }
+
+      public void Write(TProtocol oprot) {
+        oprot.IncrementRecursionDepth();
+        try
+        {
+          TStruct struc = new TStruct("execute_result");
+          oprot.WriteStructBegin(struc);
+          TField field = new TField();
+
+          if (this.__isset.success) {
+            if (Success != null) {
+              field.Name = "Success";
+              field.Type = TType.Struct;
+              field.ID = 0;
+              oprot.WriteFieldBegin(field);
+              Success.Write(oprot);
+              oprot.WriteFieldEnd();
+            }
+          } else if (this.__isset.executionException) {
+            if (ExecutionException != null) {
+              field.Name = "ExecutionException";
+              field.Type = TType.Struct;
+              field.ID = 1;
+              oprot.WriteFieldBegin(field);
+              ExecutionException.Write(oprot);
+              oprot.WriteFieldEnd();
+            }
+          }
+          oprot.WriteFieldStop();
+          oprot.WriteStructEnd();
+        }
+        finally
+        {
+          oprot.DecrementRecursionDepth();
+        }
+      }
+
+      public override string ToString() {
+        StringBuilder __sb = new StringBuilder("execute_result(");
+        bool __first = true;
+        if (Success != null && __isset.success) {
+          if(!__first) { __sb.Append(", "); }
+          __first = false;
+          __sb.Append("Success: ");
+          __sb.Append(Success== null ? "<null>" : Success.ToString());
+        }
+        if (ExecutionException != null && __isset.executionException) {
+          if(!__first) { __sb.Append(", "); }
+          __first = false;
+          __sb.Append("ExecutionException: ");
+          __sb.Append(ExecutionException== null ? "<null>" : ExecutionException.ToString());
+        }
+        __sb.Append(")");
+        return __sb.ToString();
+      }
+
+    }
+
+
+    #if !SILVERLIGHT
+    [Serializable]
+    #endif
+    public partial class close_args : TBase
+    {
+      private ConnectionHandle _handle;
+
+      public ConnectionHandle Handle
+      {
+        get
+        {
+          return _handle;
+        }
+        set
+        {
+          __isset.handle = true;
+          this._handle = value;
+        }
+      }
+
+
+      public Isset __isset;
+      #if !SILVERLIGHT
+      [Serializable]
+      #endif
+      public struct Isset {
+        public bool handle;
+      }
+
+      public close_args() {
+      }
+
+      public void Read (TProtocol iprot)
+      {
+        iprot.IncrementRecursionDepth();
+        try
+        {
+          TField field;
+          iprot.ReadStructBegin();
+          while (true)
+          {
+            field = iprot.ReadFieldBegin();
+            if (field.Type == TType.Stop) { 
+              break;
+            }
+            switch (field.ID)
+            {
+              case 1:
+                if (field.Type == TType.Struct) {
+                  Handle = new ConnectionHandle();
+                  Handle.Read(iprot);
+                } else { 
+                  TProtocolUtil.Skip(iprot, field.Type);
+                }
+                break;
+              default: 
+                TProtocolUtil.Skip(iprot, field.Type);
+                break;
+            }
+            iprot.ReadFieldEnd();
+          }
+          iprot.ReadStructEnd();
+        }
+        finally
+        {
+          iprot.DecrementRecursionDepth();
+        }
+      }
+
+      public void Write(TProtocol oprot) {
+        oprot.IncrementRecursionDepth();
+        try
+        {
+          TStruct struc = new TStruct("close_args");
+          oprot.WriteStructBegin(struc);
+          TField field = new TField();
+          if (Handle != null && __isset.handle) {
+            field.Name = "handle";
+            field.Type = TType.Struct;
+            field.ID = 1;
+            oprot.WriteFieldBegin(field);
+            Handle.Write(oprot);
+            oprot.WriteFieldEnd();
+          }
+          oprot.WriteFieldStop();
+          oprot.WriteStructEnd();
+        }
+        finally
+        {
+          oprot.DecrementRecursionDepth();
+        }
+      }
+
+      public override string ToString() {
+        StringBuilder __sb = new StringBuilder("close_args(");
+        bool __first = true;
+        if (Handle != null && __isset.handle) {
+          if(!__first) { __sb.Append(", "); }
+          __first = false;
+          __sb.Append("Handle: ");
+          __sb.Append(Handle== null ? "<null>" : Handle.ToString());
+        }
+        __sb.Append(")");
+        return __sb.ToString();
+      }
+
+    }
+
+
+    #if !SILVERLIGHT
+    [Serializable]
+    #endif
+    public partial class close_result : TBase
+    {
+
+      public close_result() {
+      }
+
+      public void Read (TProtocol iprot)
+      {
+        iprot.IncrementRecursionDepth();
+        try
+        {
+          TField field;
+          iprot.ReadStructBegin();
+          while (true)
+          {
+            field = iprot.ReadFieldBegin();
+            if (field.Type == TType.Stop) { 
+              break;
+            }
+            switch (field.ID)
+            {
+              default: 
+                TProtocolUtil.Skip(iprot, field.Type);
+                break;
+            }
+            iprot.ReadFieldEnd();
+          }
+          iprot.ReadStructEnd();
+        }
+        finally
+        {
+          iprot.DecrementRecursionDepth();
+        }
+      }
+
+      public void Write(TProtocol oprot) {
+        oprot.IncrementRecursionDepth();
+        try
+        {
+          TStruct struc = new TStruct("close_result");
+          oprot.WriteStructBegin(struc);
+
+          oprot.WriteFieldStop();
+          oprot.WriteStructEnd();
+        }
+        finally
+        {
+          oprot.DecrementRecursionDepth();
+        }
+      }
+
+      public override string ToString() {
+        StringBuilder __sb = new StringBuilder("close_result(");
+        __sb.Append(")");
+        return __sb.ToString();
+      }
+
+    }
+
+  }
+}
diff --git a/plc4j/utils/interop/src/main/thrift/gen-csharp/org/apache/plc4x/interop/PlcException.cs b/plc4j/utils/interop/src/main/thrift/gen-csharp/org/apache/plc4x/interop/PlcException.cs
new file mode 100644
index 0000000..2da263d
--- /dev/null
+++ b/plc4j/utils/interop/src/main/thrift/gen-csharp/org/apache/plc4x/interop/PlcException.cs
@@ -0,0 +1,164 @@
+/**
+ * Autogenerated by Thrift Compiler (0.12.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+using Thrift;
+using Thrift.Collections;
+using System.Runtime.Serialization;
+using Thrift.Protocol;
+using Thrift.Transport;
+
+namespace org.apache.plc4x.interop
+{
+
+  #if !SILVERLIGHT
+  [Serializable]
+  #endif
+  public partial class PlcException : TException, TBase
+  {
+    private string _url;
+    private string _exceptionString;
+
+    public string Url
+    {
+      get
+      {
+        return _url;
+      }
+      set
+      {
+        __isset.url = true;
+        this._url = value;
+      }
+    }
+
+    public string ExceptionString
+    {
+      get
+      {
+        return _exceptionString;
+      }
+      set
+      {
+        __isset.exceptionString = true;
+        this._exceptionString = value;
+      }
+    }
+
+
+    public Isset __isset;
+    #if !SILVERLIGHT
+    [Serializable]
+    #endif
+    public struct Isset {
+      public bool url;
+      public bool exceptionString;
+    }
+
+    public PlcException() {
+    }
+
+    public void Read (TProtocol iprot)
+    {
+      iprot.IncrementRecursionDepth();
+      try
+      {
+        TField field;
+        iprot.ReadStructBegin();
+        while (true)
+        {
+          field = iprot.ReadFieldBegin();
+          if (field.Type == TType.Stop) { 
+            break;
+          }
+          switch (field.ID)
+          {
+            case 1:
+              if (field.Type == TType.String) {
+                Url = iprot.ReadString();
+              } else { 
+                TProtocolUtil.Skip(iprot, field.Type);
+              }
+              break;
+            case 2:
+              if (field.Type == TType.String) {
+                ExceptionString = iprot.ReadString();
+              } else { 
+                TProtocolUtil.Skip(iprot, field.Type);
+              }
+              break;
+            default: 
+              TProtocolUtil.Skip(iprot, field.Type);
+              break;
+          }
+          iprot.ReadFieldEnd();
+        }
+        iprot.ReadStructEnd();
+      }
+      finally
+      {
+        iprot.DecrementRecursionDepth();
+      }
+    }
+
+    public void Write(TProtocol oprot) {
+      oprot.IncrementRecursionDepth();
+      try
+      {
+        TStruct struc = new TStruct("PlcException");
+        oprot.WriteStructBegin(struc);
+        TField field = new TField();
+        if (Url != null && __isset.url) {
+          field.Name = "url";
+          field.Type = TType.String;
+          field.ID = 1;
+          oprot.WriteFieldBegin(field);
+          oprot.WriteString(Url);
+          oprot.WriteFieldEnd();
+        }
+        if (ExceptionString != null && __isset.exceptionString) {
+          field.Name = "exceptionString";
+          field.Type = TType.String;
+          field.ID = 2;
+          oprot.WriteFieldBegin(field);
+          oprot.WriteString(ExceptionString);
+          oprot.WriteFieldEnd();
+        }
+        oprot.WriteFieldStop();
+        oprot.WriteStructEnd();
+      }
+      finally
+      {
+        oprot.DecrementRecursionDepth();
+      }
+    }
+
+    public override string ToString() {
+      StringBuilder __sb = new StringBuilder("PlcException(");
+      bool __first = true;
+      if (Url != null && __isset.url) {
+        if(!__first) { __sb.Append(", "); }
+        __first = false;
+        __sb.Append("Url: ");
+        __sb.Append(Url);
+      }
+      if (ExceptionString != null && __isset.exceptionString) {
+        if(!__first) { __sb.Append(", "); }
+        __first = false;
+        __sb.Append("ExceptionString: ");
+        __sb.Append(ExceptionString);
+      }
+      __sb.Append(")");
+      return __sb.ToString();
+    }
+
+  }
+
+}
diff --git a/plc4j/utils/interop/src/main/thrift/gen-csharp/org/apache/plc4x/interop/RESPONSE_CODE.cs b/plc4j/utils/interop/src/main/thrift/gen-csharp/org/apache/plc4x/interop/RESPONSE_CODE.cs
new file mode 100644
index 0000000..7fb1171
--- /dev/null
+++ b/plc4j/utils/interop/src/main/thrift/gen-csharp/org/apache/plc4x/interop/RESPONSE_CODE.cs
@@ -0,0 +1,20 @@
+/**
+ * Autogenerated by Thrift Compiler (0.12.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+
+namespace org.apache.plc4x.interop
+{
+  public enum RESPONSE_CODE
+  {
+    OK = 1,
+    NOT_FOUND = 2,
+    ACCESS_DENIED = 3,
+    INVALID_ADDRESS = 4,
+    INVALID_DATATYPE = 5,
+    INTERNAL_ERROR = 6,
+    RESPONSE_PENDING = 7,
+  }
+}
diff --git a/plc4j/utils/interop/src/main/thrift/gen-csharp/org/apache/plc4x/interop/Request.cs b/plc4j/utils/interop/src/main/thrift/gen-csharp/org/apache/plc4x/interop/Request.cs
new file mode 100644
index 0000000..6780d81
--- /dev/null
+++ b/plc4j/utils/interop/src/main/thrift/gen-csharp/org/apache/plc4x/interop/Request.cs
@@ -0,0 +1,148 @@
+/**
+ * Autogenerated by Thrift Compiler (0.12.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+using Thrift;
+using Thrift.Collections;
+using System.Runtime.Serialization;
+using Thrift.Protocol;
+using Thrift.Transport;
+
+namespace org.apache.plc4x.interop
+{
+
+  #if !SILVERLIGHT
+  [Serializable]
+  #endif
+  public partial class Request : TBase
+  {
+    private Dictionary<string, string> _fields;
+
+    public Dictionary<string, string> Fields
+    {
+      get
+      {
+        return _fields;
+      }
+      set
+      {
+        __isset.fields = true;
+        this._fields = value;
+      }
+    }
+
+
+    public Isset __isset;
+    #if !SILVERLIGHT
+    [Serializable]
+    #endif
+    public struct Isset {
+      public bool fields;
+    }
+
+    public Request() {
+    }
+
+    public void Read (TProtocol iprot)
+    {
+      iprot.IncrementRecursionDepth();
+      try
+      {
+        TField field;
+        iprot.ReadStructBegin();
+        while (true)
+        {
+          field = iprot.ReadFieldBegin();
+          if (field.Type == TType.Stop) { 
+            break;
+          }
+          switch (field.ID)
+          {
+            case 1:
+              if (field.Type == TType.Map) {
+                {
+                  Fields = new Dictionary<string, string>();
+                  TMap _map0 = iprot.ReadMapBegin();
+                  for( int _i1 = 0; _i1 < _map0.Count; ++_i1)
+                  {
+                    string _key2;
+                    string _val3;
+                    _key2 = iprot.ReadString();
+                    _val3 = iprot.ReadString();
+                    Fields[_key2] = _val3;
+                  }
+                  iprot.ReadMapEnd();
+                }
+              } else { 
+                TProtocolUtil.Skip(iprot, field.Type);
+              }
+              break;
+            default: 
+              TProtocolUtil.Skip(iprot, field.Type);
+              break;
+          }
+          iprot.ReadFieldEnd();
+        }
+        iprot.ReadStructEnd();
+      }
+      finally
+      {
+        iprot.DecrementRecursionDepth();
+      }
+    }
+
+    public void Write(TProtocol oprot) {
+      oprot.IncrementRecursionDepth();
+      try
+      {
+        TStruct struc = new TStruct("Request");
+        oprot.WriteStructBegin(struc);
+        TField field = new TField();
+        if (Fields != null && __isset.fields) {
+          field.Name = "fields";
+          field.Type = TType.Map;
+          field.ID = 1;
+          oprot.WriteFieldBegin(field);
+          {
+            oprot.WriteMapBegin(new TMap(TType.String, TType.String, Fields.Count));
+            foreach (string _iter4 in Fields.Keys)
+            {
+              oprot.WriteString(_iter4);
+              oprot.WriteString(Fields[_iter4]);
+            }
+            oprot.WriteMapEnd();
+          }
+          oprot.WriteFieldEnd();
+        }
+        oprot.WriteFieldStop();
+        oprot.WriteStructEnd();
+      }
+      finally
+      {
+        oprot.DecrementRecursionDepth();
+      }
+    }
+
+    public override string ToString() {
+      StringBuilder __sb = new StringBuilder("Request(");
+      bool __first = true;
+      if (Fields != null && __isset.fields) {
+        if(!__first) { __sb.Append(", "); }
+        __first = false;
+        __sb.Append("Fields: ");
+        __sb.Append(Fields);
+      }
+      __sb.Append(")");
+      return __sb.ToString();
+    }
+
+  }
+
+}
diff --git a/plc4j/utils/interop/src/main/thrift/gen-csharp/org/apache/plc4x/interop/Response.cs b/plc4j/utils/interop/src/main/thrift/gen-csharp/org/apache/plc4x/interop/Response.cs
new file mode 100644
index 0000000..891d278
--- /dev/null
+++ b/plc4j/utils/interop/src/main/thrift/gen-csharp/org/apache/plc4x/interop/Response.cs
@@ -0,0 +1,149 @@
+/**
+ * Autogenerated by Thrift Compiler (0.12.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+using Thrift;
+using Thrift.Collections;
+using System.Runtime.Serialization;
+using Thrift.Protocol;
+using Thrift.Transport;
+
+namespace org.apache.plc4x.interop
+{
+
+  #if !SILVERLIGHT
+  [Serializable]
+  #endif
+  public partial class Response : TBase
+  {
+    private Dictionary<string, FieldResponse> _fields;
+
+    public Dictionary<string, FieldResponse> Fields
+    {
+      get
+      {
+        return _fields;
+      }
+      set
+      {
+        __isset.fields = true;
+        this._fields = value;
+      }
+    }
+
+
+    public Isset __isset;
+    #if !SILVERLIGHT
+    [Serializable]
+    #endif
+    public struct Isset {
+      public bool fields;
+    }
+
+    public Response() {
+    }
+
+    public void Read (TProtocol iprot)
+    {
+      iprot.IncrementRecursionDepth();
+      try
+      {
+        TField field;
+        iprot.ReadStructBegin();
+        while (true)
+        {
+          field = iprot.ReadFieldBegin();
+          if (field.Type == TType.Stop) { 
+            break;
+          }
+          switch (field.ID)
+          {
+            case 1:
+              if (field.Type == TType.Map) {
+                {
+                  Fields = new Dictionary<string, FieldResponse>();
+                  TMap _map5 = iprot.ReadMapBegin();
+                  for( int _i6 = 0; _i6 < _map5.Count; ++_i6)
+                  {
+                    string _key7;
+                    FieldResponse _val8;
+                    _key7 = iprot.ReadString();
+                    _val8 = new FieldResponse();
+                    _val8.Read(iprot);
+                    Fields[_key7] = _val8;
+                  }
+                  iprot.ReadMapEnd();
+                }
+              } else { 
+                TProtocolUtil.Skip(iprot, field.Type);
+              }
+              break;
+            default: 
+              TProtocolUtil.Skip(iprot, field.Type);
+              break;
+          }
+          iprot.ReadFieldEnd();
+        }
+        iprot.ReadStructEnd();
+      }
+      finally
+      {
+        iprot.DecrementRecursionDepth();
+      }
+    }
+
+    public void Write(TProtocol oprot) {
+      oprot.IncrementRecursionDepth();
+      try
+      {
+        TStruct struc = new TStruct("Response");
+        oprot.WriteStructBegin(struc);
+        TField field = new TField();
+        if (Fields != null && __isset.fields) {
+          field.Name = "fields";
+          field.Type = TType.Map;
+          field.ID = 1;
+          oprot.WriteFieldBegin(field);
+          {
+            oprot.WriteMapBegin(new TMap(TType.String, TType.Struct, Fields.Count));
+            foreach (string _iter9 in Fields.Keys)
+            {
+              oprot.WriteString(_iter9);
+              Fields[_iter9].Write(oprot);
+            }
+            oprot.WriteMapEnd();
+          }
+          oprot.WriteFieldEnd();
+        }
+        oprot.WriteFieldStop();
+        oprot.WriteStructEnd();
+      }
+      finally
+      {
+        oprot.DecrementRecursionDepth();
+      }
+    }
+
+    public override string ToString() {
+      StringBuilder __sb = new StringBuilder("Response(");
+      bool __first = true;
+      if (Fields != null && __isset.fields) {
+        if(!__first) { __sb.Append(", "); }
+        __first = false;
+        __sb.Append("Fields: ");
+        __sb.Append(Fields);
+      }
+      __sb.Append(")");
+      return __sb.ToString();
+    }
+
+  }
+
+}
diff --git a/plc4j/utils/interop/src/main/thrift/gen-java/org/apache/plc4x/interop/ConnectionHandle.java b/plc4j/utils/interop/src/main/thrift/gen-java/org/apache/plc4x/interop/ConnectionHandle.java
new file mode 100644
index 0000000..f500c3d
--- /dev/null
+++ b/plc4j/utils/interop/src/main/thrift/gen-java/org/apache/plc4x/interop/ConnectionHandle.java
@@ -0,0 +1,372 @@
+/**
+ * Autogenerated by Thrift Compiler (0.12.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+package org.apache.plc4x.interop;
+
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.12.0)", date = "2019-04-14")
+public class ConnectionHandle implements org.apache.thrift.TBase<ConnectionHandle, ConnectionHandle._Fields>, java.io.Serializable, Cloneable, Comparable<ConnectionHandle> {
+  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("ConnectionHandle");
+
+  private static final org.apache.thrift.protocol.TField CONNECTION_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("connectionId", org.apache.thrift.protocol.TType.I64, (short)1);
+
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new ConnectionHandleStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new ConnectionHandleTupleSchemeFactory();
+
+  public long connectionId; // required
+
+  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+    CONNECTION_ID((short)1, "connectionId");
+
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
+
+    static {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
+        byName.put(field.getFieldName(), field);
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, or null if its not found.
+     */
+    @org.apache.thrift.annotation.Nullable
+    public static _Fields findByThriftId(int fieldId) {
+      switch(fieldId) {
+        case 1: // CONNECTION_ID
+          return CONNECTION_ID;
+        default:
+          return null;
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, throwing an exception
+     * if it is not found.
+     */
+    public static _Fields findByThriftIdOrThrow(int fieldId) {
+      _Fields fields = findByThriftId(fieldId);
+      if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      return fields;
+    }
+
+    /**
+     * Find the _Fields constant that matches name, or null if its not found.
+     */
+    @org.apache.thrift.annotation.Nullable
+    public static _Fields findByName(java.lang.String name) {
+      return byName.get(name);
+    }
+
+    private final short _thriftId;
+    private final java.lang.String _fieldName;
+
+    _Fields(short thriftId, java.lang.String fieldName) {
+      _thriftId = thriftId;
+      _fieldName = fieldName;
+    }
+
+    public short getThriftFieldId() {
+      return _thriftId;
+    }
+
+    public java.lang.String getFieldName() {
+      return _fieldName;
+    }
+  }
+
+  // isset id assignments
+  private static final int __CONNECTIONID_ISSET_ID = 0;
+  private byte __isset_bitfield = 0;
+  public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  static {
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+    tmpMap.put(_Fields.CONNECTION_ID, new org.apache.thrift.meta_data.FieldMetaData("connectionId", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(ConnectionHandle.class, metaDataMap);
+  }
+
+  public ConnectionHandle() {
+  }
+
+  public ConnectionHandle(
+    long connectionId)
+  {
+    this();
+    this.connectionId = connectionId;
+    setConnectionIdIsSet(true);
+  }
+
+  /**
+   * Performs a deep copy on <i>other</i>.
+   */
+  public ConnectionHandle(ConnectionHandle other) {
+    __isset_bitfield = other.__isset_bitfield;
+    this.connectionId = other.connectionId;
+  }
+
+  public ConnectionHandle deepCopy() {
+    return new ConnectionHandle(this);
+  }
+
+  @Override
+  public void clear() {
+    setConnectionIdIsSet(false);
+    this.connectionId = 0;
+  }
+
+  public long getConnectionId() {
+    return this.connectionId;
+  }
+
+  public ConnectionHandle setConnectionId(long connectionId) {
+    this.connectionId = connectionId;
+    setConnectionIdIsSet(true);
+    return this;
+  }
+
+  public void unsetConnectionId() {
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __CONNECTIONID_ISSET_ID);
+  }
+
+  /** Returns true if field connectionId is set (has been assigned a value) and false otherwise */
+  public boolean isSetConnectionId() {
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __CONNECTIONID_ISSET_ID);
+  }
+
+  public void setConnectionIdIsSet(boolean value) {
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __CONNECTIONID_ISSET_ID, value);
+  }
+
+  public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) {
+    switch (field) {
+    case CONNECTION_ID:
+      if (value == null) {
+        unsetConnectionId();
+      } else {
+        setConnectionId((java.lang.Long)value);
+      }
+      break;
+
+    }
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public java.lang.Object getFieldValue(_Fields field) {
+    switch (field) {
+    case CONNECTION_ID:
+      return getConnectionId();
+
+    }
+    throw new java.lang.IllegalStateException();
+  }
+
+  /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+  public boolean isSet(_Fields field) {
+    if (field == null) {
+      throw new java.lang.IllegalArgumentException();
+    }
+
+    switch (field) {
+    case CONNECTION_ID:
+      return isSetConnectionId();
+    }
+    throw new java.lang.IllegalStateException();
+  }
+
+  @Override
+  public boolean equals(java.lang.Object that) {
+    if (that == null)
+      return false;
+    if (that instanceof ConnectionHandle)
+      return this.equals((ConnectionHandle)that);
+    return false;
+  }
+
+  public boolean equals(ConnectionHandle that) {
+    if (that == null)
+      return false;
+    if (this == that)
+      return true;
+
+    boolean this_present_connectionId = true;
+    boolean that_present_connectionId = true;
+    if (this_present_connectionId || that_present_connectionId) {
+      if (!(this_present_connectionId && that_present_connectionId))
+        return false;
+      if (this.connectionId != that.connectionId)
+        return false;
+    }
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int hashCode = 1;
+
+    hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(connectionId);
+
+    return hashCode;
+  }
+
+  @Override
+  public int compareTo(ConnectionHandle other) {
+    if (!getClass().equals(other.getClass())) {
+      return getClass().getName().compareTo(other.getClass().getName());
+    }
+
+    int lastComparison = 0;
+
+    lastComparison = java.lang.Boolean.valueOf(isSetConnectionId()).compareTo(other.isSetConnectionId());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetConnectionId()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.connectionId, other.connectionId);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    return 0;
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public _Fields fieldForId(int fieldId) {
+    return _Fields.findByThriftId(fieldId);
+  }
+
+  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+    scheme(iprot).read(iprot, this);
+  }
+
+  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+    scheme(oprot).write(oprot, this);
+  }
+
+  @Override
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("ConnectionHandle(");
+    boolean first = true;
+
+    sb.append("connectionId:");
+    sb.append(this.connectionId);
+    first = false;
+    sb.append(")");
+    return sb.toString();
+  }
+
+  public void validate() throws org.apache.thrift.TException {
+    // check for required fields
+    // check for sub-struct validity
+  }
+
+  private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+    try {
+      write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
+    try {
+      // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
+      __isset_bitfield = 0;
+      read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private static class ConnectionHandleStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+    public ConnectionHandleStandardScheme getScheme() {
+      return new ConnectionHandleStandardScheme();
+    }
+  }
+
+  private static class ConnectionHandleStandardScheme extends org.apache.thrift.scheme.StandardScheme<ConnectionHandle> {
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot, ConnectionHandle struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TField schemeField;
+      iprot.readStructBegin();
+      while (true)
+      {
+        schemeField = iprot.readFieldBegin();
+        if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+          break;
+        }
+        switch (schemeField.id) {
+          case 1: // CONNECTION_ID
+            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
+              struct.connectionId = iprot.readI64();
+              struct.setConnectionIdIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          default:
+            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+        }
+        iprot.readFieldEnd();
+      }
+      iprot.readStructEnd();
+
+      // check for required fields of primitive type, which can't be checked in the validate method
+      struct.validate();
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot, ConnectionHandle struct) throws org.apache.thrift.TException {
+      struct.validate();
+
+      oprot.writeStructBegin(STRUCT_DESC);
+      oprot.writeFieldBegin(CONNECTION_ID_FIELD_DESC);
+      oprot.writeI64(struct.connectionId);
+      oprot.writeFieldEnd();
+      oprot.writeFieldStop();
+      oprot.writeStructEnd();
+    }
+
+  }
+
+  private static class ConnectionHandleTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+    public ConnectionHandleTupleScheme getScheme() {
+      return new ConnectionHandleTupleScheme();
+    }
+  }
+
+  private static class ConnectionHandleTupleScheme extends org.apache.thrift.scheme.TupleScheme<ConnectionHandle> {
+
+    @Override
+    public void write(org.apache.thrift.protocol.TProtocol prot, ConnectionHandle struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
+      if (struct.isSetConnectionId()) {
+        optionals.set(0);
+      }
+      oprot.writeBitSet(optionals, 1);
+      if (struct.isSetConnectionId()) {
+        oprot.writeI64(struct.connectionId);
+      }
+    }
+
+    @Override
+    public void read(org.apache.thrift.protocol.TProtocol prot, ConnectionHandle struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(1);
+      if (incoming.get(0)) {
+        struct.connectionId = iprot.readI64();
+        struct.setConnectionIdIsSet(true);
+      }
+    }
+  }
+
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+}
+
diff --git a/plc4j/utils/interop/src/main/thrift/gen-java/org/apache/plc4x/interop/FieldResponse.java b/plc4j/utils/interop/src/main/thrift/gen-java/org/apache/plc4x/interop/FieldResponse.java
new file mode 100644
index 0000000..01d615e
--- /dev/null
+++ b/plc4j/utils/interop/src/main/thrift/gen-java/org/apache/plc4x/interop/FieldResponse.java
@@ -0,0 +1,802 @@
+/**
+ * Autogenerated by Thrift Compiler (0.12.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+package org.apache.plc4x.interop;
+
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.12.0)", date = "2019-04-14")
+public class FieldResponse implements org.apache.thrift.TBase<FieldResponse, FieldResponse._Fields>, java.io.Serializable, Cloneable, Comparable<FieldResponse> {
+  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("FieldResponse");
+
+  private static final org.apache.thrift.protocol.TField RESPONSE_CODE_FIELD_DESC = new org.apache.thrift.protocol.TField("responseCode", org.apache.thrift.protocol.TType.I32, (short)1);
+  private static final org.apache.thrift.protocol.TField BOOL_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("boolValue", org.apache.thrift.protocol.TType.BOOL, (short)2);
+  private static final org.apache.thrift.protocol.TField LONG_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("longValue", org.apache.thrift.protocol.TType.I64, (short)3);
+  private static final org.apache.thrift.protocol.TField DOUBLE_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("doubleValue", org.apache.thrift.protocol.TType.DOUBLE, (short)4);
+  private static final org.apache.thrift.protocol.TField STRING_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("stringValue", org.apache.thrift.protocol.TType.STRING, (short)5);
+
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new FieldResponseStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new FieldResponseTupleSchemeFactory();
+
+  /**
+   * 
+   * @see RESPONSE_CODE
+   */
+  public @org.apache.thrift.annotation.Nullable RESPONSE_CODE responseCode; // required
+  public boolean boolValue; // optional
+  public long longValue; // optional
+  public double doubleValue; // optional
+  public @org.apache.thrift.annotation.Nullable java.lang.String stringValue; // optional
+
+  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+    /**
+     * 
+     * @see RESPONSE_CODE
+     */
+    RESPONSE_CODE((short)1, "responseCode"),
+    BOOL_VALUE((short)2, "boolValue"),
+    LONG_VALUE((short)3, "longValue"),
+    DOUBLE_VALUE((short)4, "doubleValue"),
+    STRING_VALUE((short)5, "stringValue");
+
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
+
+    static {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
+        byName.put(field.getFieldName(), field);
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, or null if its not found.
+     */
+    @org.apache.thrift.annotation.Nullable
+    public static _Fields findByThriftId(int fieldId) {
+      switch(fieldId) {
+        case 1: // RESPONSE_CODE
+          return RESPONSE_CODE;
+        case 2: // BOOL_VALUE
+          return BOOL_VALUE;
+        case 3: // LONG_VALUE
+          return LONG_VALUE;
+        case 4: // DOUBLE_VALUE
+          return DOUBLE_VALUE;
+        case 5: // STRING_VALUE
+          return STRING_VALUE;
+        default:
+          return null;
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, throwing an exception
+     * if it is not found.
+     */
+    public static _Fields findByThriftIdOrThrow(int fieldId) {
+      _Fields fields = findByThriftId(fieldId);
+      if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      return fields;
+    }
+
+    /**
+     * Find the _Fields constant that matches name, or null if its not found.
+     */
+    @org.apache.thrift.annotation.Nullable
+    public static _Fields findByName(java.lang.String name) {
+      return byName.get(name);
+    }
+
+    private final short _thriftId;
+    private final java.lang.String _fieldName;
+
+    _Fields(short thriftId, java.lang.String fieldName) {
+      _thriftId = thriftId;
+      _fieldName = fieldName;
+    }
+
+    public short getThriftFieldId() {
+      return _thriftId;
+    }
+
+    public java.lang.String getFieldName() {
+      return _fieldName;
+    }
+  }
+
+  // isset id assignments
+  private static final int __BOOLVALUE_ISSET_ID = 0;
+  private static final int __LONGVALUE_ISSET_ID = 1;
+  private static final int __DOUBLEVALUE_ISSET_ID = 2;
+  private byte __isset_bitfield = 0;
+  private static final _Fields optionals[] = {_Fields.BOOL_VALUE,_Fields.LONG_VALUE,_Fields.DOUBLE_VALUE,_Fields.STRING_VALUE};
+  public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  static {
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+    tmpMap.put(_Fields.RESPONSE_CODE, new org.apache.thrift.meta_data.FieldMetaData("responseCode", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+        new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, RESPONSE_CODE.class)));
+    tmpMap.put(_Fields.BOOL_VALUE, new org.apache.thrift.meta_data.FieldMetaData("boolValue", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
+    tmpMap.put(_Fields.LONG_VALUE, new org.apache.thrift.meta_data.FieldMetaData("longValue", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
+    tmpMap.put(_Fields.DOUBLE_VALUE, new org.apache.thrift.meta_data.FieldMetaData("doubleValue", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.DOUBLE)));
+    tmpMap.put(_Fields.STRING_VALUE, new org.apache.thrift.meta_data.FieldMetaData("stringValue", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(FieldResponse.class, metaDataMap);
+  }
+
+  public FieldResponse() {
+  }
+
+  public FieldResponse(
+    RESPONSE_CODE responseCode)
+  {
+    this();
+    this.responseCode = responseCode;
+  }
+
+  /**
+   * Performs a deep copy on <i>other</i>.
+   */
+  public FieldResponse(FieldResponse other) {
+    __isset_bitfield = other.__isset_bitfield;
+    if (other.isSetResponseCode()) {
+      this.responseCode = other.responseCode;
+    }
+    this.boolValue = other.boolValue;
+    this.longValue = other.longValue;
+    this.doubleValue = other.doubleValue;
+    if (other.isSetStringValue()) {
+      this.stringValue = other.stringValue;
+    }
+  }
+
+  public FieldResponse deepCopy() {
+    return new FieldResponse(this);
+  }
+
+  @Override
+  public void clear() {
+    this.responseCode = null;
+    setBoolValueIsSet(false);
+    this.boolValue = false;
+    setLongValueIsSet(false);
+    this.longValue = 0;
+    setDoubleValueIsSet(false);
+    this.doubleValue = 0.0;
+    this.stringValue = null;
+  }
+
+  /**
+   * 
+   * @see RESPONSE_CODE
+   */
+  @org.apache.thrift.annotation.Nullable
+  public RESPONSE_CODE getResponseCode() {
+    return this.responseCode;
+  }
+
+  /**
+   * 
+   * @see RESPONSE_CODE
+   */
+  public FieldResponse setResponseCode(@org.apache.thrift.annotation.Nullable RESPONSE_CODE responseCode) {
+    this.responseCode = responseCode;
+    return this;
+  }
+
+  public void unsetResponseCode() {
+    this.responseCode = null;
+  }
+
+  /** Returns true if field responseCode is set (has been assigned a value) and false otherwise */
+  public boolean isSetResponseCode() {
+    return this.responseCode != null;
+  }
+
+  public void setResponseCodeIsSet(boolean value) {
+    if (!value) {
+      this.responseCode = null;
+    }
+  }
+
+  public boolean isBoolValue() {
+    return this.boolValue;
+  }
+
+  public FieldResponse setBoolValue(boolean boolValue) {
+    this.boolValue = boolValue;
+    setBoolValueIsSet(true);
+    return this;
+  }
+
+  public void unsetBoolValue() {
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __BOOLVALUE_ISSET_ID);
+  }
+
+  /** Returns true if field boolValue is set (has been assigned a value) and false otherwise */
+  public boolean isSetBoolValue() {
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __BOOLVALUE_ISSET_ID);
+  }
+
+  public void setBoolValueIsSet(boolean value) {
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __BOOLVALUE_ISSET_ID, value);
+  }
+
+  public long getLongValue() {
+    return this.longValue;
+  }
+
+  public FieldResponse setLongValue(long longValue) {
+    this.longValue = longValue;
+    setLongValueIsSet(true);
+    return this;
+  }
+
+  public void unsetLongValue() {
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __LONGVALUE_ISSET_ID);
+  }
+
+  /** Returns true if field longValue is set (has been assigned a value) and false otherwise */
+  public boolean isSetLongValue() {
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __LONGVALUE_ISSET_ID);
+  }
+
+  public void setLongValueIsSet(boolean value) {
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __LONGVALUE_ISSET_ID, value);
+  }
+
+  public double getDoubleValue() {
+    return this.doubleValue;
+  }
+
+  public FieldResponse setDoubleValue(double doubleValue) {
+    this.doubleValue = doubleValue;
+    setDoubleValueIsSet(true);
+    return this;
+  }
+
+  public void unsetDoubleValue() {
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __DOUBLEVALUE_ISSET_ID);
+  }
+
+  /** Returns true if field doubleValue is set (has been assigned a value) and false otherwise */
+  public boolean isSetDoubleValue() {
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __DOUBLEVALUE_ISSET_ID);
+  }
+
+  public void setDoubleValueIsSet(boolean value) {
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __DOUBLEVALUE_ISSET_ID, value);
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public java.lang.String getStringValue() {
+    return this.stringValue;
+  }
+
+  public FieldResponse setStringValue(@org.apache.thrift.annotation.Nullable java.lang.String stringValue) {
+    this.stringValue = stringValue;
+    return this;
+  }
+
+  public void unsetStringValue() {
+    this.stringValue = null;
+  }
+
+  /** Returns true if field stringValue is set (has been assigned a value) and false otherwise */
+  public boolean isSetStringValue() {
+    return this.stringValue != null;
+  }
+
+  public void setStringValueIsSet(boolean value) {
+    if (!value) {
+      this.stringValue = null;
+    }
+  }
+
+  public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) {
+    switch (field) {
+    case RESPONSE_CODE:
+      if (value == null) {
+        unsetResponseCode();
+      } else {
+        setResponseCode((RESPONSE_CODE)value);
+      }
+      break;
+
+    case BOOL_VALUE:
+      if (value == null) {
+        unsetBoolValue();
+      } else {
+        setBoolValue((java.lang.Boolean)value);
+      }
+      break;
+
+    case LONG_VALUE:
+      if (value == null) {
+        unsetLongValue();
+      } else {
+        setLongValue((java.lang.Long)value);
+      }
+      break;
+
+    case DOUBLE_VALUE:
+      if (value == null) {
+        unsetDoubleValue();
+      } else {
+        setDoubleValue((java.lang.Double)value);
+      }
+      break;
+
+    case STRING_VALUE:
+      if (value == null) {
+        unsetStringValue();
+      } else {
+        setStringValue((java.lang.String)value);
+      }
+      break;
+
+    }
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public java.lang.Object getFieldValue(_Fields field) {
+    switch (field) {
+    case RESPONSE_CODE:
+      return getResponseCode();
+
+    case BOOL_VALUE:
+      return isBoolValue();
+
+    case LONG_VALUE:
+      return getLongValue();
+
+    case DOUBLE_VALUE:
+      return getDoubleValue();
+
+    case STRING_VALUE:
+      return getStringValue();
+
+    }
+    throw new java.lang.IllegalStateException();
+  }
+
+  /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+  public boolean isSet(_Fields field) {
+    if (field == null) {
+      throw new java.lang.IllegalArgumentException();
+    }
+
+    switch (field) {
+    case RESPONSE_CODE:
+      return isSetResponseCode();
+    case BOOL_VALUE:
+      return isSetBoolValue();
+    case LONG_VALUE:
+      return isSetLongValue();
+    case DOUBLE_VALUE:
+      return isSetDoubleValue();
+    case STRING_VALUE:
+      return isSetStringValue();
+    }
+    throw new java.lang.IllegalStateException();
+  }
+
+  @Override
+  public boolean equals(java.lang.Object that) {
+    if (that == null)
+      return false;
+    if (that instanceof FieldResponse)
+      return this.equals((FieldResponse)that);
+    return false;
+  }
+
+  public boolean equals(FieldResponse that) {
+    if (that == null)
+      return false;
+    if (this == that)
+      return true;
+
+    boolean this_present_responseCode = true && this.isSetResponseCode();
+    boolean that_present_responseCode = true && that.isSetResponseCode();
+    if (this_present_responseCode || that_present_responseCode) {
+      if (!(this_present_responseCode && that_present_responseCode))
+        return false;
+      if (!this.responseCode.equals(that.responseCode))
+        return false;
+    }
+
+    boolean this_present_boolValue = true && this.isSetBoolValue();
+    boolean that_present_boolValue = true && that.isSetBoolValue();
+    if (this_present_boolValue || that_present_boolValue) {
+      if (!(this_present_boolValue && that_present_boolValue))
+        return false;
+      if (this.boolValue != that.boolValue)
+        return false;
+    }
+
+    boolean this_present_longValue = true && this.isSetLongValue();
+    boolean that_present_longValue = true && that.isSetLongValue();
+    if (this_present_longValue || that_present_longValue) {
+      if (!(this_present_longValue && that_present_longValue))
+        return false;
+      if (this.longValue != that.longValue)
+        return false;
+    }
+
+    boolean this_present_doubleValue = true && this.isSetDoubleValue();
+    boolean that_present_doubleValue = true && that.isSetDoubleValue();
+    if (this_present_doubleValue || that_present_doubleValue) {
+      if (!(this_present_doubleValue && that_present_doubleValue))
+        return false;
+      if (this.doubleValue != that.doubleValue)
+        return false;
+    }
+
+    boolean this_present_stringValue = true && this.isSetStringValue();
+    boolean that_present_stringValue = true && that.isSetStringValue();
+    if (this_present_stringValue || that_present_stringValue) {
+      if (!(this_present_stringValue && that_present_stringValue))
+        return false;
+      if (!this.stringValue.equals(that.stringValue))
+        return false;
+    }
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int hashCode = 1;
+
+    hashCode = hashCode * 8191 + ((isSetResponseCode()) ? 131071 : 524287);
+    if (isSetResponseCode())
+      hashCode = hashCode * 8191 + responseCode.getValue();
+
+    hashCode = hashCode * 8191 + ((isSetBoolValue()) ? 131071 : 524287);
+    if (isSetBoolValue())
+      hashCode = hashCode * 8191 + ((boolValue) ? 131071 : 524287);
+
+    hashCode = hashCode * 8191 + ((isSetLongValue()) ? 131071 : 524287);
+    if (isSetLongValue())
+      hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(longValue);
+
+    hashCode = hashCode * 8191 + ((isSetDoubleValue()) ? 131071 : 524287);
+    if (isSetDoubleValue())
+      hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(doubleValue);
+
+    hashCode = hashCode * 8191 + ((isSetStringValue()) ? 131071 : 524287);
+    if (isSetStringValue())
+      hashCode = hashCode * 8191 + stringValue.hashCode();
+
+    return hashCode;
+  }
+
+  @Override
+  public int compareTo(FieldResponse other) {
+    if (!getClass().equals(other.getClass())) {
+      return getClass().getName().compareTo(other.getClass().getName());
+    }
+
+    int lastComparison = 0;
+
+    lastComparison = java.lang.Boolean.valueOf(isSetResponseCode()).compareTo(other.isSetResponseCode());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetResponseCode()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.responseCode, other.responseCode);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    lastComparison = java.lang.Boolean.valueOf(isSetBoolValue()).compareTo(other.isSetBoolValue());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetBoolValue()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.boolValue, other.boolValue);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    lastComparison = java.lang.Boolean.valueOf(isSetLongValue()).compareTo(other.isSetLongValue());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetLongValue()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.longValue, other.longValue);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    lastComparison = java.lang.Boolean.valueOf(isSetDoubleValue()).compareTo(other.isSetDoubleValue());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetDoubleValue()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.doubleValue, other.doubleValue);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    lastComparison = java.lang.Boolean.valueOf(isSetStringValue()).compareTo(other.isSetStringValue());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetStringValue()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.stringValue, other.stringValue);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    return 0;
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public _Fields fieldForId(int fieldId) {
+    return _Fields.findByThriftId(fieldId);
+  }
+
+  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+    scheme(iprot).read(iprot, this);
+  }
+
+  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+    scheme(oprot).write(oprot, this);
+  }
+
+  @Override
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("FieldResponse(");
+    boolean first = true;
+
+    sb.append("responseCode:");
+    if (this.responseCode == null) {
+      sb.append("null");
+    } else {
+      sb.append(this.responseCode);
+    }
+    first = false;
+    if (isSetBoolValue()) {
+      if (!first) sb.append(", ");
+      sb.append("boolValue:");
+      sb.append(this.boolValue);
+      first = false;
+    }
+    if (isSetLongValue()) {
+      if (!first) sb.append(", ");
+      sb.append("longValue:");
+      sb.append(this.longValue);
+      first = false;
+    }
+    if (isSetDoubleValue()) {
+      if (!first) sb.append(", ");
+      sb.append("doubleValue:");
+      sb.append(this.doubleValue);
+      first = false;
+    }
+    if (isSetStringValue()) {
+      if (!first) sb.append(", ");
+      sb.append("stringValue:");
+      if (this.stringValue == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.stringValue);
+      }
+      first = false;
+    }
+    sb.append(")");
+    return sb.toString();
+  }
+
+  public void validate() throws org.apache.thrift.TException {
+    // check for required fields
+    // check for sub-struct validity
+  }
+
+  private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+    try {
+      write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
+    try {
+      // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
+      __isset_bitfield = 0;
+      read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private static class FieldResponseStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+    public FieldResponseStandardScheme getScheme() {
+      return new FieldResponseStandardScheme();
+    }
+  }
+
+  private static class FieldResponseStandardScheme extends org.apache.thrift.scheme.StandardScheme<FieldResponse> {
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot, FieldResponse struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TField schemeField;
+      iprot.readStructBegin();
+      while (true)
+      {
+        schemeField = iprot.readFieldBegin();
+        if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+          break;
+        }
+        switch (schemeField.id) {
+          case 1: // RESPONSE_CODE
+            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+              struct.responseCode = org.apache.plc4x.interop.RESPONSE_CODE.findByValue(iprot.readI32());
+              struct.setResponseCodeIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          case 2: // BOOL_VALUE
+            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
+              struct.boolValue = iprot.readBool();
+              struct.setBoolValueIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          case 3: // LONG_VALUE
+            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
+              struct.longValue = iprot.readI64();
+              struct.setLongValueIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          case 4: // DOUBLE_VALUE
+            if (schemeField.type == org.apache.thrift.protocol.TType.DOUBLE) {
+              struct.doubleValue = iprot.readDouble();
+              struct.setDoubleValueIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          case 5: // STRING_VALUE
+            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+              struct.stringValue = iprot.readString();
+              struct.setStringValueIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          default:
+            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+        }
+        iprot.readFieldEnd();
+      }
+      iprot.readStructEnd();
+
+      // check for required fields of primitive type, which can't be checked in the validate method
+      struct.validate();
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot, FieldResponse struct) throws org.apache.thrift.TException {
+      struct.validate();
+
+      oprot.writeStructBegin(STRUCT_DESC);
+      if (struct.responseCode != null) {
+        oprot.writeFieldBegin(RESPONSE_CODE_FIELD_DESC);
+        oprot.writeI32(struct.responseCode.getValue());
+        oprot.writeFieldEnd();
+      }
+      if (struct.isSetBoolValue()) {
+        oprot.writeFieldBegin(BOOL_VALUE_FIELD_DESC);
+        oprot.writeBool(struct.boolValue);
+        oprot.writeFieldEnd();
+      }
+      if (struct.isSetLongValue()) {
+        oprot.writeFieldBegin(LONG_VALUE_FIELD_DESC);
+        oprot.writeI64(struct.longValue);
+        oprot.writeFieldEnd();
+      }
+      if (struct.isSetDoubleValue()) {
+        oprot.writeFieldBegin(DOUBLE_VALUE_FIELD_DESC);
+        oprot.writeDouble(struct.doubleValue);
+        oprot.writeFieldEnd();
+      }
+      if (struct.stringValue != null) {
+        if (struct.isSetStringValue()) {
+          oprot.writeFieldBegin(STRING_VALUE_FIELD_DESC);
+          oprot.writeString(struct.stringValue);
+          oprot.writeFieldEnd();
+        }
+      }
+      oprot.writeFieldStop();
+      oprot.writeStructEnd();
+    }
+
+  }
+
+  private static class FieldResponseTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+    public FieldResponseTupleScheme getScheme() {
+      return new FieldResponseTupleScheme();
+    }
+  }
+
+  private static class FieldResponseTupleScheme extends org.apache.thrift.scheme.TupleScheme<FieldResponse> {
+
+    @Override
+    public void write(org.apache.thrift.protocol.TProtocol prot, FieldResponse struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
+      if (struct.isSetResponseCode()) {
+        optionals.set(0);
+      }
+      if (struct.isSetBoolValue()) {
+        optionals.set(1);
+      }
+      if (struct.isSetLongValue()) {
+        optionals.set(2);
+      }
+      if (struct.isSetDoubleValue()) {
+        optionals.set(3);
+      }
+      if (struct.isSetStringValue()) {
+        optionals.set(4);
+      }
+      oprot.writeBitSet(optionals, 5);
+      if (struct.isSetResponseCode()) {
+        oprot.writeI32(struct.responseCode.getValue());
+      }
+      if (struct.isSetBoolValue()) {
+        oprot.writeBool(struct.boolValue);
+      }
+      if (struct.isSetLongValue()) {
+        oprot.writeI64(struct.longValue);
+      }
+      if (struct.isSetDoubleValue()) {
+        oprot.writeDouble(struct.doubleValue);
+      }
+      if (struct.isSetStringValue()) {
+        oprot.writeString(struct.stringValue);
+      }
+    }
+
+    @Override
+    public void read(org.apache.thrift.protocol.TProtocol prot, FieldResponse struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(5);
+      if (incoming.get(0)) {
+        struct.responseCode = org.apache.plc4x.interop.RESPONSE_CODE.findByValue(iprot.readI32());
+        struct.setResponseCodeIsSet(true);
+      }
+      if (incoming.get(1)) {
+        struct.boolValue = iprot.readBool();
+        struct.setBoolValueIsSet(true);
+      }
+      if (incoming.get(2)) {
+        struct.longValue = iprot.readI64();
+        struct.setLongValueIsSet(true);
+      }
+      if (incoming.get(3)) {
+        struct.doubleValue = iprot.readDouble();
+        struct.setDoubleValueIsSet(true);
+      }
+      if (incoming.get(4)) {
+        struct.stringValue = iprot.readString();
+        struct.setStringValueIsSet(true);
+      }
+    }
+  }
+
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+}
+
diff --git a/plc4j/utils/interop/src/main/thrift/gen-java/org/apache/plc4x/interop/InteropServer.java b/plc4j/utils/interop/src/main/thrift/gen-java/org/apache/plc4x/interop/InteropServer.java
new file mode 100644
index 0000000..1cc5341
--- /dev/null
+++ b/plc4j/utils/interop/src/main/thrift/gen-java/org/apache/plc4x/interop/InteropServer.java
@@ -0,0 +1,2989 @@
+/**
+ * Autogenerated by Thrift Compiler (0.12.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+package org.apache.plc4x.interop;
+
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.12.0)", date = "2019-04-14")
+public class InteropServer {
+
+  public interface Iface {
+
+    public ConnectionHandle connect(java.lang.String connectionString) throws PlcException, org.apache.thrift.TException;
+
+    public Response execute(ConnectionHandle handle, Request request) throws PlcException, org.apache.thrift.TException;
+
+    public void close(ConnectionHandle handle) throws org.apache.thrift.TException;
+
+  }
+
+  public interface AsyncIface {
+
+    public void connect(java.lang.String connectionString, org.apache.thrift.async.AsyncMethodCallback<ConnectionHandle> resultHandler) throws org.apache.thrift.TException;
+
+    public void execute(ConnectionHandle handle, Request request, org.apache.thrift.async.AsyncMethodCallback<Response> resultHandler) throws org.apache.thrift.TException;
+
+    public void close(ConnectionHandle handle, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
+
+  }
+
+  public static class Client extends org.apache.thrift.TServiceClient implements Iface {
+    public static class Factory implements org.apache.thrift.TServiceClientFactory<Client> {
+      public Factory() {}
+      public Client getClient(org.apache.thrift.protocol.TProtocol prot) {
+        return new Client(prot);
+      }
+      public Client getClient(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
+        return new Client(iprot, oprot);
+      }
+    }
+
+    public Client(org.apache.thrift.protocol.TProtocol prot)
+    {
+      super(prot, prot);
+    }
+
+    public Client(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
+      super(iprot, oprot);
+    }
+
+    public ConnectionHandle connect(java.lang.String connectionString) throws PlcException, org.apache.thrift.TException
+    {
+      send_connect(connectionString);
+      return recv_connect();
+    }
+
+    public void send_connect(java.lang.String connectionString) throws org.apache.thrift.TException
+    {
+      connect_args args = new connect_args();
+      args.setConnectionString(connectionString);
+      sendBase("connect", args);
+    }
+
+    public ConnectionHandle recv_connect() throws PlcException, org.apache.thrift.TException
+    {
+      connect_result result = new connect_result();
+      receiveBase(result, "connect");
+      if (result.isSetSuccess()) {
+        return result.success;
+      }
+      if (result.connectionException != null) {
+        throw result.connectionException;
+      }
+      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "connect failed: unknown result");
+    }
+
+    public Response execute(ConnectionHandle handle, Request request) throws PlcException, org.apache.thrift.TException
+    {
+      send_execute(handle, request);
+      return recv_execute();
+    }
+
+    public void send_execute(ConnectionHandle handle, Request request) throws org.apache.thrift.TException
+    {
+      execute_args args = new execute_args();
+      args.setHandle(handle);
+      args.setRequest(request);
+      sendBase("execute", args);
+    }
+
+    public Response recv_execute() throws PlcException, org.apache.thrift.TException
+    {
+      execute_result result = new execute_result();
+      receiveBase(result, "execute");
+      if (result.isSetSuccess()) {
+        return result.success;
+      }
+      if (result.executionException != null) {
+        throw result.executionException;
+      }
+      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "execute failed: unknown result");
+    }
+
+    public void close(ConnectionHandle handle) throws org.apache.thrift.TException
+    {
+      send_close(handle);
+      recv_close();
+    }
+
+    public void send_close(ConnectionHandle handle) throws org.apache.thrift.TException
+    {
+      close_args args = new close_args();
+      args.setHandle(handle);
+      sendBase("close", args);
+    }
+
+    public void recv_close() throws org.apache.thrift.TException
+    {
+      close_result result = new close_result();
+      receiveBase(result, "close");
+      return;
+    }
+
+  }
+  public static class AsyncClient extends org.apache.thrift.async.TAsyncClient implements AsyncIface {
+    public static class Factory implements org.apache.thrift.async.TAsyncClientFactory<AsyncClient> {
+      private org.apache.thrift.async.TAsyncClientManager clientManager;
+      private org.apache.thrift.protocol.TProtocolFactory protocolFactory;
+      public Factory(org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.protocol.TProtocolFactory protocolFactory) {
+        this.clientManager = clientManager;
+        this.protocolFactory = protocolFactory;
+      }
+      public AsyncClient getAsyncClient(org.apache.thrift.transport.TNonblockingTransport transport) {
+        return new AsyncClient(protocolFactory, clientManager, transport);
+      }
+    }
+
+    public AsyncClient(org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.transport.TNonblockingTransport transport) {
+      super(protocolFactory, clientManager, transport);
+    }
+
+    public void connect(java.lang.String connectionString, org.apache.thrift.async.AsyncMethodCallback<ConnectionHandle> resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      connect_call method_call = new connect_call(connectionString, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class connect_call extends org.apache.thrift.async.TAsyncMethodCall<ConnectionHandle> {
+      private java.lang.String connectionString;
+      public connect_call(java.lang.String connectionString, org.apache.thrift.async.AsyncMethodCallback<ConnectionHandle> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.connectionString = connectionString;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("connect", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        connect_args args = new connect_args();
+        args.setConnectionString(connectionString);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public ConnectionHandle getResult() throws PlcException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new java.lang.IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return (new Client(prot)).recv_connect();
+      }
+    }
+
+    public void execute(ConnectionHandle handle, Request request, org.apache.thrift.async.AsyncMethodCallback<Response> resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      execute_call method_call = new execute_call(handle, request, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class execute_call extends org.apache.thrift.async.TAsyncMethodCall<Response> {
+      private ConnectionHandle handle;
+      private Request request;
+      public execute_call(ConnectionHandle handle, Request request, org.apache.thrift.async.AsyncMethodCallback<Response> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.handle = handle;
+        this.request = request;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("execute", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        execute_args args = new execute_args();
+        args.setHandle(handle);
+        args.setRequest(request);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public Response getResult() throws PlcException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new java.lang.IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return (new Client(prot)).recv_execute();
+      }
+    }
+
+    public void close(ConnectionHandle handle, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      close_call method_call = new close_call(handle, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class close_call extends org.apache.thrift.async.TAsyncMethodCall<Void> {
+      private ConnectionHandle handle;
+      public close_call(ConnectionHandle handle, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.handle = handle;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("close", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        close_args args = new close_args();
+        args.setHandle(handle);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public Void getResult() throws org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new java.lang.IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return null;
+      }
+    }
+
+  }
+
+  public static class Processor<I extends Iface> extends org.apache.thrift.TBaseProcessor<I> implements org.apache.thrift.TProcessor {
+    private static final org.slf4j.Logger _LOGGER = org.slf4j.LoggerFactory.getLogger(Processor.class.getName());
+    public Processor(I iface) {
+      super(iface, getProcessMap(new java.util.HashMap<java.lang.String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>>()));
+    }
+
+    protected Processor(I iface, java.util.Map<java.lang.String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> processMap) {
+      super(iface, getProcessMap(processMap));
+    }
+
+    private static <I extends Iface> java.util.Map<java.lang.String,  org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> getProcessMap(java.util.Map<java.lang.String, org.apache.thrift.ProcessFunction<I, ? extends  org.apache.thrift.TBase>> processMap) {
+      processMap.put("connect", new connect());
+      processMap.put("execute", new execute());
+      processMap.put("close", new close());
+      return processMap;
+    }
+
+    public static class connect<I extends Iface> extends org.apache.thrift.ProcessFunction<I, connect_args> {
+      public connect() {
+        super("connect");
+      }
+
+      public connect_args getEmptyArgsInstance() {
+        return new connect_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      @Override
+      protected boolean rethrowUnhandledExceptions() {
+        return false;
+      }
+
+      public connect_result getResult(I iface, connect_args args) throws org.apache.thrift.TException {
+        connect_result result = new connect_result();
+        try {
+          result.success = iface.connect(args.connectionString);
+        } catch (PlcException connectionException) {
+          result.connectionException = connectionException;
+        }
+        return result;
+      }
+    }
+
+    public static class execute<I extends Iface> extends org.apache.thrift.ProcessFunction<I, execute_args> {
+      public execute() {
+        super("execute");
+      }
+
+      public execute_args getEmptyArgsInstance() {
+        return new execute_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      @Override
+      protected boolean rethrowUnhandledExceptions() {
+        return false;
+      }
+
+      public execute_result getResult(I iface, execute_args args) throws org.apache.thrift.TException {
+        execute_result result = new execute_result();
+        try {
+          result.success = iface.execute(args.handle, args.request);
+        } catch (PlcException executionException) {
+          result.executionException = executionException;
+        }
+        return result;
+      }
+    }
+
+    public static class close<I extends Iface> extends org.apache.thrift.ProcessFunction<I, close_args> {
+      public close() {
+        super("close");
+      }
+
+      public close_args getEmptyArgsInstance() {
+        return new close_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      @Override
+      protected boolean rethrowUnhandledExceptions() {
+        return false;
+      }
+
+      public close_result getResult(I iface, close_args args) throws org.apache.thrift.TException {
+        close_result result = new close_result();
+        iface.close(args.handle);
+        return result;
+      }
+    }
+
+  }
+
+  public static class AsyncProcessor<I extends AsyncIface> extends org.apache.thrift.TBaseAsyncProcessor<I> {
+    private static final org.slf4j.Logger _LOGGER = org.slf4j.LoggerFactory.getLogger(AsyncProcessor.class.getName());
+    public AsyncProcessor(I iface) {
+      super(iface, getProcessMap(new java.util.HashMap<java.lang.String, org.apache.thrift.AsyncProcessFunction<I, ? extends org.apache.thrift.TBase, ?>>()));
+    }
+
+    protected AsyncProcessor(I iface, java.util.Map<java.lang.String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase, ?>> processMap) {
+      super(iface, getProcessMap(processMap));
+    }
+
+    private static <I extends AsyncIface> java.util.Map<java.lang.String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase,?>> getProcessMap(java.util.Map<java.lang.String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase, ?>> processMap) {
+      processMap.put("connect", new connect());
+      processMap.put("execute", new execute());
+      processMap.put("close", new close());
+      return processMap;
+    }
+
+    public static class connect<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, connect_args, ConnectionHandle> {
+      public connect() {
+        super("connect");
+      }
+
+      public connect_args getEmptyArgsInstance() {
+        return new connect_args();
+      }
+
+      public org.apache.thrift.async.AsyncMethodCallback<ConnectionHandle> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new org.apache.thrift.async.AsyncMethodCallback<ConnectionHandle>() { 
+          public void onComplete(ConnectionHandle o) {
+            connect_result result = new connect_result();
+            result.success = o;
+            try {
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
+            }
+          }
+          public void onError(java.lang.Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TSerializable msg;
+            connect_result result = new connect_result();
+            if (e instanceof PlcException) {
+              result.connectionException = (PlcException) e;
+              result.setConnectionExceptionIsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
+            }
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, connect_args args, org.apache.thrift.async.AsyncMethodCallback<ConnectionHandle> resultHandler) throws org.apache.thrift.TException {
+        iface.connect(args.connectionString,resultHandler);
+      }
+    }
+
+    public static class execute<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, execute_args, Response> {
+      public execute() {
+        super("execute");
+      }
+
+      public execute_args getEmptyArgsInstance() {
+        return new execute_args();
+      }
+
+      public org.apache.thrift.async.AsyncMethodCallback<Response> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new org.apache.thrift.async.AsyncMethodCallback<Response>() { 
+          public void onComplete(Response o) {
+            execute_result result = new execute_result();
+            result.success = o;
+            try {
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
+            }
+          }
+          public void onError(java.lang.Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TSerializable msg;
+            execute_result result = new execute_result();
+            if (e instanceof PlcException) {
+              result.executionException = (PlcException) e;
+              result.setExecutionExceptionIsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
+            }
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, execute_args args, org.apache.thrift.async.AsyncMethodCallback<Response> resultHandler) throws org.apache.thrift.TException {
+        iface.execute(args.handle, args.request,resultHandler);
+      }
+    }
+
+    public static class close<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, close_args, Void> {
+      public close() {
+        super("close");
+      }
+
+      public close_args getEmptyArgsInstance() {
+        return new close_args();
+      }
+
+      public org.apache.thrift.async.AsyncMethodCallback<Void> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new org.apache.thrift.async.AsyncMethodCallback<Void>() { 
+          public void onComplete(Void o) {
+            close_result result = new close_result();
+            try {
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
+            }
+          }
+          public void onError(java.lang.Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TSerializable msg;
+            close_result result = new close_result();
+            if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
+            }
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, close_args args, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException {
+        iface.close(args.handle,resultHandler);
+      }
+    }
+
+  }
+
+  public static class connect_args implements org.apache.thrift.TBase<connect_args, connect_args._Fields>, java.io.Serializable, Cloneable, Comparable<connect_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("connect_args");
+
+    private static final org.apache.thrift.protocol.TField CONNECTION_STRING_FIELD_DESC = new org.apache.thrift.protocol.TField("connectionString", org.apache.thrift.protocol.TType.STRING, (short)1);
+
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new connect_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new connect_argsTupleSchemeFactory();
+
+    public @org.apache.thrift.annotation.Nullable java.lang.String connectionString; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      CONNECTION_STRING((short)1, "connectionString");
+
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
+
+      static {
+        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      @org.apache.thrift.annotation.Nullable
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // CONNECTION_STRING
+            return CONNECTION_STRING;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      @org.apache.thrift.annotation.Nullable
+      public static _Fields findByName(java.lang.String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final java.lang.String _fieldName;
+
+      _Fields(short thriftId, java.lang.String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public java.lang.String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.CONNECTION_STRING, new org.apache.thrift.meta_data.FieldMetaData("connectionString", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(connect_args.class, metaDataMap);
+    }
+
+    public connect_args() {
+    }
+
+    public connect_args(
+      java.lang.String connectionString)
+    {
+      this();
+      this.connectionString = connectionString;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public connect_args(connect_args other) {
+      if (other.isSetConnectionString()) {
+        this.connectionString = other.connectionString;
+      }
+    }
+
+    public connect_args deepCopy() {
+      return new connect_args(this);
+    }
+
+    @Override
+    public void clear() {
+      this.connectionString = null;
+    }
+
+    @org.apache.thrift.annotation.Nullable
+    public java.lang.String getConnectionString() {
+      return this.connectionString;
+    }
+
+    public connect_args setConnectionString(@org.apache.thrift.annotation.Nullable java.lang.String connectionString) {
+      this.connectionString = connectionString;
+      return this;
+    }
+
+    public void unsetConnectionString() {
+      this.connectionString = null;
+    }
+
+    /** Returns true if field connectionString is set (has been assigned a value) and false otherwise */
+    public boolean isSetConnectionString() {
+      return this.connectionString != null;
+    }
+
+    public void setConnectionStringIsSet(boolean value) {
+      if (!value) {
+        this.connectionString = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) {
+      switch (field) {
+      case CONNECTION_STRING:
+        if (value == null) {
+          unsetConnectionString();
+        } else {
+          setConnectionString((java.lang.String)value);
+        }
+        break;
+
+      }
+    }
+
+    @org.apache.thrift.annotation.Nullable
+    public java.lang.Object getFieldValue(_Fields field) {
+      switch (field) {
+      case CONNECTION_STRING:
+        return getConnectionString();
+
+      }
+      throw new java.lang.IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new java.lang.IllegalArgumentException();
+      }
+
... 5101 lines suppressed ...