From 19643a366517b3141d0bb74e1a160069774e0b2b Mon Sep 17 00:00:00 2001
From: "Mirar (Pontus Hagland)" <pike@sort.mirar.org>
Date: Sun, 13 Jun 1999 01:01:50 +0200
Subject: [PATCH] inserted into pike as Protocols.LysKOM

Rev: lib/modules/Protocols.pmod/LysKOM.pmod/Connection.pike:1.1
Rev: lib/modules/Protocols.pmod/LysKOM.pmod/Helper.pmod:1.1
Rev: lib/modules/Protocols.pmod/LysKOM.pmod/ProtocolTypes.pmod:1.1
Rev: lib/modules/Protocols.pmod/LysKOM.pmod/Raw.pike:1.1
Rev: lib/modules/Protocols.pmod/LysKOM.pmod/Request.pmod:1.1
Rev: lib/modules/Protocols.pmod/LysKOM.pmod/Session.pike:1.1
---
 .gitattributes                                |    3 +
 .../LysKOM.pmod/Connection.pike               |  158 +
 .../Protocols.pmod/LysKOM.pmod/Helper.pmod    |  360 +++
 .../LysKOM.pmod/ProtocolTypes.pmod            | 1075 +++++++
 .../Protocols.pmod/LysKOM.pmod/Raw.pike       |  453 +++
 .../Protocols.pmod/LysKOM.pmod/Request.pmod   | 2560 +++++++++++++++++
 .../Protocols.pmod/LysKOM.pmod/Session.pike   |  599 ++++
 7 files changed, 5208 insertions(+)
 create mode 100644 lib/modules/Protocols.pmod/LysKOM.pmod/Connection.pike
 create mode 100644 lib/modules/Protocols.pmod/LysKOM.pmod/Helper.pmod
 create mode 100644 lib/modules/Protocols.pmod/LysKOM.pmod/ProtocolTypes.pmod
 create mode 100644 lib/modules/Protocols.pmod/LysKOM.pmod/Raw.pike
 create mode 100644 lib/modules/Protocols.pmod/LysKOM.pmod/Request.pmod
 create mode 100644 lib/modules/Protocols.pmod/LysKOM.pmod/Session.pike

diff --git a/.gitattributes b/.gitattributes
index 9a3eeb6a99..7d05fad768 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -43,6 +43,9 @@ testfont binary
 /lib/modules/Protocols.pmod/Ident.pmod foreign_ident
 /lib/modules/Protocols.pmod/LPD.pmod foreign_ident
 /lib/modules/Protocols.pmod/Line.pmod foreign_ident
+/lib/modules/Protocols.pmod/LysKOM.pmod/Connection.pike foreign_ident
+/lib/modules/Protocols.pmod/LysKOM.pmod/Request.pmod foreign_ident
+/lib/modules/Protocols.pmod/LysKOM.pmod/Session.pike foreign_ident
 /lib/modules/Protocols.pmod/Ports.pmod foreign_ident
 /lib/modules/Protocols.pmod/TELNET.pmod foreign_ident
 /lib/modules/Protocols.pmod/X.pmod/Atom.pmod foreign_ident
