diff --git a/lib/modules/Protocols.pmod/X.pmod/my_struct.pmod b/lib/modules/Protocols.pmod/X.pmod/my_struct.pmod
new file mode 100644
index 0000000000000000000000000000000000000000..012356f09b23d3a281fe917914ad55abe686c1a0
--- /dev/null
+++ b/lib/modules/Protocols.pmod/X.pmod/my_struct.pmod
@@ -0,0 +1,137 @@
+/* my_struct.pmod
+ *
+ * This should replace ADT.struct at some time.
+ */
+
+#include "error.h"
+
+class struct {     
+  string buffer;
+  int index;
+  
+  void create(void|string s)
+  {
+    buffer = s || "";
+    index = 0;
+  }
+
+  /* Return data, without removing it */
+  string contents()
+  {
+    buffer = buffer[index..];
+    index = 0;
+    return buffer;
+  }
+  
+  void add_data(string s)
+  {
+    buffer += s;
+  }
+
+  string pop_data()
+  {
+    string res = buffer;
+    create();
+    return res;
+  }
+  
+  void put_uint(int i, int len)
+  {
+    if (i<0)
+      error("ADT.struct->put_uint: negative argument.\n");
+
+    add_data(sprintf("%*c", len, i));
+  }
+
+  void put_var_string(string s, int len)
+  {
+    if ( (len <= 3) && (strlen(s) >= ({ -1, 0x100, 0x10000, 0x1000000 })[len] ))
+      error("ADT.struct->put_var_string: Field overflow.\n");
+    put_uint(strlen(s), len);
+    add_data(s);
+  }
+
+  void put_bignum(object i, int|void len)
+  {
+    if (i<0)
+      error("ADT.struct->put_bignum: negative argument.\n");
+    put_var_string(i->digits(256), len || 2);
+  }
+
+  void put_fix_string(string s)
+  {
+    add_data(s);
+  }
+
+#if 0
+  void put_fix_array(array(int) data, int item_size)
+  {
+    foreach(data, int i)
+      put_int(i, item_size);
+  }
+
+  void put_var_array(array(int) data, int item_size, int len)
+  {
+    put_int(sizeof(data), len);
+    put_fix_array(data, item_size);
+  }
+#endif
+
+  int get_uint(int len)
+  {
+    mixed i;
+    if ( (strlen(buffer) - index) < len)
+      error("ADT.struct->get_uint: no data\n");
+    sscanf(buffer, "%*" + (string) index +"s%" + (string) len + "c", i);
+    index += len;
+    return i;
+  }
+
+  string get_fix_string(int len)
+  {
+    string res;
+  
+    if ((strlen(buffer) - index) < len)
+      error("ADT.struct->get_fix_string: no data\n");
+    res = buffer[index .. index + len - 1];
+    index += len;
+    return res;
+  }
+
+  string get_var_string(int len)
+  {
+    return get_fix_string(get_uint(len));
+  }
+
+  object get_bignum(int|void len)
+  {
+//     return Gmp.mpz(get_var_string(len || 2), 256);
+  }
+
+  string get_rest()
+  {
+    string s = buffer[index..];
+    create();
+    return s;
+  }
+
+#if 0
+  array(mixed) get_fix_array(int item_size, int size)
+  {
+    array(mixed) res = allocate(size);
+    for(int i = 0; i<size; i++)
+      res[i] = get_int(item_size);
+    return res;
+  }
+
+  array(mixed) get_var_array(int item_size, int len)
+  {
+    return get_fix_array(item_size, get_int(len));
+  }
+#endif
+
+  int is_empty()
+  {
+    return (index == strlen(buffer));
+  }
+}