diff --git a/lib/modules/Protocols.pmod/LysKOM.pmod/Connection.pike b/lib/modules/Protocols.pmod/LysKOM.pmod/Connection.pike
new file mode 100644
index 0000000000..36f913a43b
--- /dev/null
+++ b/lib/modules/Protocols.pmod/LysKOM.pmod/Connection.pike
@@ -0,0 +1,158 @@
+//  $Id: Connection.pike,v 1.1 1999/06/12 23:01:49 mirar Exp $
+//! module Protocols
+//! submodule LysKOM
+//! class Session
+//  ^^^ this is just to get the classes sorted right. Session first,
+//      then Connection, then it doesn't matter
+//! submodule LysKOM
+//! class Connection
+//!	This class contains nice abstraction for calls into the
+//!	server. They are named "<i>call</i>", 
+//!	"<tt>async_</tt><i>call</i>" or 
+//!	"<tt>async_cb_</tt><i>call</i>", depending on 
+//!	how you want the call to be done. 
+//!
+//! method mixed /call/(mixed ...args)
+//! method object async_/call/(mixed ...args)
+//! method object async_cb_/call/(function callback,mixed ...args)
+//!	Do a call to the server. This really 
+//!	clones a <link to=Protocols.LysKOM.Request>request</link> object,
+//!	and initialises it. /call/ is to be read as 
+//!	one of the calls in the lyskom protocol. ('-' is replaced
+//!	with '_'.) (ie, logout, async_login or async_cb_get_conf_stat.)
+//!	
+//!	The first method is a synchronous call. This will
+//!	send the command, wait for the server to execute it,
+//!	and then return the result.
+//!
+//!	The last two is asynchronous calls, returning the
+//!	initialised <link to=Protocols.LysKOM.Request>request</link> object.
+//!
+
+import ".";
+
+object this=this_object();
+object con; // LysKOM.Raw
+
+//!
+//! method void create(string server)
+//! method void create(string server,mapping options)
+//!	<pre>
+//!	    "login"      : int|string - login as this person number
+//!                                     (get number from name)
+//!	    "password"   : string     - send this login password
+//!	    "invisible"  : int(0..1)  - login invisible    
+//!				      
+//!	advanced:		      
+//!	    "port" : int              - server port (default is 4894)
+//!	    "whoami" : string         - user name (default is from uid)
+//!	</pre>
+
+void create(string server,void|mapping options)
+{
+   if (!options) options=([]);
+   con=Raw(server,options->port,options->whoami);
+   if (!con->con)
+   {
+      con=0;
+      return;
+   }
+
+   if (options->login)
+   {
+      if (stringp(options->login))
+      {
+	 array a=this->lookup_z_name(options->login,1,0);
+	 if (sizeof(a)!=1)
+	    error("LysKOM: The login name %O does not match 1 name "
+		  "exact (%d hits)\n",
+		  options->login,sizeof(a));
+	 options->login=a[0]->conf_no;
+      }
+      this->login(options->login,
+		  options->password||"",
+		  options->invisible);
+   }
+}
+
+class SyncRequest
+{
+   program prog;
+   object ret;
+	 
+   void create(program p,object _ret)
+   {
+      prog=p;
+      ret=_ret;
+   }
+
+   mixed `()(mixed ...args)
+   {
+      mixed m;
+      object req=prog(con);
+      m=req->sync(@args);
+      if (!req->ok)
+      {
+	 throw(req->error);
+// 	 error(sprintf("lyskom-error %d,%d: %s\n%-=75s\n",
+// 		       req->error->no,
+// 		       req->error->status,
+// 		       req->error->name,
+// 		       req->error->desc));
+      }
+      if (!m) return ret;
+      else return m;
+   }
+}
+      
+class AsyncRequest
+{
+   program prog;
+	 
+   void create(program p)
+   {
+      prog=p;
+   }
+
+   mixed `()(mixed ...args)
+   {
+      object req=prog(con);
+      req->async(@args);
+      return req;
+   }
+}
+
+class AsyncCBRequest
+{
+   program prog;
+
+   void create(program p)
+   {
+      prog=p;
+   }
+
+   mixed `()(function callback,mixed ...args)
+   {
+      object req=prog(con);
+      req->callback=callback;
+      req->async(@args);
+      return req;
+   }
+}
+
+mixed `->(string request)
+{
+   program p;
+   if ( (p=Request[String.capitalize(request)]) )
+      return SyncRequest(p,this_object());
+   else if ( request[..5]=="async_" &&
+	     (p=Request[String.capitalize(request[6..])]) )
+      return AsyncRequest(p);
+   else if ( request[..8]=="async_cb_" &&
+	     (p=Request[String.capitalize(request[9..])]) )
+      return AsyncCBRequest(p);
+   else
+      return ::`[](request);
+}
+
+mixed `[](string request) { return `->(request); }
diff --git a/lib/modules/Protocols.pmod/LysKOM.pmod/Helper.pmod b/lib/modules/Protocols.pmod/LysKOM.pmod/Helper.pmod
new file mode 100644
index 0000000000..02b2edbd10
--- /dev/null
+++ b/lib/modules/Protocols.pmod/LysKOM.pmod/Helper.pmod
@@ -0,0 +1,360 @@
+constant CONNECTION_CLOSED=-100;
+
+string encode(mixed ... z) // encode arguments
+{
+   return ((array(string))z)*" ";
+}
+
+string H(string what) // encode hollerith
+{
+   return strlen(what)+"H"+what;
+}
+
+string B(int(0..1) ... z) // encode bitfield
+{
+   string res="";
+   res=((array(string))z)*"";
+   return res;
+}
+
+array(string) A(mixed ... z) // encode array (use @)
+{
+   if (!sizeof(z)) return ({"0","*"});
+   return ({""+sizeof(z)," { "+encode(@z)+" }"});
+}
+
+class LysKOMError
+{
+   constant iserror=1;
+   constant is_generic_error=1;
+
+   int no;
+   string name;
+   string desc;
+   int status;
+   array(mixed) __backtrace;
+
+   void create(int _no,string _name,string _desc,void|int _status)
+   {
+      no=_no;
+      name=_name;
+      desc=_desc;
+      status=_status;
+      __backtrace=backtrace();
+      __backtrace=__backtrace[..sizeof(__backtrace)-3];
+   }
+
+   object clone(int status)
+   {
+      return LysKOMError(no,name,desc,status);
+   }
+   
+   mixed `[](mixed z)
+   {
+      switch (z)
+      {
+	 case 0: return "Protocols.LysKOM: ["+no+"] "+name+"\n";
+	 case 1: return __backtrace;
+      }
+   }
+}
+
+object lyskom_error(int no,void|int status)
+{
+   return LysKOMError(@_lyskomerror[no],status);
+}
+
+mapping _lyskomerror=
+([
+   0:({0,"no-error",
+       "No error has occurred. This should never "
+       "happen, but it might."}),
+
+   2:({2,"not-implemented",
+       "The call has not been implemented yet."}),
+
+   3:({3,"obsolete-call",
+       "The call is obsolete and no longer "
+       "implemented. Status value is "
+       "undefined."}),
+
+   4:({4,"invalid-password",
+       "Attempt to set a password containing "
+       "illegal characters, or to use an "
+       "incorrect password."}),
+
+   5:({5,"string-too-long",
+       "A string was too long (see descriptions "
+       "of each call.) Status value indicates "
+       "the maximum string length."}),
+
+       6:({6,"login-first",
+	   "Login is required before issuing the "
+	   "call. Status value is undefined. "}),
+
+   7:({7,"login-disallowed",
+       "The system is in single-user mode. You "
+       "need to be privileged to log in despite "
+       "this. "}),
+
+   8:({8,"conference-zero",
+       "Attempt to use conference number 0. "}),
+
+   9:({9,"undefined-conference",
+       "Attempt to access a non-existent or "
+       "secret conference. Status value contains "
+       "the conference number in question."}),
+
+   10:({10,"undefined-person",
+	"Attempt to access a non-existent or"
+	"secret person. Status value contains the"
+	"person number in question."}),
+
+   11:({11,"access-denied",
+	"No read/write access to something. This"
+	"might be returned in response to an"
+	"attempt to create a text, when the"
+	"recipient conference and its super"
+	"conferences are read-only, or when"
+	"attempting to add a member to a"
+	"conference without enough permission to"
+	"do so. Status value indicates the object"
+	"to which we didn't have enough"
+	"permissions to."}),
+
+   12:({12,"permission-denied",
+	"Not enough permissions to do something."
+	"The exact meaning of this response"
+	"depends on the call. Status value"
+	"indicated the object for which"
+	"permission was lacking, or zero."}),
+
+   13:({13,"not-member",
+	"The call requires the caller to be a"
+	"member of some conference that the"
+	"caller is not a member of. Status value"
+	"indicates the conference in question."}),
+
+   14:({14,"no-such-text",
+	"Attempt to access a text that either"
+	"does not exist or is secret in some way."
+	"status value indicates the text number"
+	"in question."}),
+
+   15:({15,"text-zero",
+	"Attempt to use text number 0. "}),
+
+   16:({16,"no-such-local-text",
+	"Attempt to access a text using a local"
+	"text number that does not represent an"
+	"existing text. Status value indicates"
+	"the offending number."}),
+
+   17:({17,"local-text-zero",
+	"Attempt to use local text number zero."}),
+
+   18:({18,"bad-name",
+	"Attempt to use a name that's too long,"
+	"too short or contains invalid"
+	"characters. "}),
+
+   19:({19,"index-out-of-range",
+	"Attempt to use a number that's out of"
+	"range. The range and meaning of the"
+	"numbers depends on the call issued."
+	"status value is undefined."}),
+
+   20:({20,"conference-exists",
+	"Attempt to create a conference or person"
+	"with a name that's already occupied. "}),
+
+   21:({21,"person-exists",
+	"Attempt to create a person with a name"
+	"that's already occupied. This error code"
+	"is probably not used, but you never know"
+	"for sure."}),
+
+   22:({22,"secret-public",
+	"Attempt to give a conference a type with"
+	"@code{secret} bit set and the"
+	"@code{rd-prot} bit unset. This is an"
+	"error since such a conference type is"
+	"inconsistent. "}),
+
+   23:({23,"letterbox",
+	"Attempt to change the @code{letterbox}"
+	"flag of a conference. Status value"
+	"indicates the conference number."}),
+
+   24:({24,"ldb-error",
+	"Database is corrupted. Status value is"
+	"an internal code."}),
+
+   25:({25,"illegal-misc",
+	"Attempt to create an illegal misc item."
+	"status value contains the index of the"
+	"illegal item."}),
+
+   26:({26,"illegal-info-type",
+	"Attempt to use a Misc-Info type that the"
+	"server knows nothing about. "}),
+
+   27:({27,"already-recipient",
+	"Attempt to add a recipient that is"
+	"already a recipient of the same type."
+	"status value contains the recipient that"
+	"already is."}),
+
+   28:({28,"already-comment",
+	"Attempt to add a comment to a text twice"
+	"over. Status value contains the text"
+	"number of the text that already is a"
+	"comment."}),
+
+   29:({29,"already-footnote",
+	"Attempt to add a footnote to a text"
+	"twice over. Status value contains the"
+	"text number of the text that already is"
+	"a footnote."}),
+
+   30:({30,"not-recipient",
+	"Attempt to remove a recipient that isn't"
+	"really a recipient. Status value"
+	"contains the conference number in"
+	"question."}),
+
+   31:({31,"not-comment",
+	"Attempt to remove a comment link that"
+	"does not exist. Status value contains"
+	"the text number that isn't a comment. "}),
+
+   32:({32,"not-footnote",
+	"Attempt to remove a footnote link that"
+	"does not exist. Status value contains"
+	"the text number that isn't a footnote."}),
+
+   33:({33,"recipient-limit",
+	"Attempt to add a recipient to a text"
+	"that already has the maximum number of"
+	"recipients. Status value is the text"
+	"that has the maximum number of"
+	"recipients."}),
+
+   34:({34,"comment-limit",
+	"Attempt to add a comment to a text that"
+	"already has the maximum number of"
+	"comments. Status value is the text with"
+	"the maximum number of comments. "}),
+
+   35:({35,"footnote-limit",
+	"Attempt to add a footnote to a text that"
+	"already has the maximum number of"
+	"footnote. Status value is the text with"
+	"the maximum number of footnote. "}),
+
+   36:({36,"mark-limit",
+	"Attempt to add a mark to a text that"
+	"already has the maximum number of marks."
+	"status value is the text with the"
+	"maximum number of marks. "}),
+
+   37:({37,"not-author",
+	"Attempt to manipulate a text in a way"
+	"that required the user to be the author"
+	"of the text, when not in fact the"
+	"author. Status value contains the text"
+	"number in question."}),
+
+   38:({38,"no-connect",
+	"Currently unused."}),
+
+   39:({39,"out-of-memory",
+	"The server ran out of memory."}),
+
+   40:({40,"server-is-crazy",
+	"Currently unused."}),
+
+   41:({41,"client-is-crazy",
+	"Currently unused."}),
+
+   42:({42,"undefined-session",
+	"Attempt to access a session that does"
+	"not exist. Status value contains the"
+	"offending session number."}),
+
+   43:({43,"regexp-error",
+	"Error using a regexp. The regexp may be"
+	"invalid or the server unable to compile"
+	"it for other reasons. "}),
+
+   44:({44,"not-marked",
+	"Attempt to manipulate a text in a way"
+	"that requires the text to be marked,"
+	"when in fact it is not marked. Status"
+	"value indicates the text in question."}),
+
+   45:({45,"temporary-failure",
+	"Temporary failure. Try again later."
+	"@code{error-code} is undefined."}),
+
+   46:({46,"long-array",
+	"An array sent to the server was too"
+	"long. Status value is undefined."}),
+
+   47:({47,"anonymous-rejected",
+	"Attempt to send an anonymous text to a"
+	"conference that does not accept"
+	"anonymous texts. "}),
+
+   48:({48,"illegal-aux-item",
+	"Attempt to create an invalid aux-item."
+	"Probably the tag or data are invalid."
+	"status value contains the index in the"
+	"aux-item list where the invalid item"
+	"appears."}),
+
+   49:({49,"aux-item-permission",
+	"Attempt to manipulate an aux-item"
+	"without enough permissions. This"
+	"response is sent when attempting to"
+	"delete an item set by someone else or an"
+	"item that can't be deleted, and when"
+	"attempting to create an item without"
+	"permissions to do so. Status value"
+	"contains the index at which the item"
+	"appears in the aux-item list sent to the"
+	"server."}),
+
+   50:({50,"unknown-async",
+	"Sent in response to a request for an"
+	"asynchronous message the server does not"
+	"send. The call succeeds, but this is"
+	"sent as a warning to the client. Status"
+	"value contains the message type the"
+	"server did not understand."}),
+
+   51:({51,"internal-error",
+	"The server has encountered a possibly"
+	"recoverable internal error. "}),
+
+   52:({52,"feature-disabled",
+	"Attempt to use a feature that has been"
+	"explicitly disabled in the server. "}),
+
+   53:({53,"message-not-sent",
+	"Attempt to send an asynchronous message"
+	"failed for some reason. Perhaps the"
+	"recipient is not accepting messages at"
+	"the moment."}),
+
+   54:({54,"invalid-membership-type",
+	"A requested membership type was not"
+	"compatible with restrictions set on the"
+	"server or on a specific conference."
+	"status value is undefined unless"
+	"specifically mentioned in the"
+	"documentation for a specific call."}),
+
+   CONNECTION_CLOSED:({CONNECTION_CLOSED,"connection closed",
+		       "LysKOM module: connection has been closed"})
+]);
diff --git a/lib/modules/Protocols.pmod/LysKOM.pmod/ProtocolTypes.pmod b/lib/modules/Protocols.pmod/LysKOM.pmod/ProtocolTypes.pmod
new file mode 100644
index 0000000000..af45aed44d
--- /dev/null
+++ b/lib/modules/Protocols.pmod/LysKOM.pmod/ProtocolTypes.pmod
@@ -0,0 +1,1075 @@
+import .Helper;
+
+
+//
+// automatically generated datatypes
+//
+
+class LysKOMTime
+{
+   int              seconds;                       // INT32
+   int              minutes;                       // INT32
+   int              hours;                         // INT32
+   int              day;                           // INT32
+   int              month;                         // INT32
+   int              year;                          // INT32
+   int              day_of_week;                   // INT32
+   int              day_of_year;                   // INT32
+   int(0..1)        is_dst;                        // BOOL
+
+   void create(string|array ...args)
+   {
+      seconds=(int)args[0];                        // INT32
+      minutes=(int)args[1];                        // INT32
+      hours=(int)args[2];                          // INT32
+      day=(int)args[3];                            // INT32
+      month=(int)args[4];                          // INT32
+      year=(int)args[5];                           // INT32
+      day_of_week=(int)args[6];                    // INT32
+      day_of_year=(int)args[7];                    // INT32
+      is_dst=(int)args[8];                         // BOOL
+   }
+
+   array encode()
+   {
+      return
+         ({
+            seconds,                               // INT32
+            minutes,                               // INT32
+            hours,                                 // INT32
+            day,                                   // INT32
+            month,                                 // INT32
+            year,                                  // INT32
+            day_of_week,                           // INT32
+            day_of_year,                           // INT32
+            is_dst,                                // BOOL
+         });
+   }
+}
+
+class TextStatOld
+{
+   LysKOMTime       creation_time;                 // Time
+   int(0..65535)    author;                        // Pers-No
+   int              no_of_lines;                   // INT32
+   int              no_of_chars;                   // INT32
+   int(0..65535)    no_of_marks;                   // INT16
+   array(int)       misc_info;                     // ARRAY Misc-Info
+
+   void create(string|array ...args)
+   {
+      creation_time=LysKOMTime(@args[0..8]);       // Time
+      author=(int)args[9];                         // Pers-No
+      no_of_lines=(int)args[10];                   // INT32
+      no_of_chars=(int)args[11];                   // INT32
+      no_of_marks=(int)args[12];                   // INT16
+      // --- skip array size: args[13]
+      misc_info=(array(int))args[14];              // ARRAY Misc-Info
+   }
+
+   array encode()
+   {
+      return
+         ({
+            @creation_time->encode(),              // Time
+            author,                                // Pers-No
+            no_of_lines,                           // INT32
+            no_of_chars,                           // INT32
+            no_of_marks,                           // INT16
+            @A((array(string))misc_info),          // ARRAY Misc-Info
+         });
+   }
+}
+
+class TextNumberPair
+{
+   int              local_number;                  // Local-Text-No
+   int              global_number;                 // Text-No
+
+   void create(string|array ...args)
+   {
+      local_number=(int)args[0];                   // Local-Text-No
+      global_number=(int)args[1];                  // Text-No
+   }
+
+   array encode()
+   {
+      return
+         ({
+            local_number,                          // Local-Text-No
+            global_number,                         // Text-No
+         });
+   }
+}
+
+mixed LocalToGlobalBlock(array what) { werror("LysKOM: LocalToGlobalBlock unimplemented\n"); exit(-1); };
+
+class TextMapping
+{
+   int              range_begin;                   // Local-Text-No
+   int              range_end;                     // Local-Text-No
+   int(0..1)        later_texts_exists;            // BOOL
+   mixed            block;                         // Local-To-Global-Block
+
+   void create(string|array ...args)
+   {
+      range_begin=(int)args[0];                    // Local-Text-No
+      range_end=(int)args[1];                      // Local-Text-No
+      later_texts_exists=(int)args[2];             // BOOL
+      block=LocalToGlobalBlock(args[3]);           // Local-To-Global-Block
+   }
+
+   array encode()
+   {
+      return
+         ({
+            range_begin,                           // Local-Text-No
+            range_end,                             // Local-Text-No
+            later_texts_exists,                    // BOOL
+            @error("unimplemented"),               // Local-To-Global-Block
+         });
+   }
+}
+
+constant sessionflagsnames = 
+   ({ "invisible", "user_active_used", "user_absent",    
+      "reserved3", "reserved4", "reserved5", "reserved6",
+      "reserved7"                                         });
+
+multiset(string) SessionFlags(string bits)
+{
+   multiset(string) res=(<>);
+   foreach (Array.transpose( ({sessionflagsnames,values(bits)}) ),
+            [string name,int z] )
+      res[name]=z-'0';
+   return res;
+}
+
+class DynamicSessionInfo
+{
+   int              session;                       // Session-No
+   int(0..65535)    person;                        // Pers-No
+   int(0..65535)    working_conference;            // Conf-No
+   int              idle_time;                     // INT32
+   multiset(string) flags;                         // Session-Flags
+   string           what_am_i_doing;               // HOLLERITH
+
+   void create(string|array ...args)
+   {
+      session=(int)args[0];                        // Session-No
+      person=(int)args[1];                         // Pers-No
+      working_conference=(int)args[2];             // Conf-No
+      idle_time=(int)args[3];                      // INT32
+      flags=SessionFlags(args[4]);                 // Session-Flags
+      what_am_i_doing=args[5];                     // HOLLERITH
+   }
+
+   array encode()
+   {
+      return
+         ({
+            session,                               // Session-No
+            person,                                // Pers-No
+            working_conference,                    // Conf-No
+            idle_time,                             // INT32
+            @B(@rows(flags,sessionflagsnames)),    // Session-Flags
+            H(what_am_i_doing),                    // HOLLERITH
+         });
+   }
+}
+
+class SessionInfo
+{
+   int(0..65535)    person;                        // Pers-No
+   int(0..65535)    working_conference;            // Conf-No
+   int              session;                       // Session-No
+   string           what_am_i_doing;               // HOLLERITH
+   string           username;                      // HOLLERITH
+   int              idle_time;                     // INT32
+   LysKOMTime       connection_time;               // Time
+
+   void create(string|array ...args)
+   {
+      person=(int)args[0];                         // Pers-No
+      working_conference=(int)args[1];             // Conf-No
+      session=(int)args[2];                        // Session-No
+      what_am_i_doing=args[3];                     // HOLLERITH
+      username=args[4];                            // HOLLERITH
+      idle_time=(int)args[5];                      // INT32
+      connection_time=LysKOMTime(@args[6..14]);    // Time
+   }
+
+   array encode()
+   {
+      return
+         ({
+            person,                                // Pers-No
+            working_conference,                    // Conf-No
+            session,                               // Session-No
+            H(what_am_i_doing),                    // HOLLERITH
+            H(username),                           // HOLLERITH
+            idle_time,                             // INT32
+            @connection_time->encode(),            // Time
+         });
+   }
+}
+
+class WhoInfo
+{
+   int(0..65535)    person;                        // Pers-No
+   int(0..65535)    working_conference;            // Conf-No
+   int              session;                       // Session-No
+   string           what_am_i_doing;               // HOLLERITH
+   string           username;                      // HOLLERITH
+
+   void create(string|array ...args)
+   {
+      person=(int)args[0];                         // Pers-No
+      working_conference=(int)args[1];             // Conf-No
+      session=(int)args[2];                        // Session-No
+      what_am_i_doing=args[3];                     // HOLLERITH
+      username=args[4];                            // HOLLERITH
+   }
+
+   array encode()
+   {
+      return
+         ({
+            person,                                // Pers-No
+            working_conference,                    // Conf-No
+            session,                               // Session-No
+            H(what_am_i_doing),                    // HOLLERITH
+            H(username),                           // HOLLERITH
+         });
+   }
+}
+
+constant personalflagsnames = 
+   ({ "unread_is_secret", "flg2", "flg3", "flg4", "flg5",
+      "flg6", "flg7", "flg8"                              });
+
+multiset(string) PersonalFlags(string bits)
+{
+   multiset(string) res=(<>);
+   foreach (Array.transpose( ({personalflagsnames,values(bits)}) ),
+            [string name,int z] )
+      res[name]=z-'0';
+   return res;
+}
+
+constant auxitemflagsnames = 
+   ({ "deleted", "inherit", "secret", "hide_creator",    
+      "dont_garb", "reserved2", "reserved3", "reserved4"  });
+
+multiset(string) AuxItemFlags(string bits)
+{
+   multiset(string) res=(<>);
+   foreach (Array.transpose( ({auxitemflagsnames,values(bits)}) ),
+            [string name,int z] )
+      res[name]=z-'0';
+   return res;
+}
+
+class AuxItem
+{
+   int              aux_no;                        // Aux-No
+   int              tag;                           // INT32
+   int(0..65535)    creator;                       // Pers-No
+   LysKOMTime       created_at;                    // Time
+   multiset(string) flags;                         // Aux-Item-Flags
+   int              inherit_limit;                 // INT32
+   string           data;                          // HOLLERITH
+
+   void create(string|array ...args)
+   {
+      aux_no=(int)args[0];                         // Aux-No
+      tag=(int)args[1];                            // INT32
+      creator=(int)args[2];                        // Pers-No
+      created_at=LysKOMTime(@args[3..11]);         // Time
+      flags=AuxItemFlags(args[12]);                // Aux-Item-Flags
+      inherit_limit=(int)args[13];                 // INT32
+      data=args[14];                               // HOLLERITH
+   }
+
+   array encode()
+   {
+      return
+         ({
+            aux_no,                                // Aux-No
+            tag,                                   // INT32
+            creator,                               // Pers-No
+            @created_at->encode(),                 // Time
+            @B(@rows(flags,auxitemflagsnames)),    // Aux-Item-Flags
+            inherit_limit,                         // INT32
+            H(data),                               // HOLLERITH
+         });
+   }
+}
+
+class TextStat
+{
+   LysKOMTime       creation_time;                 // Time
+   int(0..65535)    author;                        // Pers-No
+   int              no_of_lines;                   // INT32
+   int              no_of_chars;                   // INT32
+   int(0..65535)    no_of_marks;                   // INT16
+   array(int)       misc_info;                     // ARRAY Misc-Info
+   array(AuxItem)   aux_items;                     // ARRAY Aux-Item
+
+   void create(string|array ...args)
+   {
+      creation_time=LysKOMTime(@args[0..8]);       // Time
+      author=(int)args[9];                         // Pers-No
+      no_of_lines=(int)args[10];                   // INT32
+      no_of_chars=(int)args[11];                   // INT32
+      no_of_marks=(int)args[12];                   // INT16
+      // --- skip array size: args[13]
+      misc_info=(array(int))args[14];              // ARRAY Misc-Info
+      // --- skip array size: args[15]
+      aux_items=                                   // ARRAY Aux-Item
+         Array.map(args[16]/15,
+                   lambda(array z) { return AuxItem(@z); });
+   }
+
+   array encode()
+   {
+      return
+         ({
+            @creation_time->encode(),              // Time
+            author,                                // Pers-No
+            no_of_lines,                           // INT32
+            no_of_chars,                           // INT32
+            no_of_marks,                           // INT16
+            @A((array(string))misc_info),          // ARRAY Misc-Info
+            A(`+(@Array.map(aux_items,             // ARRAY Aux-Item
+                            lambda(AuxItem z) 
+                               { return z->encode(); }))),
+         });
+   }
+}
+
+class InfoOld
+{
+   int              version;                       // INT32
+   int(0..65535)    conf_pres_conf;                // Conf-No
+   int(0..65535)    pers_pres_conf;                // Conf-No
+   int(0..65535)    motd_conf;                     // Conf-No
+   int(0..65535)    kom_news_conf;                 // Conf-No
+   int              motd_of_lyskom;                // Text-No
+
+   void create(string|array ...args)
+   {
+      version=(int)args[0];                        // INT32
+      conf_pres_conf=(int)args[1];                 // Conf-No
+      pers_pres_conf=(int)args[2];                 // Conf-No
+      motd_conf=(int)args[3];                      // Conf-No
+      kom_news_conf=(int)args[4];                  // Conf-No
+      motd_of_lyskom=(int)args[5];                 // Text-No
+   }
+
+   array encode()
+   {
+      return
+         ({
+            version,                               // INT32
+            conf_pres_conf,                        // Conf-No
+            pers_pres_conf,                        // Conf-No
+            motd_conf,                             // Conf-No
+            kom_news_conf,                         // Conf-No
+            motd_of_lyskom,                        // Text-No
+         });
+   }
+}
+
+constant membershiptypenames = 
+   ({ "invitation", "passive", "secret", "reserved1",    
+      "reserved2", "reserved3", "reserved4", "reserved5"  });
+
+multiset(string) MembershipType(string bits)
+{
+   multiset(string) res=(<>);
+   foreach (Array.transpose( ({membershiptypenames,values(bits)}) ),
+            [string name,int z] )
+      res[name]=z-'0';
+   return res;
+}
+
+class Membership
+{
+   int              position;                      // INT32
+   LysKOMTime       last_time_read;                // Time
+   int(0..65535)    conf_no;                       // Conf-No
+   int(0..255)      priority;                      // INT8
+   int              last_text_read;                // Local-Text-No
+   array(int)       read_texts;                    // ARRAY Local-Text-No
+   int(0..65535)    added_by;                      // Pers-No
+   LysKOMTime       added_at;                      // Time
+   multiset(string) type;                          // Membership-Type
+
+   void create(string|array ...args)
+   {
+      position=(int)args[0];                       // INT32
+      last_time_read=LysKOMTime(@args[1..9]);      // Time
+      conf_no=(int)args[10];                       // Conf-No
+      priority=(int)args[11];                      // INT8
+      last_text_read=(int)args[12];                // Local-Text-No
+      // --- skip array size: args[13]
+      read_texts=(array(int))args[14];             // ARRAY Local-Text-No
+      added_by=(int)args[15];                      // Pers-No
+      added_at=LysKOMTime(@args[16..24]);          // Time
+      type=MembershipType(args[25]);               // Membership-Type
+   }
+
+   array encode()
+   {
+      return
+         ({
+            position,                              // INT32
+            @last_time_read->encode(),             // Time
+            conf_no,                               // Conf-No
+            priority,                              // INT8
+            last_text_read,                        // Local-Text-No
+            @A((array(string))read_texts),         // ARRAY Local-Text-No
+            added_by,                              // Pers-No
+            @added_at->encode(),                   // Time
+            @B(@rows(type,membershiptypenames)),   // Membership-Type
+         });
+   }
+}
+
+class Member
+{
+   int(0..65535)    member;                        // Pers-No
+   int(0..65535)    added_by;                      // Pers-No
+   LysKOMTime       added_at;                      // Time
+   multiset(string) type;                          // Membership-Type
+
+   void create(string|array ...args)
+   {
+      member=(int)args[0];                         // Pers-No
+      added_by=(int)args[1];                       // Pers-No
+      added_at=LysKOMTime(@args[2..10]);           // Time
+      type=MembershipType(args[11]);               // Membership-Type
+   }
+
+   array encode()
+   {
+      return
+         ({
+            member,                                // Pers-No
+            added_by,                              // Pers-No
+            @added_at->encode(),                   // Time
+            @B(@rows(type,membershiptypenames)),   // Membership-Type
+         });
+   }
+}
+
+class MembershipOld
+{
+   LysKOMTime       last_time_read;                // Time
+   int(0..65535)    conf_no;                    // Conf-No
+   int(0..255)      priority;                      // INT8
+   int              last_text_read;                // Local-Text-No
+   array(int)       read_texts;                    // ARRAY Local-Text-No
+
+   void create(string|array ...args)
+   {
+      last_time_read=LysKOMTime(@args[0..8]);      // Time
+      conf_no=(int)args[9];                     // Conf-No
+      priority=(int)args[10];                      // INT8
+      last_text_read=(int)args[11];                // Local-Text-No
+      // --- skip array size: args[12]
+      read_texts=(array(int))args[13];             // ARRAY Local-Text-No
+   }
+
+   array encode()
+   {
+      return
+         ({
+            @last_time_read->encode(),             // Time
+            conf_no,                            // Conf-No
+            priority,                              // INT8
+            last_text_read,                        // Local-Text-No
+            @A((array(string))read_texts),         // ARRAY Local-Text-No
+         });
+   }
+}
+
+class Info
+{
+   int              version;                       // INT32
+   int(0..65535)    conf_pres_conf;                // Conf-No
+   int(0..65535)    pers_pres_conf;                // Conf-No
+   int(0..65535)    motd_conf;                     // Conf-No
+   int(0..65535)    kom_news_conf;                 // Conf-No
+   int              motd_of_lyskom;                // Text-No
+   array(AuxItem)   aux_item_list;                 // ARRAY Aux-Item
+
+   void create(string|array ...args)
+   {
+      version=(int)args[0];                        // INT32
+      conf_pres_conf=(int)args[1];                 // Conf-No
+      pers_pres_conf=(int)args[2];                 // Conf-No
+      motd_conf=(int)args[3];                      // Conf-No
+      kom_news_conf=(int)args[4];                  // Conf-No
+      motd_of_lyskom=(int)args[5];                 // Text-No
+      // --- skip array size: args[6]
+      aux_item_list=                               // ARRAY Aux-Item
+         Array.map(args[7]/15,
+                   lambda(array z) { return AuxItem(@z); });
+   }
+
+   array encode()
+   {
+      return
+         ({
+            version,                               // INT32
+            conf_pres_conf,                        // Conf-No
+            pers_pres_conf,                        // Conf-No
+            motd_conf,                             // Conf-No
+            kom_news_conf,                         // Conf-No
+            motd_of_lyskom,                        // Text-No
+            A(`+(@Array.map(aux_item_list,         // ARRAY Aux-Item
+                            lambda(AuxItem z) 
+                               { return z->encode(); }))),
+         });
+   }
+}
+
+class StaticSessionInfo
+{
+   string           username;                      // HOLLERITH
+   string           hostname;                      // HOLLERITH
+   string           ident_user;                    // HOLLERITH
+   LysKOMTime       connection_time;               // Time
+
+   void create(string|array ...args)
+   {
+      username=args[0];                            // HOLLERITH
+      hostname=args[1];                            // HOLLERITH
+      ident_user=args[2];                          // HOLLERITH
+      connection_time=LysKOMTime(@args[3..11]);    // Time
+   }
+
+   array encode()
+   {
+      return
+         ({
+            H(username),                           // HOLLERITH
+            H(hostname),                           // HOLLERITH
+            H(ident_user),                         // HOLLERITH
+            @connection_time->encode(),            // Time
+         });
+   }
+}
+
+constant extendedconftypenames = 
+   ({ "rd_prot", "original", "secret", "letterbox",      
+      "allow_anonymous", "forbid_secret", "reserved2",   
+      "reserved3"                                         });
+
+multiset(string) ExtendedConfType(string bits)
+{
+   multiset(string) res=(<>);
+   foreach (Array.transpose( ({extendedconftypenames,values(bits)}) ),
+            [string name,int z] )
+      res[name]=z-'0';
+   return res;
+}
+
+class TextList
+{
+   int              first_local_no;                // Local-Text-No
+   array(int)       texts;                         // ARRAY Text-No
+
+   void create(string|array ...args)
+   {
+      first_local_no=(int)args[0];                 // Local-Text-No
+      // --- skip array size: args[1]
+      texts=(array(int))args[2];                   // ARRAY Text-No
+   }
+
+   array encode()
+   {
+      return
+         ({
+            first_local_no,                        // Local-Text-No
+            @A((array(string))texts),              // ARRAY Text-No
+         });
+   }
+}
+
+class AuxItemInput
+{
+   int              tag;                           // INT32
+   multiset(string) flags;                         // Aux-Item-Flags
+   int              inherit_limit;                 // INT32
+   string           data;                          // HOLLERITH
+
+   void create(string|array ...args)
+   {
+      tag=(int)args[0];                            // INT32
+      flags=AuxItemFlags(args[1]);                 // Aux-Item-Flags
+      inherit_limit=(int)args[2];                  // INT32
+      data=args[3];                                // HOLLERITH
+   }
+
+   array encode()
+   {
+      return
+         ({
+            tag,                                   // INT32
+            @B(@rows(flags,auxitemflagsnames)),    // Aux-Item-Flags
+            inherit_limit,                         // INT32
+            H(data),                               // HOLLERITH
+         });
+   }
+}
+
+class WhoInfoIdent
+{
+   int(0..65535)    person;                        // Pers-No
+   int(0..65535)    working_conference;            // Conf-No
+   int              session;                       // Session-No
+   string           what_am_i_doing;               // HOLLERITH
+   string           username;                      // HOLLERITH
+   string           hostname;                      // HOLLERITH
+   string           ident_user;                    // HOLLERITH
+
+   void create(string|array ...args)
+   {
+      person=(int)args[0];                         // Pers-No
+      working_conference=(int)args[1];             // Conf-No
+      session=(int)args[2];                        // Session-No
+      what_am_i_doing=args[3];                     // HOLLERITH
+      username=args[4];                            // HOLLERITH
+      hostname=args[5];                            // HOLLERITH
+      ident_user=args[6];                          // HOLLERITH
+   }
+
+   array encode()
+   {
+      return
+         ({
+            person,                                // Pers-No
+            working_conference,                    // Conf-No
+            session,                               // Session-No
+            H(what_am_i_doing),                    // HOLLERITH
+            H(username),                           // HOLLERITH
+            H(hostname),                           // HOLLERITH
+            H(ident_user),                         // HOLLERITH
+         });
+   }
+}
+
+constant conftypenames = 
+   ({ "rd_prot", "original", "secret", "letterbox"        });
+
+multiset(string) ConfType(string bits)
+{
+   multiset(string) res=(<>);
+   foreach (Array.transpose( ({conftypenames,values(bits)}) ),
+            [string name,int z] )
+      res[name]=z-'0';
+   return res;
+}
+
+class ConfZInfo
+{
+   string           name;                          // HOLLERITH
+   multiset(string) type;                          // Conf-Type
+   int(0..65535)    conf_no;                       // Conf-No
+
+   void create(string|array ...args)
+   {
+      name=args[0];                                // HOLLERITH
+      type=ConfType(args[1]);                      // Conf-Type
+      conf_no=(int)args[2];                        // Conf-No
+   }
+
+   array encode()
+   {
+      return
+         ({
+            H(name),                               // HOLLERITH
+            @B(@rows(type,conftypenames)),         // Conf-Type
+            conf_no,                               // Conf-No
+         });
+   }
+}
+
+class WhoInfoOld
+{
+   int(0..65535)    person;                        // Pers-No
+   int(0..65535)    working_conference;            // Conf-No
+   string           what_am_i_doing;               // HOLLERITH
+
+   void create(string|array ...args)
+   {
+      person=(int)args[0];                         // Pers-No
+      working_conference=(int)args[1];             // Conf-No
+      what_am_i_doing=args[2];                     // HOLLERITH
+   }
+
+   array encode()
+   {
+      return
+         ({
+            person,                                // Pers-No
+            working_conference,                    // Conf-No
+            H(what_am_i_doing),                    // HOLLERITH
+         });
+   }
+}
+
+class Mark
+{
+   int              text_no;                       // Text-No
+   int(0..255)      type;                          // INT8
+
+   void create(string|array ...args)
+   {
+      text_no=(int)args[0];                        // Text-No
+      type=(int)args[1];                           // INT8
+   }
+
+   array encode()
+   {
+      return
+         ({
+            text_no,                               // Text-No
+            type,                                  // INT8
+         });
+   }
+}
+
+class Conference
+{
+   string           name;                          // HOLLERITH
+   multiset(string) type;                          // Extended-Conf-Type
+   LysKOMTime       creation_time;                 // Time
+   LysKOMTime       last_written;                  // Time
+   int(0..65535)    creator;                       // Pers-No
+   int              presentation;                  // Text-No
+   int(0..65535)    supervisor;                    // Conf-No
+   int(0..65535)    permitted_submitters;          // Conf-No
+   int(0..65535)    super_conf;                    // Conf-No
+   int              msg_of_day;                    // Text-No
+   int              nice;                          // Garb-Nice
+   int              keep_commented;                // Garb-Nice
+   int(0..65535)    no_of_members;                 // INT16
+   int              first_local_no;                // Local-Text-No
+   int              no_of_texts;                   // INT32
+   int              expire;                        // Garb-Nice
+   array(AuxItem)   aux_items;                     // ARRAY Aux-Item
+
+   void create(string|array ...args)
+   {
+      name=args[0];                                // HOLLERITH
+      type=ExtendedConfType(args[1]);              // Extended-Conf-Type
+      creation_time=LysKOMTime(@args[2..10]);      // Time
+      last_written=LysKOMTime(@args[11..19]);      // Time
+      creator=(int)args[20];                       // Pers-No
+      presentation=(int)args[21];                  // Text-No
+      supervisor=(int)args[22];                    // Conf-No
+      permitted_submitters=(int)args[23];          // Conf-No
+      super_conf=(int)args[24];                    // Conf-No
+      msg_of_day=(int)args[25];                    // Text-No
+      nice=(int)args[26];                          // Garb-Nice
+      keep_commented=(int)args[27];                // Garb-Nice
+      no_of_members=(int)args[28];                 // INT16
+      first_local_no=(int)args[29];                // Local-Text-No
+      no_of_texts=(int)args[30];                   // INT32
+      expire=(int)args[31];                        // Garb-Nice
+      // --- skip array size: args[32]
+      aux_items=                                   // ARRAY Aux-Item
+         Array.map(args[33]/15,
+                   lambda(array z) { return AuxItem(@z); });
+   }
+
+   array encode()
+   {
+      return
+         ({
+            H(name),                               // HOLLERITH
+            @B(@rows(type,extendedconftypenames)), // Extended-Conf-Type
+            @creation_time->encode(),              // Time
+            @last_written->encode(),               // Time
+            creator,                               // Pers-No
+            presentation,                          // Text-No
+            supervisor,                            // Conf-No
+            permitted_submitters,                  // Conf-No
+            super_conf,                            // Conf-No
+            msg_of_day,                            // Text-No
+            nice,                                  // Garb-Nice
+            keep_commented,                        // Garb-Nice
+            no_of_members,                         // INT16
+            first_local_no,                        // Local-Text-No
+            no_of_texts,                           // INT32
+            expire,                                // Garb-Nice
+            A(`+(@Array.map(aux_items,             // ARRAY Aux-Item
+                            lambda(AuxItem z) 
+                               { return z->encode(); }))),
+         });
+   }
+}
+
+class ConferenceOld
+{
+   string           name;                          // HOLLERITH
+   multiset(string) type;                          // Conf-Type
+   LysKOMTime       creation_time;                 // Time
+   LysKOMTime       last_written;                  // Time
+   int(0..65535)    creator;                       // Pers-No
+   int              presentation;                  // Text-No
+   int(0..65535)    supervisor;                    // Conf-No
+   int(0..65535)    permitted_submitters;          // Conf-No
+   int(0..65535)    super_conf;                    // Conf-No
+   int              msg_of_day;                    // Text-No
+   int              nice;                          // Garb-Nice
+   int(0..65535)    no_of_members;                 // INT16
+   int              first_local_no;                // Local-Text-No
+   int              no_of_texts;                   // INT32
+
+   void create(string|array ...args)
+   {
+      name=args[0];                                // HOLLERITH
+      type=ConfType(args[1]);                      // Conf-Type
+      creation_time=LysKOMTime(@args[2..10]);      // Time
+      last_written=LysKOMTime(@args[11..19]);      // Time
+      creator=(int)args[20];                       // Pers-No
+      presentation=(int)args[21];                  // Text-No
+      supervisor=(int)args[22];                    // Conf-No
+      permitted_submitters=(int)args[23];          // Conf-No
+      super_conf=(int)args[24];                    // Conf-No
+      msg_of_day=(int)args[25];                    // Text-No
+      nice=(int)args[26];                          // Garb-Nice
+      no_of_members=(int)args[27];                 // INT16
+      first_local_no=(int)args[28];                // Local-Text-No
+      no_of_texts=(int)args[29];                   // INT32
+   }
+
+   array encode()
+   {
+      return
+         ({
+            H(name),                               // HOLLERITH
+            @B(@rows(type,conftypenames)),         // Conf-Type
+            @creation_time->encode(),              // Time
+            @last_written->encode(),               // Time
+            creator,                               // Pers-No
+            presentation,                          // Text-No
+            supervisor,                            // Conf-No
+            permitted_submitters,                  // Conf-No
+            super_conf,                            // Conf-No
+            msg_of_day,                            // Text-No
+            nice,                                  // Garb-Nice
+            no_of_members,                         // INT16
+            first_local_no,                        // Local-Text-No
+            no_of_texts,                           // INT32
+         });
+   }
+}
+
+class SessionInfoIdent
+{
+   int(0..65535)    person;                        // Pers-No
+   int(0..65535)    working_conference;            // Conf-No
+   int              session;                       // Session-No
+   string           what_am_i_doing;               // HOLLERITH
+   string           username;                      // HOLLERITH
+   string           hostname;                      // HOLLERITH
+   string           ident_user;                    // HOLLERITH
+   int              idle_time;                     // INT32
+   LysKOMTime       connection_time;               // Time
+
+   void create(string|array ...args)
+   {
+      person=(int)args[0];                         // Pers-No
+      working_conference=(int)args[1];             // Conf-No
+      session=(int)args[2];                        // Session-No
+      what_am_i_doing=args[3];                     // HOLLERITH
+      username=args[4];                            // HOLLERITH
+      hostname=args[5];                            // HOLLERITH
+      ident_user=args[6];                          // HOLLERITH
+      idle_time=(int)args[7];                      // INT32
+      connection_time=LysKOMTime(@args[8..16]);    // Time
+   }
+
+   array encode()
+   {
+      return
+         ({
+            person,                                // Pers-No
+            working_conference,                    // Conf-No
+            session,                               // Session-No
+            H(what_am_i_doing),                    // HOLLERITH
+            H(username),                           // HOLLERITH
+            H(hostname),                           // HOLLERITH
+            H(ident_user),                         // HOLLERITH
+            idle_time,                             // INT32
+            @connection_time->encode(),            // Time
+         });
+   }
+}
+
+class VersionInfo
+{
+   int              protocol_version;              // INT32
+   string           server_software;               // HOLLERITH
+   string           software_version;              // HOLLERITH
+
+   void create(string|array ...args)
+   {
+      protocol_version=(int)args[0];               // INT32
+      server_software=args[1];                     // HOLLERITH
+      software_version=args[2];                    // HOLLERITH
+   }
+
+   array encode()
+   {
+      return
+         ({
+            protocol_version,                      // INT32
+            H(server_software),                    // HOLLERITH
+            H(software_version),                   // HOLLERITH
+         });
+   }
+}
+
+class ConfListArchaic
+{
+   array(int(0..65535)) conf_nos;                  // ARRAY Conf-No
+   array(multiset(string)) conf_types;             // ARRAY Conf-Type
+
+   void create(string|array ...args)
+   {
+      // --- skip array size: args[0]
+      conf_nos=(array(int))args[1];                // ARRAY Conf-No
+      // --- skip array size: args[2]
+      conf_types=                                  // ARRAY Conf-Type
+         Array.map(args[3],
+                   lambda(string z) { return ConfType(z); });
+   }
+
+   array encode()
+   {
+      return
+         ({
+            @A((array(string))conf_nos),           // ARRAY Conf-No
+            A(`+(@Array.map(conf_types,            // ARRAY Conf-Type
+                            lambda(multiset(string) z) 
+                               { return B(@rows(z,conftypenames)); }))),
+         });
+   }
+}
+
+constant privbitsnames = 
+   ({ "wheel", "admin", "statistic", "create_pers",      
+      "create_conf", "change_name", "flg7", "flg8",      
+      "flg9", "flg10", "flg11", "flg12", "flg13",        
+      "flg14", "flg15", "flg16"                           });
+
+multiset(string) PrivBits(string bits)
+{
+   multiset(string) res=(<>);
+   foreach (Array.transpose( ({privbitsnames,values(bits)}) ),
+            [string name,int z] )
+      res[name]=z-'0';
+   return res;
+}
+
+class UConference
+{
+   string           name;                          // HOLLERITH
+   multiset(string) type;                          // Extended-Conf-Type
+   int              highest_local_no;              // Local-Text-No
+   int              nice;                          // Garb-Nice
+
+   void create(string|array ...args)
+   {
+      name=args[0];                                // HOLLERITH
+      type=ExtendedConfType(args[1]);              // Extended-Conf-Type
+      highest_local_no=(int)args[2];               // Local-Text-No
+      nice=(int)args[3];                           // Garb-Nice
+   }
+
+   array encode()
+   {
+      return
+         ({
+            H(name),                               // HOLLERITH
+            @B(@rows(type,extendedconftypenames)), // Extended-Conf-Type
+            highest_local_no,                      // Local-Text-No
+            nice,                                  // Garb-Nice
+         });
+   }
+}
+
+class Person
+{
+   string           username;                      // HOLLERITH
+   multiset(string) privileges;                    // Priv-Bits
+   multiset(string) flags;                         // Personal-Flags
+   LysKOMTime       last_login;                    // Time
+   int              user_area;                     // Text-No
+   int              total_time_present;            // INT32
+   int              sessions;                      // INT32
+   int              created_lines;                 // INT32
+   int              created_bytes;                 // INT32
+   int              read_texts;                    // INT32
+   int              no_of_text_fetches;            // INT32
+   int(0..65535)    created_persons;               // INT16
+   int(0..65535)    created_confs;                 // INT16
+   int              first_created_local_no;        // INT32
+   int              no_of_created_texts;           // INT32
+   int(0..65535)    no_of_marks;                   // INT16
+   int(0..65535)    no_of_confs;                   // INT16
+
+   void create(string|array ...args)
+   {
+      username=args[0];                            // HOLLERITH
+      privileges=PrivBits(args[1]);                // Priv-Bits
+      flags=PersonalFlags(args[2]);                // Personal-Flags
+      last_login=LysKOMTime(@args[3..11]);         // Time
+      user_area=(int)args[12];                     // Text-No
+      total_time_present=(int)args[13];            // INT32
+      sessions=(int)args[14];                      // INT32
+      created_lines=(int)args[15];                 // INT32
+      created_bytes=(int)args[16];                 // INT32
+      read_texts=(int)args[17];                    // INT32
+      no_of_text_fetches=(int)args[18];            // INT32
+      created_persons=(int)args[19];               // INT16
+      created_confs=(int)args[20];                 // INT16
+      first_created_local_no=(int)args[21];        // INT32
+      no_of_created_texts=(int)args[22];           // INT32
+      no_of_marks=(int)args[23];                   // INT16
+      no_of_confs=(int)args[24];                   // INT16
+   }
+
+   array encode()
+   {
+      return
+         ({
+            H(username),                           // HOLLERITH
+            @B(@rows(privileges,privbitsnames)),   // Priv-Bits
+            @B(@rows(flags,personalflagsnames)),   // Personal-Flags
+            @last_login->encode(),                 // Time
+            user_area,                             // Text-No
+            total_time_present,                    // INT32
+            sessions,                              // INT32
+            created_lines,                         // INT32
+            created_bytes,                         // INT32
+            read_texts,                            // INT32
+            no_of_text_fetches,                    // INT32
+            created_persons,                       // INT16
+            created_confs,                         // INT16
+            first_created_local_no,                // INT32
+            no_of_created_texts,                   // INT32
+            no_of_marks,                           // INT16
+            no_of_confs,                           // INT16
+         });
+   }
+}
+
+
diff --git a/lib/modules/Protocols.pmod/LysKOM.pmod/Raw.pike b/lib/modules/Protocols.pmod/LysKOM.pmod/Raw.pike
new file mode 100644
index 0000000000..ce776491c9
--- /dev/null
+++ b/lib/modules/Protocols.pmod/LysKOM.pmod/Raw.pike
@@ -0,0 +1,453 @@
+import .Helper;
+
+/* debug */
+// function f=lambda()
+// {
+//    call_out(f,0.5);
+
+//    if (!con) 
+//       return;
+
+//    if (con->query_read_callback()!=recv)
+//       werror("no read callback\n");
+
+//    werror("asyncs: %4d queue: %4d out: %4d\n",
+// 	  sizeof(indices(async)),
+// 	  sizeof(sendqueue),
+// 	  out_req);
+// };
+// mixed g=f();
+
+//---------------- raw protocol --------------------------
+
+/* connection object */
+object con;
+
+/* recieve buffer */
+string buf="";
+
+/* outstanding calls */
+mapping(int:function(string:void)) async=([]);
+int ref=1;
+
+/* asynchronous messages callback list */
+mapping(int:function(string:void)) async_callbacks=([]);
+
+/* max number of outstanding requests */
+int max_out_req=4;
+
+/* queue of send-objects */
+array(object) sendqueue=({});
+
+/* outstanding requests */
+int out_req;
+
+
+/*--- send/recv ------------------------ */
+
+static inline int conwrite(string what)
+{
+#ifdef LYSKOM_DEBUG
+   werror("-> %O\n",what);
+#endif
+   int i=con->write(what)==strlen(what);
+   if (!i) { werror("write failed!!!\n"); _exit(1); }
+   return i;
+}
+
+class Send
+{
+   int ref;
+   string request;
+   function(string:void) callback;
+   
+   void create(int rf,string r,function(string:void) c)
+   {
+      ref=rf;
+      request=r;
+      callback=c;
+   }
+   int cast(string i) { return ref; }
+   void write()
+   {
+      out_req++;
+      conwrite(ref+" "+request+"\r\n");
+      async[ref]=callback;
+   }
+}
+
+int send(string request,
+	 function(string:void) callback)
+{
+   int r=++ref;
+   sendqueue+=({Send(r,request,callback)});
+   flush_queue();
+   return r;
+}
+
+void flush_queue()
+{
+   while (sizeof(sendqueue) && out_req<max_out_req)
+   {
+      sendqueue[0]->write();
+      sendqueue=sendqueue[1..];
+   }
+}
+
+mixed send_sync(string request)
+{
+   return sync_do(++ref,request);
+}
+
+mixed sync_do(int ref,string|void request)
+{
+   mixed err;
+   string s;
+   array res;
+
+   con->set_blocking();
+   if (request)
+   {
+      if (!conwrite(ref+" "+request+"\r\n"))
+      {
+	 connection_lost();
+	 return lyskom_error(CONNECTION_CLOSED);
+      }
+      out_req++;
+   }
+   else
+   {
+      array(int) o=(array(int))sendqueue;
+      int j=search(o,ref);
+      if (j==-1) 
+      {
+	 if (!async[ref])
+	    error("request ref %d not in queue, but no callback\n",ref);
+	 m_delete(async,ref);
+      }
+      else
+      {
+	 sendqueue[j]->write();
+	 sendqueue=sendqueue[..j-1]+sendqueue[j+1..];
+      }
+   }
+
+   for (;;)
+   {
+      s=con->read(0x7fffffff,1);
+      if (s=="") 
+      {
+	 con->set_nonblocking(recv,0,0);
+	 connection_lost();
+	 return lyskom_error(CONNECTION_CLOSED);
+      }
+      err=catch { res=recv(0,s,ref); };
+      if (err)
+      {
+	 con->set_nonblocking(recv,0,0);
+	 throw(err);
+      }
+      if (res) break;
+   }
+
+   con->set_nonblocking(recv,0,0);
+
+   return res;
+}
+
+void|array|object recv(mixed x,string what,void|int syn)
+{
+#ifdef LYSKOM_DEBUG
+   werror("<- %O\n",what);
+#endif
+//    werror("<- (%d bytes) (%d asyncs left)\n",sizeof(what),
+// 	  sizeof(indices(async)));
+
+   array|object ires=0;
+   buf+=what;
+   // wait for newline before we do anything at all
+   while (search(buf,"\n")!=-1)
+   {
+      mixed res;
+      int len;
+      // ok, try to figure out what we got
+      switch (buf[0])
+      {
+	 case ':':
+	    [res,len]=try_parse(buf[1..]);
+	    if (res)
+	    {
+	       buf=buf[len+1..];
+	       if (ref)
+		  call_out(got_async_message,0,res);
+	       else
+		  got_async_message(res);
+	       break;
+	    }
+	    return;
+
+	 case '=':
+	    [res,len]=try_parse(buf[1..]);
+	    if (res)
+	    {
+	       buf=buf[len+1..];
+	       if (syn && (int)res[0] == syn)
+	       {
+		  ires=res[1..]; // this is what we wait for
+		  out_req--;
+		  break;
+	       }
+	       if (ref)
+		  call_out(got_reply,0,(int)res[0],res[1..]);
+	       else
+		  got_reply((int)res[0],res[1..]);
+	       out_req--;
+	       flush_queue();
+	       break;
+	    }
+	    return;
+
+	 case '%':
+	    sscanf(buf,"%s\n%s",res,buf);
+	    int ref,no,status;
+	    if (sscanf(res,"%%%d %d %d",ref,no,status)==3)
+	    {
+	       if (ref==syn)
+	       {
+		  ires=lyskom_error(no,status);
+		  out_req--;
+		  break;
+	       }
+	       if (ref)
+		  call_out(got_reply,0,ref,lyskom_error(no,status));
+	       else
+		  got_reply(ref,lyskom_error(no,status));
+	       out_req--;
+	       flush_queue();
+	    }
+	    else
+	    {
+	       werror("LysKOM.Raw: generic error recieved: %O\n",res);
+	    }
+	    break;
+
+	 default:
+	    werror("LysKOM.Raw: protocol error: %O\n",buf);
+	    connection_lost();
+	    return;
+      }
+   }
+   return ires;
+}
+
+void connection_lost()
+{
+   werror("CONNECTION LOST\n");
+   catch { con->close(); };
+   con=0;
+   // send error to all outstanding requests
+   foreach (values(async),function f)
+      if (f) f(lyskom_error(CONNECTION_CLOSED));
+}
+
+void create(string server,void|int port,void|string whoami)
+{
+   mixed err;
+
+   if (!port) port=4894;
+   con=Stdio.File();
+   err=catch {
+      if (!con->connect(server,port))
+      {
+	 object err=LysKOMError(-1,strerror(con->errno())-"\n",
+				"Failed to connect to server "
+				+server+".\n");
+	 throw(err);
+	 return;
+      }
+   };
+   if (err)
+   {
+      if (objectp(err) && err->iserror) throw(err);
+      err=LysKOMError(-1,err[0]-"\n",
+		      "Failed to connect to server "
+		      +server+".\n");
+      throw(err);
+   }
+   
+
+   conwrite("A"+H(whoami||
+#if constant(getpwuid) && constant(getuid)
+		  (getpwuid(getuid())||({"*unknown*"}))[0]+
+#else
+		  "*unknown*"
+#endif
+		  "%"
+#if constant(uname)
+		  +uname()->nodename
+#else
+		  "*unknown*"
+#endif
+		  ));
+   string reply=con->read(7);
+#ifdef LYSKOM_DEBUG
+   werror("<- %O\n",reply);
+#endif
+   if (reply!="LysKOM\n")
+   {
+      con->close();
+      con=0;
+      return;
+   }
+   con->set_nonblocking(recv,0,0);
+   return;
+}
+
+void set_async_callbacks(mapping(int:function(string:void)) m)
+{
+   async_callbacks=m;
+}
+
+array(array(mixed)|int) try_parse(string what)
+{
+   array res=({});
+   int len=0;
+   
+   array stack=({});
+
+   while (strlen(what)>1)
+   {
+      string a,b;
+
+      switch(what[0])
+      {
+	 case '0'..'9':
+	    // int, bitfield or hollerith
+
+	    if (sscanf(what,"%[0-9]%s",a,b)<2 ||
+		b=="") 
+	       return ({0,0}); // incomplete
+
+	    if (b[0]=='H') // hollerith
+	    {
+	       if (strlen(b)<=(int)a)
+		  return ({0,0}); // incomplete
+	       res+=({b[1..(int)a]});
+	       len+=strlen(a)+strlen(res[-1])+2;
+	       b=b[(int)a+1..];
+	    }
+	    else // bitfield or int
+	    {
+	       res+=({a});
+	       len+=strlen(a)+1;
+	    }
+
+	    if (b=="") return ({0,0}); // incomplete
+
+	    switch (b[0])
+	    {
+	       case ' ': // cont
+		  break;
+	       case '\n': // done
+// 		  werror("ret: len=%d %O\n",len,res);
+		  return ({res,len});
+	       default:
+		  werror("reached unknown: %O\n",b);
+		  exit(-1);
+	    }
+
+	    what=b[1..];
+
+	    break;
+
+	 case '{': // array start;
+	    if (what[..1]=="{ ")
+	    {
+	       stack=({res})+stack;
+	       res=({});
+	       len+=2;
+	       what=what[2..];
+	       break;
+	    }
+	    if (what[..1]!="{")
+	    {
+	       werror("reached unknown: %O\n",what);
+	       exit(-1);
+	    }
+	    return ({0,0});
+
+	 case '*': // empty array
+	    res+=({({})});
+	    len+=2;
+	    switch (what[1])
+	    {
+	       case ' ': // cont
+		  break;
+	       case '\n': // done
+		  return ({res,len});
+	       default:
+		  werror("reached unknown: %O\n",b);
+		  exit(-1);
+	    }
+	    what=what[2..];
+	    break;
+
+	 case '}': // array end;
+
+	    if (stack==({}))
+	    {
+	       werror("protocol error: stack underflow\n",what);
+	       connection_lost();
+	       return ({0,0});
+	    }
+
+	    res=stack[0]+({res});
+	    stack=stack[1..];
+	    
+	    len+=2;
+
+	    switch (what[1])
+	    {
+	       case ' ': // cont
+		  break;
+	       case '\n': // done
+		  return ({res,len});
+	       default:
+		  werror("reached unknown: %O\n",b);
+		  exit(-1);
+	    }
+
+	    what=what[2..];
+	    break;
+
+	 default:
+	    werror("reached unknown: %O\n",what);
+	    exit(-1);
+      }
+   }
+   
+   return ({0,0}); // incomplete
+}
+
+void got_async_message(array what)
+{
+   // werror("got async: %O\n",what);
+}
+
+void got_reply(int ref,object|array what)
+{
+   function call=async[ref];
+   if (!call)
+   {
+      werror("LysKOM.Raw: lost callback for call %d\n",ref);
+      werror(master()->describe_backtrace(backtrace()));
+      return;
+   }
+   m_delete(async,ref);
+   call_out(call,0,what);
+}
+
+void delete_async(int ref)
+{
+   m_delete(async,ref);
+}
diff --git a/lib/modules/Protocols.pmod/LysKOM.pmod/Request.pmod b/lib/modules/Protocols.pmod/LysKOM.pmod/Request.pmod
new file mode 100644
index 0000000000..66df35c90f
--- /dev/null
+++ b/lib/modules/Protocols.pmod/LysKOM.pmod/Request.pmod
@@ -0,0 +1,2560 @@
+//  $Id: Request.pmod,v 1.1 1999/06/12 23:01:50 mirar Exp $
+//! module Protocols
+//! submodule LysKOM
+//! submodule Request
+//!	This class contains nice abstraction for calls into the
+//!	server. They are named "<i>call</i>", 
+//!	"<tt>async_</tt><i>call</i>" or 
+//!	"<tt>async_cb_</tt><i>call</i>", depending on 
+//!	how you want the call to be done. 
+
+import .Helper;
+import .ProtocolTypes;
+
+int _no=1;
+
+//! class _Request
+//!	This is the main request class. All lyskom request
+//!	classes inherits this class.
+//!
+//! method void async(mixed ...args)
+//! method mixed sync(mixed ...args)
+//!	initialise an asynchronous or a synchronous call,
+//!	the latter is also evaluating the result. This calls
+//!	'indata' in itself, to get the correct arguments to 
+//!	the lyskom protocol call.
+//!
+//! method void _async(int call, mixed_data)
+//! method mixed _sync(int call, mixed_data)
+//!	initialise an asynchronous or a synchronous call,
+//!	the latter is also evaluating the result. These
+//!	are called by async and sync respectively.
+//!
+//! method mixed _reply(object|array what)
+//! method mixed reply(object|array what)
+//!	_reply is called as callback to evaluate the result, 
+//!	and calls reply in itself to do the real work.
+//!
+//! method mixed `()()
+//!	wait for the call to finish.
+//!
+//! variable int ok
+//!	tells if the call is executed ok
+//! variable object error
+//!	how the call failed
+//!	The call is completed if (ok||error).
+//!
+
+class _Request
+{
+   private Stdio.File raw;
+   private int ref;
+
+   private mixed res;
+
+#if constant(thread_create)
+   private object wait_lock;
+   private object wait_mutex;
+#endif
+
+   function callback;
+
+   void _async(int call,mixed ... data)
+   {
+      ref=raw->send(encode(call,@data),_reply);
+   }
+   
+   mixed _sync(int call,mixed ... data)
+   {
+      mixed res=raw->send_sync(encode(call,@data),_reply);
+      return _reply(res);
+   }
+
+   mixed _reply(object|array what)
+   {
+      if (objectp(what))
+      {
+	 error=what;
+	 failure(what);
+      }
+      else
+      {
+	 ok=1;
+	 res=reply(what);
+      }
+#if constant(thread_create)
+      if (wait_lock)
+	 destruct(wait_lock);
+#endif
+      if (callback) callback(error||res);
+
+      return res;
+   }
+
+   mixed reply(array what); // virtual
+   void failure(object err); // virtual
+   array indata(mixed ...); // virtual
+
+#if constant(thread_create)
+   mixed `()() // wait
+   {
+      if (ok || error) return res;
+      wait_mutex=Thread.Mutex();
+      wait_lock=wait_mutex->lock(); // lock it
+      wait_lock=wait_mutex->lock(1); // lock it again, ie wait
+      return res;
+   }
+#else
+   mixed `()() // wait
+   {
+      if (ok || error) return res;
+      mixed tmp=_reply(raw->sync_do(ref));
+      return tmp;
+   }
+#endif
+
+   // public
+
+   int(0..1) ok;
+   object error;
+
+   void create(Stdio.File _raw)
+   {
+      raw=_raw;
+   }
+
+   void async(mixed ...args)
+   {
+      _async(@indata(@args));
+   }
+
+   mixed sync(mixed ...args)
+   {
+      return _sync(@indata(@args));
+   }
+}
+
+//
+// automatically generated requests
+//
+
+/* 0 */
+class Login_old
+{
+   inherit _Request;
+
+   array indata(int(0..65535) person,
+                string passwd)
+   {
+      return ({0,
+               person,
+               H(passwd)});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 1 */
+class Logout
+{
+   inherit _Request;
+
+   array indata()
+   {
+      return ({1});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 2 */
+class Change_conference
+{
+   inherit _Request;
+
+   array indata(int(0..65535) conference)
+   {
+      return ({2,
+               conference});
+   }
+
+   int(0..65535) reply(array what)
+   {
+      return what[0]; /* INT16 */
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 3 */
+class Change_name
+{
+   inherit _Request;
+
+   array indata(int(0..65535) conference,
+                string new_name)
+   {
+      return ({3,
+               conference,
+               H(new_name)});
+   }
+
+   string reply(array what)
+   {
+      return what[0]; /* HOLLERITH */
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 4 */
+class Change_what_i_am_doing
+{
+   inherit _Request;
+
+   array indata(string what_am_i_doing)
+   {
+      return ({4,
+               H(what_am_i_doing)});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 5 */
+class Create_person_old
+{
+   inherit _Request;
+
+   array indata(string name,
+                string passwd)
+   {
+      return ({5,
+               H(name),
+               H(passwd)});
+   }
+
+   string reply(array what)
+   {
+      return what[0]; /* HOLLERITH */
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 6 */
+class Get_person_stat_old
+{
+   inherit _Request;
+
+   array indata(int(0..65535) person,
+                int mask)
+   {
+      return ({6,
+               person,
+               mask});
+   }
+
+
+   Person person;
+
+   Person reply(array what)
+   {
+      /* ( Person ) */
+      return Person(@what);
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 7 */
+class Set_priv_bits
+{
+   inherit _Request;
+
+   array indata(int(0..65535) person,
+                multiset(string) privileges)
+   {
+      return ({7,
+               person,
+               @B(@rows(privileges,privbitsnames))});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 8 */
+class Set_passwd
+{
+   inherit _Request;
+
+   array indata(int(0..65535) person,
+                string old_pwd,
+                string new_pwd)
+   {
+      return ({8,
+               person,
+               H(old_pwd),
+               H(new_pwd)});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 9 */
+class Query_read_texts_old
+{
+   inherit _Request;
+
+   array indata(int(0..65535) person,
+                int(0..65535) conference)
+   {
+      return ({9,
+               person,
+               conference});
+   }
+
+
+   MembershipOld membershipold;
+
+   MembershipOld reply(array what)
+   {
+      /* ( Membership-Old ) */
+      return MembershipOld(@what);
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 10 */
+class Create_conf_old
+{
+   inherit _Request;
+
+   array indata(string name,
+                multiset(string) type)
+   {
+      return ({10,
+               H(name),
+               @B(@rows(type,extendedconftypenames))});
+   }
+
+   int(0..65535) reply(array what)
+   {
+      return what[0]; /* Conf-No */
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 11 */
+class Delete_conf
+{
+   inherit _Request;
+
+   array indata(int(0..65535) conf)
+   {
+      return ({11,
+               conf});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 12 */
+class Lookup_name
+{
+   inherit _Request;
+
+   array indata(string name)
+   {
+      return ({12,
+               H(name)});
+   }
+
+
+   ConfListArchaic conflistarchaic;
+
+   ConfListArchaic reply(array what)
+   {
+      /* ( Conf-List-Archaic ) */
+      return ConfListArchaic(@what);
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 13 */
+class Get_conf_stat_older
+{
+   inherit _Request;
+
+   array indata(int(0..65535) conf_no,
+                int mask)
+   {
+      return ({13,
+               conf_no,
+               mask});
+   }
+
+
+   ConferenceOld conferenceold;
+
+   ConferenceOld reply(array what)
+   {
+      /* ( Conference-Old ) */
+      return ConferenceOld(@what);
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 14 */
+class Add_member_old
+{
+   inherit _Request;
+
+   array indata(int(0..65535) conf_no,
+                int(0..65535) pers_no,
+                int(0..255) priority,
+                int(0..65535) where)
+   {
+      return ({14,
+               conf_no,
+               pers_no,
+               priority,
+               where});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 15 */
+class Sub_member
+{
+   inherit _Request;
+
+   array indata(int(0..65535) conf_no,
+                int(0..65535) pers_no)
+   {
+      return ({15,
+               conf_no,
+               pers_no});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 16 */
+class Set_presentation
+{
+   inherit _Request;
+
+   array indata(int(0..65535) conf_no,
+                int text_no)
+   {
+      return ({16,
+               conf_no,
+               text_no});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 17 */
+class Set_etc_motd
+{
+   inherit _Request;
+
+   array indata(int(0..65535) conf_no,
+                int text_no)
+   {
+      return ({17,
+               conf_no,
+               text_no});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 18 */
+class Set_supervisor
+{
+   inherit _Request;
+
+   array indata(int(0..65535) conf_no,
+                int(0..65535) admin)
+   {
+      return ({18,
+               conf_no,
+               admin});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 19 */
+class Set_permitted_submitters
+{
+   inherit _Request;
+
+   array indata(int(0..65535) conf_no,
+                int(0..65535) perm_sub)
+   {
+      return ({19,
+               conf_no,
+               perm_sub});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 20 */
+class Set_super_conf
+{
+   inherit _Request;
+
+   array indata(int(0..65535) conf_no,
+                int(0..65535) super_conf)
+   {
+      return ({20,
+               conf_no,
+               super_conf});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 21 */
+class Set_conf_type
+{
+   inherit _Request;
+
+   array indata(int(0..65535) conf_no,
+                multiset(string) type)
+   {
+      return ({21,
+               conf_no,
+               @B(@rows(type,extendedconftypenames))});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 22 */
+class Set_garb_nice
+{
+   inherit _Request;
+
+   array indata(int(0..65535) conf_no,
+                int nice)
+   {
+      return ({22,
+               conf_no,
+               nice});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 23 */
+class Get_marks
+{
+   inherit _Request;
+
+   array indata()
+   {
+      return ({23});
+   }
+
+
+   array(Mark) marks;
+
+   array(Mark) reply(array what)
+   {
+      /* ( ARRAY Mark ) */
+      return marks=Array.map(what[1]/2,
+                                lambda(array z) { return Mark(@z); });
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 24 */
+class Mark_text_old
+{
+   inherit _Request;
+
+   array indata(int text,
+                int(0..255) mark_type)
+   {
+      return ({24,
+               text,
+               mark_type});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 25 */
+class Get_text
+{
+   inherit _Request;
+
+   array indata(int text,
+                int start_char,
+                int end_char)
+   {
+      return ({25,
+               text,
+               start_char,
+               end_char});
+   }
+
+   string reply(array what)
+   {
+      return what[0]; /* HOLLERITH */
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 26 */
+class Get_text_stat_old
+{
+   inherit _Request;
+
+   array indata(int text_no)
+   {
+      return ({26,
+               text_no});
+   }
+
+
+   TextStatOld textstatold;
+
+   TextStatOld reply(array what)
+   {
+      /* ( Text-Stat-Old ) */
+      return TextStatOld(@what);
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 27 */
+class Mark_as_read
+{
+   inherit _Request;
+
+   array indata(int(0..65535) conference,
+                array(int) text)
+   {
+      return ({27,
+               conference,
+               @A((array(string))text)});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 28 */
+class Create_text_old
+{
+   inherit _Request;
+
+   array indata(string text,
+                array(int) misc_info)
+   {
+      return ({28,
+               H(text),
+               @A((array(string))misc_info)});
+   }
+
+   int reply(array what)
+   {
+      return what[0]; /* Text-No */
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 29 */
+class Delete_text
+{
+   inherit _Request;
+
+   array indata(int text)
+   {
+      return ({29,
+               text});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 30 */
+class Add_recipient
+{
+   inherit _Request;
+
+   array indata(int text_no,
+                int(0..65535) conf_no,
+                int recpt_type)
+   {
+      return ({30,
+               text_no,
+               conf_no,
+               recpt_type});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 31 */
+class Sub_recipient
+{
+   inherit _Request;
+
+   array indata(int text_no,
+                int(0..65535) conf_no)
+   {
+      return ({31,
+               text_no,
+               conf_no});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 32 */
+class Add_comment
+{
+   inherit _Request;
+
+   array indata(int text_no,
+                int comment_to)
+   {
+      return ({32,
+               text_no,
+               comment_to});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 33 */
+class Sub_comment
+{
+   inherit _Request;
+
+   array indata(int text_no,
+                int comment_to)
+   {
+      return ({33,
+               text_no,
+               comment_to});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 34 */
+class Get_map
+{
+   inherit _Request;
+
+   array indata(int(0..65535) conf_no,
+                int first_local_no,
+                int no_of_texts)
+   {
+      return ({34,
+               conf_no,
+               first_local_no,
+               no_of_texts});
+   }
+
+
+   TextList textlist;
+
+   TextList reply(array what)
+   {
+      /* ( Text-List ) */
+      return TextList(@what);
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 35 */
+class Get_time
+{
+   inherit _Request;
+
+   array indata()
+   {
+      return ({35});
+   }
+
+
+   LysKOMTime lyskomtime;
+
+   LysKOMTime reply(array what)
+   {
+      /* ( Time ) */
+      return LysKOMTime(@what);
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 36 */
+class Get_info_old
+{
+   inherit _Request;
+
+   array indata()
+   {
+      return ({36});
+   }
+
+
+   InfoOld infoold;
+
+   InfoOld reply(array what)
+   {
+      /* ( Info-Old ) */
+      return InfoOld(@what);
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 37 */
+class Add_footnote
+{
+   inherit _Request;
+
+   array indata(int text_no)
+   {
+      return ({37,
+               text_no});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 38 */
+class Sub_footnote
+{
+   inherit _Request;
+
+   array indata(int text_no,
+                int footnote_to)
+   {
+      return ({38,
+               text_no,
+               footnote_to});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 39 */
+class Who_is_on_old
+{
+   inherit _Request;
+
+   array indata()
+   {
+      return ({39});
+   }
+
+
+   array(WhoInfoOld) whoinfoolds;
+
+   array(WhoInfoOld) reply(array what)
+   {
+      /* ( ARRAY Who-Info-Old ) */
+      return whoinfoolds=Array.map(what[1]/3,
+                                lambda(array z) { return WhoInfoOld(@z); });
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 40 */
+class Set_unread
+{
+   inherit _Request;
+
+   array indata(int(0..65535) conf_no,
+                int no_of_unread)
+   {
+      return ({40,
+               conf_no,
+               no_of_unread});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 41 */
+class Set_motd_of_lyskom
+{
+   inherit _Request;
+
+   array indata(int text_no)
+   {
+      return ({41,
+               text_no});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 42 */
+class Enable
+{
+   inherit _Request;
+
+   array indata(int(0..255) level)
+   {
+      return ({42,
+               level});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 43 */
+class Sync_kom
+{
+   inherit _Request;
+
+   array indata()
+   {
+      return ({43});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 44 */
+class Shutdown_kom
+{
+   inherit _Request;
+
+   array indata(int(0..255) exit_val)
+   {
+      return ({44,
+               exit_val});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 45 */
+class Broadcast
+{
+   inherit _Request;
+
+   array indata(string message)
+   {
+      return ({45,
+               H(message)});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 46 */
+class Get_membership_old
+{
+   inherit _Request;
+
+   array indata(int(0..65535) person,
+                int(0..65535) first,
+                int(0..65535) no_of_confs,
+                int(0..1) want_read_texts)
+   {
+      return ({46,
+               person,
+               first,
+               no_of_confs,
+               B(want_read_texts)});
+   }
+
+
+   array(MembershipOld) membershipolds;
+
+   array(MembershipOld) reply(array what)
+   {
+      /* ( ARRAY Membership-Old ) */
+      return membershipolds=Array.map(what[1]/14,
+                                lambda(array z) { return MembershipOld(@z); });
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 47 */
+class Get_created_texts
+{
+   inherit _Request;
+
+   array indata(int(0..65535) person,
+                int first,
+                int no_of_texts)
+   {
+      return ({47,
+               person,
+               first,
+               no_of_texts});
+   }
+
+
+   TextList textlist;
+
+   TextList reply(array what)
+   {
+      /* ( Text-List ) */
+      return TextList(@what);
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 48 */
+class Get_members_old
+{
+   inherit _Request;
+
+   array indata(int(0..65535) conf,
+                int(0..65535) first,
+                int(0..65535) no_of_members)
+   {
+      return ({48,
+               conf,
+               first,
+               no_of_members});
+   }
+
+   array(int(0..65535)) persnos;
+
+   array(int(0..65535)) reply(array what)
+   {
+      /* ( ARRAY Pers-No ) */
+      return (array(int(0..65535)))what[1];
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 49 */
+class Get_person_stat
+{
+   inherit _Request;
+
+   array indata(int(0..65535) pers_no)
+   {
+      return ({49,
+               pers_no});
+   }
+
+
+   Person person;
+
+   Person reply(array what)
+   {
+      /* ( Person ) */
+      return Person(@what);
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 50 */
+class Get_conf_stat_old
+{
+   inherit _Request;
+
+   array indata(int(0..65535) conf_no)
+   {
+      return ({50,
+               conf_no});
+   }
+
+
+   ConferenceOld conferenceold;
+
+   ConferenceOld reply(array what)
+   {
+      /* ( Conference-Old ) */
+      return ConferenceOld(@what);
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 51 */
+class Who_is_on
+{
+   inherit _Request;
+
+   array indata()
+   {
+      return ({51});
+   }
+
+
+   array(WhoInfo) whoinfos;
+
+   array(WhoInfo) reply(array what)
+   {
+      /* ( ARRAY Who-Info ) */
+      return whoinfos=Array.map(what[1]/5,
+                                lambda(array z) { return WhoInfo(@z); });
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 52 */
+class Get_unread_confs
+{
+   inherit _Request;
+
+   array indata(int(0..65535) pers_no)
+   {
+      return ({52,
+               pers_no});
+   }
+
+   array(int(0..65535)) confnos;
+
+   array(int(0..65535)) reply(array what)
+   {
+      /* ( ARRAY Conf-No ) */
+      return (array(int(0..65535)))what[1];
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 53 */
+class Send_message
+{
+   inherit _Request;
+
+   array indata(int(0..65535) recipient,
+                string message)
+   {
+      return ({53,
+               recipient,
+               H(message)});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 58 */
+class Get_last_text
+{
+   inherit _Request;
+
+   array indata(LysKOMTime before)
+   {
+      return ({58,
+               @before->encode()});
+   }
+
+   int reply(array what)
+   {
+      return what[0]; /* Text-No */
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 59 */
+class Create_anonymous_text_old
+{
+   inherit _Request;
+
+   array indata(string text,
+                array(int) misc_info)
+   {
+      return ({59,
+               H(text),
+               @A((array(string))misc_info)});
+   }
+
+   int reply(array what)
+   {
+      return what[0]; /* Text-No */
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 60 */
+class Find_next_text_no
+{
+   inherit _Request;
+
+   array indata(int start)
+   {
+      return ({60,
+               start});
+   }
+
+   int reply(array what)
+   {
+      return what[0]; /* Text-No */
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 61 */
+class Find_previous_text_no
+{
+   inherit _Request;
+
+   array indata(int start)
+   {
+      return ({61,
+               start});
+   }
+
+   int reply(array what)
+   {
+      return what[0]; /* Text-No */
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 62 */
+class Login
+{
+   inherit _Request;
+
+   array indata(int(0..65535) person,
+                string passwd,
+                int(0..1) is_invisible)
+   {
+      return ({62,
+               person,
+               H(passwd),
+               B(is_invisible)});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 63 */
+class Who_is_on_ident
+{
+   inherit _Request;
+
+   array indata()
+   {
+      return ({63});
+   }
+
+
+   array(WhoInfoIdent) whoinfoidents;
+
+   array(WhoInfoIdent) reply(array what)
+   {
+      /* ( ARRAY Who-Info-Ident ) */
+      return whoinfoidents=Array.map(what[1]/7,
+                                lambda(array z) { return WhoInfoIdent(@z); });
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 64 */
+class Get_session_info_ident
+{
+   inherit _Request;
+
+   array indata(int session_no)
+   {
+      return ({64,
+               session_no});
+   }
+
+
+   SessionInfoIdent sessioninfoident;
+
+   SessionInfoIdent reply(array what)
+   {
+      /* ( Session-Info-Ident ) */
+      return SessionInfoIdent(@what);
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 65 */
+class Re_lookup_person
+{
+   inherit _Request;
+
+   array indata(string regexp)
+   {
+      return ({65,
+               H(regexp)});
+   }
+
+   array(int(0..65535)) persnos;
+
+   array(int(0..65535)) reply(array what)
+   {
+      /* ( ARRAY Pers-No ) */
+      return (array(int(0..65535)))what[1];
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 66 */
+class Re_lookup_conf
+{
+   inherit _Request;
+
+   array indata(string regexp)
+   {
+      return ({66,
+               H(regexp)});
+   }
+
+   array(int(0..65535)) confnos;
+
+   array(int(0..65535)) reply(array what)
+   {
+      /* ( ARRAY Conf-No ) */
+      return (array(int(0..65535)))what[1];
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 67 */
+class Lookup_person
+{
+   inherit _Request;
+
+   array indata(string name)
+   {
+      return ({67,
+               H(name)});
+   }
+
+   array(int(0..65535)) persnos;
+
+   array(int(0..65535)) reply(array what)
+   {
+      /* ( ARRAY Pers-No ) */
+      return (array(int(0..65535)))what[1];
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 68 */
+class Lookup_conf
+{
+   inherit _Request;
+
+   array indata(string name)
+   {
+      return ({68,
+               H(name)});
+   }
+
+   array(int(0..65535)) confnos;
+
+   array(int(0..65535)) reply(array what)
+   {
+      /* ( ARRAY Conf-No ) */
+      return (array(int(0..65535)))what[1];
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 69 */
+class Set_client_version
+{
+   inherit _Request;
+
+   array indata(string client_name,
+                string client_version)
+   {
+      return ({69,
+               H(client_name),
+               H(client_version)});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 70 */
+class Get_client_name
+{
+   inherit _Request;
+
+   array indata(int session)
+   {
+      return ({70,
+               session});
+   }
+
+   string reply(array what)
+   {
+      return what[0]; /* HOLLERITH */
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 71 */
+class Get_client_version
+{
+   inherit _Request;
+
+   array indata(int session)
+   {
+      return ({71,
+               session});
+   }
+
+   string reply(array what)
+   {
+      return what[0]; /* HOLLERITH */
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 72 */
+class Mark_text
+{
+   inherit _Request;
+
+   array indata(int text,
+                int(0..255) mark_type)
+   {
+      return ({72,
+               text,
+               mark_type});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 73 */
+class Unmark_text
+{
+   inherit _Request;
+
+   array indata(int text_no)
+   {
+      return ({73,
+               text_no});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 74 */
+class Re_z_lookup
+{
+   inherit _Request;
+
+   array indata(string regexp,
+                int(0..1) want_persons,
+                int(0..1) want_confs)
+   {
+      return ({74,
+               H(regexp),
+               want_persons,
+               want_confs});
+   }
+
+
+   array(ConfZInfo) confzinfos;
+
+   array(ConfZInfo) reply(array what)
+   {
+      /* ( ARRAY Conf-Z-Info ) */
+      return confzinfos=Array.map(what[1]/3,
+                                lambda(array z) { return ConfZInfo(@z); });
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 75 */
+class Get_version_info
+{
+   inherit _Request;
+
+   array indata()
+   {
+      return ({75});
+   }
+
+
+   VersionInfo versioninfo;
+
+   VersionInfo reply(array what)
+   {
+      /* ( Version-Info ) */
+      return VersionInfo(@what);
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 76 */
+class Lookup_z_name
+{
+   inherit _Request;
+
+   array indata(string name,
+                int(0..1) want_pers,
+                int(0..1) want_confs)
+   {
+      return ({76,
+               H(name),
+               want_pers,
+               want_confs});
+   }
+
+
+   array(ConfZInfo) confzinfos;
+
+   array(ConfZInfo) reply(array what)
+   {
+      /* ( ARRAY Conf-Z-Info ) */
+      return confzinfos=Array.map(what[1]/3,
+                                lambda(array z) { return ConfZInfo(@z); });
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 77 */
+class Set_last_read
+{
+   inherit _Request;
+
+   array indata(int(0..65535) conference,
+                int last_read)
+   {
+      return ({77,
+               conference,
+               last_read});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 78 */
+class Get_uconf_stat
+{
+   inherit _Request;
+
+   array indata(int(0..65535) conference)
+   {
+      return ({78,
+               conference});
+   }
+
+
+   UConference uconference;
+
+   UConference reply(array what)
+   {
+      /* ( UConference ) */
+      return UConference(@what);
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 79 */
+class Set_info
+{
+   inherit _Request;
+
+   array indata(InfoOld info)
+   {
+      return ({79,
+               @info->encode()});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 80 */
+class Accept_async
+{
+   inherit _Request;
+
+   array indata(array(int) request_list)
+   {
+      return ({80,
+               @A((array(string))request_list)});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 81 */
+class Query_async
+{
+   inherit _Request;
+
+   array indata()
+   {
+      return ({81});
+   }
+
+   array(int) reply(array what)
+   {
+      return what[0]; /* ARRAY INT32 */
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 82 */
+class User_active
+{
+   inherit _Request;
+
+   array indata()
+   {
+      return ({82});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 83 */
+class Who_is_on_dynamic
+{
+   inherit _Request;
+
+   array indata(int(0..1) want_visible,
+                int(0..1) want_invisible,
+                int active_last)
+   {
+      return ({83,
+               want_visible,
+               want_invisible,
+               active_last});
+   }
+
+
+   array(DynamicSessionInfo) dynamicsessioninfos;
+
+   array(DynamicSessionInfo) reply(array what)
+   {
+      /* ( ARRAY Dynamic-Session-Info ) */
+      return dynamicsessioninfos=Array.map(what[1]/6,
+                                lambda(array z) { return DynamicSessionInfo(@z); });
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 84 */
+class Get_static_session_info
+{
+   inherit _Request;
+
+   array indata(int session_no)
+   {
+      return ({84,
+               session_no});
+   }
+
+
+   StaticSessionInfo staticsessioninfo;
+
+   StaticSessionInfo reply(array what)
+   {
+      /* ( Static-Session-Info ) */
+      return StaticSessionInfo(@what);
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 85 */
+class Get_collate_table
+{
+   inherit _Request;
+
+   array indata()
+   {
+      return ({85});
+   }
+
+   string reply(array what)
+   {
+      return what[0]; /* HOLLERITH */
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 86 */
+class Create_text
+{
+   inherit _Request;
+
+   array indata(string text,
+                array(int) misc_info,
+                array(AuxItemInput) aux_items)
+   {
+      return ({86,
+               H(text),
+               @A((array(string))misc_info),
+               @A(`+(@Array.map(aux_items,
+                               lambda(AuxItemInput z) 
+                                  { return z->encode(); })))});
+   }
+
+   int reply(array what)
+   {
+      return what[0]; /* Text-No */
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 87 */
+class Create_anonymous_text
+{
+   inherit _Request;
+
+   array indata(string text,
+                array(int) misc_info,
+                array(AuxItemInput) aux_items)
+   {
+      return ({87,
+               H(text),
+               @A((array(string))misc_info),
+               @A(`+(@Array.map(aux_items,
+                               lambda(AuxItemInput z) 
+                                  { return z->encode(); })))});
+   }
+
+   int reply(array what)
+   {
+      return what[0]; /* Text-No */
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 88 */
+class Create_conf
+{
+   inherit _Request;
+
+   array indata(string name,
+                multiset(string) type,
+                array(AuxItemInput) aux_items)
+   {
+      return ({88,
+               H(name),
+               @B(@rows(type,extendedconftypenames)),
+               @A(`+(@Array.map(aux_items,
+                               lambda(AuxItemInput z) 
+                                  { return z->encode(); })))});
+   }
+
+   int(0..65535) reply(array what)
+   {
+      return what[0]; /* Conf-No */
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 89 */
+class Create_person
+{
+   inherit _Request;
+
+   array indata(string name,
+                string passwd,
+                array(AuxItemInput) aux_items)
+   {
+      return ({89,
+               H(name),
+               H(passwd),
+               @A(`+(@Array.map(aux_items,
+                               lambda(AuxItemInput z) 
+                                  { return z->encode(); })))});
+   }
+
+   int(0..65535) reply(array what)
+   {
+      return what[0]; /* Pers-No */
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 90 */
+class Get_text_stat
+{
+   inherit _Request;
+
+   array indata(int text_no)
+   {
+      return ({90,
+               text_no});
+   }
+
+
+   TextStat textstat;
+
+   TextStat reply(array what)
+   {
+      /* ( Text-Stat ) */
+      return TextStat(@what);
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 91 */
+class Get_conf_stat
+{
+   inherit _Request;
+
+   array indata(int(0..65535) conf_no)
+   {
+      return ({91,
+               conf_no});
+   }
+
+
+   Conference conference;
+
+   Conference reply(array what)
+   {
+      /* ( Conference ) */
+      return Conference(@what);
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 92 */
+class Modify_text_info
+{
+   inherit _Request;
+
+   array indata(int text,
+                array(int) delete,
+                array(AuxItemInput) add)
+   {
+      return ({92,
+               text,
+               @A((array(string))delete),
+               @A(`+(@Array.map(add,
+                               lambda(AuxItemInput z) 
+                                  { return z->encode(); })))});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 93 */
+class Modify_conf_info
+{
+   inherit _Request;
+
+   array indata(int(0..65535) conf,
+                array(int) delete,
+                array(AuxItemInput) add)
+   {
+      return ({93,
+               conf,
+               @A((array(string))delete),
+               @A(`+(@Array.map(add,
+                               lambda(AuxItemInput z) 
+                                  { return z->encode(); })))});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 94 */
+class Get_info
+{
+   inherit _Request;
+
+   array indata()
+   {
+      return ({94});
+   }
+
+
+   Info info;
+
+   Info reply(array what)
+   {
+      /* ( Info ) */
+      return Info(@what);
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 95 */
+class Modify_system_info
+{
+   inherit _Request;
+
+   array indata(array(int) items_to_delete,
+                array(AuxItemInput) items_to_add)
+   {
+      return ({95,
+               @A((array(string))items_to_delete),
+               @A(`+(@Array.map(items_to_add,
+                               lambda(AuxItemInput z) 
+                                  { return z->encode(); })))});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 96 */
+class Query_predefined_aux_items
+{
+   inherit _Request;
+
+   array indata()
+   {
+      return ({96});
+   }
+
+   array(int) reply(array what)
+   {
+      return what[0]; /* ARRAY INT32 */
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 97 */
+class Set_expire
+{
+   inherit _Request;
+
+   array indata(int(0..65535) conf_no,
+                int expire)
+   {
+      return ({97,
+               conf_no,
+               expire});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 98 */
+class Query_read_texts
+{
+   inherit _Request;
+
+   array indata(int(0..65535) person,
+                int(0..65535) conference)
+   {
+      return ({98,
+               person,
+               conference});
+   }
+
+
+   Membership membership;
+
+   Membership reply(array what)
+   {
+      /* ( Membership ) */
+      return Membership(@what);
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 99 */
+class Get_membership
+{
+   inherit _Request;
+
+   array indata(int(0..65535) person,
+                int(0..65535) first,
+                int(0..65535) no_of_confs,
+                int(0..1) want_read_texts)
+   {
+      return ({99,
+               person,
+               first,
+               no_of_confs,
+               B(want_read_texts)});
+   }
+
+
+   array(Membership) memberships;
+
+   array(Membership) reply(array what)
+   {
+      /* ( ARRAY Membership ) */
+      return memberships=Array.map(what[1]/26,
+                                lambda(array z) { return Membership(@z); });
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 100 */
+class Add_member
+{
+   inherit _Request;
+
+   array indata(int(0..65535) conf_no,
+                int(0..65535) pers_no,
+                int(0..255) priority,
+                int(0..65535) where,
+                multiset(string) type)
+   {
+      return ({100,
+               conf_no,
+               pers_no,
+               priority,
+               where,
+               @B(@rows(type,membershiptypenames))});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 101 */
+class Get_members
+{
+   inherit _Request;
+
+   array indata(int(0..65535) conf,
+                int(0..65535) first,
+                int(0..65535) no_of_members)
+   {
+      return ({101,
+               conf,
+               first,
+               no_of_members});
+   }
+
+
+   array(Member) members;
+
+   array(Member) reply(array what)
+   {
+      /* ( ARRAY Member ) */
+      return members=Array.map(what[1]/12,
+                                lambda(array z) { return Member(@z); });
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 102 */
+class Set_membership_type
+{
+   inherit _Request;
+
+   array indata(int(0..65535) pers,
+                int(0..65535) conf,
+                multiset(string) type)
+   {
+      return ({102,
+               pers,
+               conf,
+               @B(@rows(type,membershiptypenames))});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 103 */
+class Local_to_global
+{
+   inherit _Request;
+
+   array indata(int(0..65535) conf_no,
+                int first_local_no,
+                int no_of_existing_texts)
+   {
+      return ({103,
+               conf_no,
+               first_local_no,
+               no_of_existing_texts});
+   }
+
+
+   TextMapping textmapping;
+
+   TextMapping reply(array what)
+   {
+      /* ( Text-Mapping ) */
+      return TextMapping(@what);
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 104 */
+class Map_created_texts
+{
+   inherit _Request;
+
+   array indata(int(0..65535) author,
+                int first_local_no,
+                int no_of_existing_texts)
+   {
+      return ({104,
+               author,
+               first_local_no,
+               no_of_existing_texts});
+   }
+
+
+   TextMapping textmapping;
+
+   TextMapping reply(array what)
+   {
+      /* ( Text-Mapping ) */
+      return TextMapping(@what);
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
+/* 105 */
+class Set_keep_commented
+{
+   inherit _Request;
+
+   array indata(int(0..65535) conf_no,
+                int keep_commented)
+   {
+      return ({105,
+               conf_no,
+               keep_commented});
+   }
+
+   void reply(array what)
+   {
+   }
+
+   void failure(object error)
+   {
+   }
+}
+
diff --git a/lib/modules/Protocols.pmod/LysKOM.pmod/Session.pike b/lib/modules/Protocols.pmod/LysKOM.pmod/Session.pike
new file mode 100644
index 0000000000..11b6aea087
--- /dev/null
+++ b/lib/modules/Protocols.pmod/LysKOM.pmod/Session.pike
@@ -0,0 +1,599 @@
+//  $Id: Session.pike,v 1.1 1999/06/12 23:01:50 mirar Exp $
+//! module Protocols
+//! submodule LysKOM
+//! class Session
+
+import ".";
+
+Connection con;
+
+//! variable user
+//!	This variable contains the 
+//!	<link to=Protocols.LysKOM.Session.Person>person</link>
+//!	that are logged in.
+
+object user; // logged in as this Person 
+
+string server;
+
+int oldlevel; // level <10 protocol
+
+mapping(int:object) _text=([]);
+mapping(int:object) _person=([]);
+mapping(int:object) _conference=([]);
+
+//! method void create(string server)
+//! method void create(string server,mapping options)
+//!	Initializes the session object, and opens
+//!	a connection to that server.
+//!	
+//!	options is a mapping of options,
+//!	<pre>
+//!	    "login"      : int|string - login as this person number
+//!                                     (get number from name)
+//!	    "password"   : string     - send this login password
+//!	    "invisible"  : int(0..1)  - login invisible    
+//!				      
+//!	advanced:		      
+//!	    "port" : int              - server port (default is 4894)
+//!	    "whoami" : string         - user name (default is from uid)
+//!	</pre>
+//!
+//! see also: Connection
+
+void create(object|string _server,void|mapping options)
+{
+   if (objectp(_server)) // clone
+   {
+      con        = _server->con;
+      server     = _server->server;
+      oldlevel   = _server->oldlevel;
+      user       = _server->user;
+      _person    = _server->_person;
+      _conference= _server->_conference;
+      _text      = _server->_text;
+      return;
+   }
+   server=_server;
+   con=Connection(_server,options);
+   user=(options && options->login)?person(options->login):0;
+}
+
+
+class MiscInfo
+{
+   class Recpt
+   {
+      object conf;
+      int local_no;
+      object received_at;
+      object sent_by;
+      object sent_at;
+   }
+   array(Recpt) recpt=({});
+   array(Recpt) ccrecpt=({});
+   array(Recpt) bccrecpt=({});
+
+   array(object) comm_to=({});
+   array(object) comm_in=({});
+   array(object) foot_to=({});
+   array(object) foot_in=({});
+
+   void create(array(int) a)
+   {
+      int i;
+      object r;
+      for (i=0; i<sizeof(a);)
+      {
+	 switch (a[i++])
+	 {
+	    case  0: recpt+=({r=Recpt()}); r->conf=conference(a[i++]); break;
+	    case  1: ccrecpt+=({r=Recpt()}); 
+	             r->conf=conference(a[i++]); break;
+	    case 15: bccrecpt+=({r=Recpt()}); 
+	             r->conf=conference(a[i++]); break;
+
+	    case  2: comm_to+=({text(a[i++])}); break;
+	    case  3: comm_in+=({text(a[i++])}); break;
+	    case  4: foot_to+=({text(a[i++])}); break;
+	    case  5: foot_in+=({text(a[i++])}); break;
+	       
+	    case  6: r->local_no=a[i++]; break;
+	    case  7: r->received_at=ProtocolTypes.LysKOMTime(@a[i..i+8]); 
+	             i+=9; break;
+	    case  8: r->sent_by=person(a[i++]); break;
+	    case  9: r->sent_at=ProtocolTypes.LysKOMTime(@a[i..i+8]); 
+	             i+=9; break;
+	    default:
+	       error("unexpected selection in misc_info: %d\n",a[i-1]);
+	 }
+      }
+   }
+}
+
+#define FETCHERC(WHAT,TYPE,VAR,CALL,ARGS,CONV)				\
+   TYPE VAR;						\
+   private object fetch_##WHAT;						\
+   private array(function) fetch_##WHAT##_callbacks=({});		\
+									\
+   void prefetch_##WHAT##(void|function callback)			\
+   {									\
+      if (VAR) 								\
+      {									\
+	 if (callback) callback(this_object());				\
+	 return;							\
+      }									\
+      if (callback) fetch_##WHAT##_callbacks+=({callback});		\
+      if (!fetch_##WHAT)						\
+	 fetch_##WHAT=							\
+	    con->async_cb_##CALL(lambda(mixed res)			\
+				 {					\
+				    if (objectp(res) && res->iserror)	\
+				       err=res;				\
+				    else				\
+				       VAR=CONV;			\
+				    fetch_##WHAT=0;			\
+				    array m=fetch_##WHAT##_callbacks;	\
+				    fetch_##WHAT##_callbacks=0;		\
+				    m(this_object());			\
+				 },ARGS);				\
+   }									\
+									\
+   inline void need_##WHAT()						\
+   {									\
+      if (VAR) return;							\
+      if (!fetch_##WHAT) prefetch_##WHAT();				\
+      if (fetch_##WHAT) fetch_##WHAT();					\
+   }
+#define FETCHER(WHAT,TYPE,VAR,CALL,ARGS)				\
+	FETCHERC(WHAT,TYPE,VAR,CALL,ARGS,res)
+
+#define FETCHER2(WHAT,TYPE1,VAR1,TYPE2,VAR2,CALL1,CALL2,ARGS)		\
+   TYPE1 VAR1;						                \
+   TYPE2 VAR2;						                \
+   private object fetch_##WHAT;						\
+   private array(function) fetch_##WHAT##_callbacks=({});		\
+									\
+   private void _got_##WHAT##1(mixed res)				\
+   {									\
+      if (objectp(res) && res->iserror)					\
+      {									\
+	 if (res->no==2)						\
+	 {								\
+	    oldlevel=1;							\
+	    fetch_##WHAT=con->async_cb_##CALL2(_got_##WHAT##2,ARGS);	\
+	 }								\
+	 err=res;							\
+      }									\
+      else 								\
+	 VAR1=res;							\
+      array m=fetch_##WHAT##_callbacks;					\
+      fetch_##WHAT##_callbacks=({});					\
+      m(this_object());							\
+   }									\
+									\
+   private void _got_##WHAT##2(mixed res)				\
+   {									\
+      if (objectp(res) && res->iserror) err=res; else VAR2=res;		\
+      array m=fetch_##WHAT##_callbacks;					\
+      fetch_##WHAT##_callbacks=({});					\
+      m(this_object());							\
+   }									\
+									\
+   object prefetch_##WHAT##(void|function callback)			\
+   {									\
+      if (VAR1 || VAR2)                                                 \
+      {									\
+	 if (callback) callback(this_object());				\
+	 return this_object();						\
+      }									\
+      if (callback) fetch_##WHAT##_callbacks+=({callback});		\
+      if (!fetch_##WHAT)						\
+	 if (oldlevel)							\
+	    fetch_##WHAT=con->async_cb_##CALL2(_got_##WHAT##2,ARGS);	\
+	 else								\
+	    fetch_##WHAT=con->async_cb_##CALL1(_got_##WHAT##1,ARGS);	\
+      return this_object(); \
+   }									\
+									\
+   inline void need_##WHAT()						\
+   {									\
+      if (VAR1 || VAR2) return;						\
+      if (!fetch_##WHAT) prefetch_##WHAT();				\
+      if (fetch_##WHAT) fetch_##WHAT();					\
+      if (fetch_##WHAT) fetch_##WHAT();					\
+   }
+
+#define FETCHERC2b(WHAT,TYPE,VAR,CALL,ARGS,CONV)		\
+   TYPE VAR;						                \
+   private object fetch_##WHAT;						\
+   private array(function) fetch_##WHAT##_callbacks=({});		\
+									\
+   private void _got_##WHAT##1(mixed res)				\
+   {									\
+      if (objectp(res) && res->iserror)					\
+      {									\
+	 if (res->no==2)						\
+	 {								\
+	    oldlevel=1;							\
+	    fetch_##WHAT= \
+                 con->async_cb_##CALL##_old(_got_##WHAT##2,ARGS);	\
+	 }								\
+	 err=res;							\
+      }									\
+      else 								\
+	 VAR=CONV;							\
+      array m=fetch_##WHAT##_callbacks;					\
+      fetch_##WHAT##_callbacks=({});					\
+      m(this_object());							\
+   }									\
+									\
+   private void _got_##WHAT##2(mixed res)				\
+   {									\
+      if (objectp(res) && res->iserror) err=res; \
+   	else VAR=CONV;		\
+      array m=fetch_##WHAT##_callbacks;					\
+      fetch_##WHAT##_callbacks=({});					\
+      m(this_object());							\
+   }									\
+									\
+   object prefetch_##WHAT##(void|function callback)			\
+   {									\
+      if (VAR)                                                 \
+      {									\
+	 if (callback) callback(this_object());				\
+	 return this_object();						\
+      }									\
+      if (callback) fetch_##WHAT##_callbacks+=({callback});		\
+      if (!fetch_##WHAT)						\
+	 if (oldlevel)							\
+	    fetch_##WHAT=con->async_cb_##CALL##_old(_got_##WHAT##2,ARGS); \
+	 else								\
+	    fetch_##WHAT=con->async_cb_##CALL(_got_##WHAT##1,ARGS);	\
+      return this_object(); \
+   }									\
+									\
+   inline void need_##WHAT()						\
+   {									\
+      if (VAR) return;						\
+      if (!fetch_##WHAT) prefetch_##WHAT();				\
+      if (fetch_##WHAT) fetch_##WHAT();					\
+      if (fetch_##WHAT) fetch_##WHAT();					\
+   }
+
+class Text
+{
+   int no;
+
+   MiscInfo _misc;
+
+   object err;
+
+   object _author;
+
+   void create(int _no)
+   {
+      no=_no;
+   }
+
+   FETCHERC(text,array(string),_text,get_text,@({no,0,0x7fffffff}),
+	    array_sscanf(res,"%s\n%s"))
+   FETCHERC2b(stat,object,_stat,get_text_stat,@({no}),
+	      (_misc=MiscInfo(res->misc_info),res))
+
+   mixed `[](string what)
+   {
+      switch (what)
+      {
+	 case "create":
+	    return create;
+	 case "prefetch_text":
+	    return prefetch_text;
+	 case "prefetch_stat":
+	    return prefetch_stat;
+
+	 case "no":
+	    return no;
+	 case "error":
+	    return err;
+
+	 case "text": 
+	    need_text();
+	    return _text[1];
+
+	 case "subject": 
+	    need_text();
+	    return _text[0];
+
+	 case "author":
+	    need_stat();
+	    return _author 
+	       || (_author=person(_stat->author));
+
+	 case "misc":
+	    need_stat();
+	    return _misc;
+
+	 case "lines":
+	    need_text();
+	    return String.count(_text[1],"\n")+1;
+
+	 case "characters":
+	    need_text();
+	    return strlen(_text[1]);
+      }
+   }
+
+   mixed `->(string what) { return `[](what); }
+}
+
+
+object text(int no)
+{
+   return _text[no] || (_text[no]=Text(no));
+}
+
+class Membership
+{
+   int              person;
+   int 		    newtype;
+   object           last_time_read;             
+   int(0..255)      priority;                   
+   int              last_text_read;             
+   array(int)       read_texts;                 
+   int(0..65535)    added_by;   // new
+   object           added_at;   // new
+   multiset(string) type;       // new
+   int              position;        // new
+
+   object conf;
+
+   void create(object mb,int pers)
+   {
+      person=pers;
+
+      last_time_read=mb->last_time_read;
+      read_texts=mb->read_texts;
+      last_text_read=mb->last_text_read;
+      priority=mb->priority;
+      conf=conference(mb->conf_no);
+	 
+      if (mb->type)
+      {
+	 added_at=mb->added_at;
+	 position=mb->position;
+	 added_by=mb->added_by;
+	 type=mb->type;
+	 newtype=1;
+      }
+   }
+
+   int number_unread()
+   {
+      return (conf->no_of_texts+conf->first_local_no-1)
+	 -last_text_read -sizeof(read_texts);
+   }
+   
+   mixed `[](string what)
+   {
+      switch (what)
+      {
+	 case "last_time_read":
+	 case "read_texts":
+	 case "last_text_read":
+	 case "priority":
+	 case "conf":
+	 case "added_at":
+	 case "position":
+	 case "type":
+	 case "number_unread":
+	    return ::`[](what);
+      }
+   }
+}
+
+
+class Person
+{
+   int no;
+   
+   object conf;
+
+   object err;
+
+   FETCHER(stat,ProtocolTypes.Person,_person,get_person_stat,no);
+   FETCHERC(unread,array(object),_unread,get_unread_confs,no,
+	    Array.map(res,conference));
+   FETCHERC2b(membership,array(object),_membership,get_membership,
+	      @({no,0,65535,1}),
+	      Array.map(res,Membership,no));
+
+   void create(int _no)
+   {
+      no=_no;
+      conf=conference(no);
+   }
+
+   mixed `[](string what)
+   {
+      switch (what)
+      {
+	 case "create":
+	    return create;
+	 case "prefetch_stat":
+	    return prefetch_stat;
+	 case "prefetch_conf":
+	    return conf->prefetch_stat;
+	 case "prefetch_membership":
+	    return prefetch_membership;
+
+	 case "no":
+	    return no;
+	 case "error":
+	    return err;
+	 case "user_area":
+	    need_stat();
+	    return text(_person->user_area);
+         case "username":
+	 case "privileges":
+	 case "flags":
+	 case "last_login":
+	 case "total_time_present":
+	 case "sessions":
+	 case "created_lines":
+	 case "created_bytes":
+	 case "read_texts":
+	 case "no_of_text_fetches":
+	 case "created_persons":
+	 case "created_confs":
+	 case "first_created_local_no":
+	 case "no_of_created_texts":
+	 case "no_of_marks":
+	 case "no_of_confs":
+	    need_stat();
+	    return _person[what];
+	 case "unread":
+	    need_unread();
+	    return _unread;
+	 case "membership":
+	    need_membership();
+	    return _membership;
+      }
+
+      return conf[what];
+   }
+
+   mixed `->(string what) { return `[](what); }
+}
+
+object person(int no)
+{
+   return _person[no] || (_person[no]=Person(no));
+}
+
+class Conference
+{
+   int no;
+
+   private object err;
+
+   FETCHER2(stat,ProtocolTypes.Conference,_conf,
+	    ProtocolTypes.ConferenceOld,_confold,
+	    get_conf_stat,get_conf_stat_old,no)
+
+   void create(int _no)
+   {
+      no=_no;
+   }
+
+   mixed `[](string what)
+   {
+      switch (what)
+      {
+	 case "create":
+	    return create;
+	 case "prefetch_stat":
+	    return prefetch_stat;
+
+	 case "no":
+	    return no;
+	 case "error":
+	    return err;
+
+	 case "presentation":
+	 case "msg_of_day":
+	    need_stat();
+	    return text( (_conf||_confold)[what] );
+	 case "supervisor":
+	 case "permitted_submitters":
+	 case "super_conf":
+	    need_stat();
+	    return conference( (_conf||_confold)[what] );
+	 case "creator":
+	    need_stat();
+	    return person( (_conf||_confold)[what] );
+	 case "name":
+	 case "type":
+	 case "creation_time":
+	 case "last_written":
+	 case "nice":
+	 case "no_of_members":
+	 case "first_local_no":
+	 case "no_of_texts":
+	    need_stat();
+	    return (_conf||_confold)[what];
+      }
+   }
+
+   mixed `->(string what) { return `[](what); }
+}
+
+object conference(int no)
+{
+   return _conference[no] || (_conference[no]=Conference(no));
+}
+
+//!
+//! method array(object) try_complete_person(string orig)
+//!	Runs a LysKOM completion on the given string,
+//!	returning an array of confzinfos of the match.
+
+array(ProtocolTypes.ConfZInfo) try_complete_person(string orig)
+{
+   return con->lookup_z_name(orig,1,0);
+}
+
+//! method login(int user_no,string password)
+//! method login(int user_no,string password,int invisible)
+//!	Performs a login. Returns 1 on success or throws a lyskom error.
+
+int(1..1) login(int user_no,string password,
+		void|int invisible)
+{
+   con->login(user_no,password,invisible);
+   user=person(user_no);
+   return 1;
+}
+
+//! method logout()
+//!	Logouts from the server.
+
+int(1..1) logout()
+{
+   if (con) 
+      con->logout();
+   return 1;
+}
+
+
+/*
+
+session->new_text(string subject,
+                  string message,
+                  void|object|array(object) mottagare,
+                  void|object|array(object) comment_to,
+                  void|object|array(object) footnote_to,
+                  void|multiset flags);
+
+(conf)->new_text(string subject,
+                 string message,
+                 void|object|array(object) mottagare,
+                 void|object|array(object) comment_to,
+                 void|object|array(object) footnote_to,
+                 void|multiset flags);
+
+(text)->comment(string subject,
+                string message,
+                void|object|array(object) mottagare,
+                void|object|array(object) comment_to,
+                void|object|array(object) footnote_to,
+                void|multiset flags);
+
+(text)->footnote(string subject,
+                 string message,
+                 void|object|array(object) mottagare,
+                 void|object|array(object) comment_to,
+                 void|object|array(object) footnote_to,
+                 void|multiset flags);
+
+*/
-- 
GitLab