Added public files

Roughly added all public files. Probably missed some, though.
diff --git a/doc/LPC/.synonym b/doc/LPC/.synonym
new file mode 100644
index 0000000..300916b
--- /dev/null
+++ b/doc/LPC/.synonym
@@ -0,0 +1,26 @@
+array arrays
+vererbung inheritance
+erben inheritance
+integer integers
+mapping mappings
+modulo operators
+operatoren operators
+increment operators
+decrement operators
+string strings
+case switch
+private modifiers
+public modifiers
+static modifiers
+nomask modifiers
+protected modifiers
+nosave modifiers
+virtual modifiers
+struct structs
+strong_types pragma
+strict_types pragma
+save_types pragma
+pedantic pragma
+range_check pragma
+rttc pragma
+rtt_checks pragma
diff --git a/doc/LPC/alists b/doc/LPC/alists
new file mode 100644
index 0000000..5550de7
--- /dev/null
+++ b/doc/LPC/alists
@@ -0,0 +1,53 @@
+CONCEPT
+        alists
+
+LAST UPDATE
+        2 Mar 92 21:10:21 GMT
+
+AUTHOR
+        From: amylaar@mcshh.hanse.de (Joern Rennecke)
+        Subject: general documentation on alists
+
+DESCRIPTION
+        Alists provide a fast and convenient way to access data
+        associatively.
+
+        Alists are implemented as arrays of arrays, the first being
+        the array holding the keys, the others arrays holding
+        associated data. An empty alist is an array of empty arrays.
+
+        Note that the the dimensions of the arrays are used the other
+        way than in lisp to allow for faster searching.
+
+        Keys have to be of type integer, string or object. Types can
+        be mixed.
+
+        The search functions return an undefined value when another
+        list is given in place of a presorted key list.
+
+        A list with non-numeric keys retrieved by restore_object() has
+        to be readjusted by using order_alist(), especially after
+        reboot.
+
+        Deleting an entry can safely be done with exclude_array as
+        long as all associated data lists are treated like the key
+        array; index finding for such purposes can be done with assoc.
+
+        Typical applications: holding administrary information about
+        wizards, list of visitors in a pub, list of customers having
+        some sort of credit, information remembered about items etc.
+
+NOTE
+        The main use of alists, storing data associatively, is now
+        better performed by mappings. Alists are needed for more
+        extreme situations only.
+
+        Alists are available only if the driver is compiled with
+        alist support. In that case, __ALISTS__ is defined.
+
+HISTORY
+        LDMud 3.3 made alists an optional efun.
+
+SEE ALSO
+        mappings(LPC), order_alist(E), insert_alist(E), assoc(E),
+        transpose_array(E)
diff --git a/doc/LPC/arrays b/doc/LPC/arrays
new file mode 100644
index 0000000..883dddb
--- /dev/null
+++ b/doc/LPC/arrays
@@ -0,0 +1,116 @@
+CONCEPT
+        arrays
+
+DESCRIPTION
+        There is support for arrays. The arrays can't be declared, but
+        should be allocated dynamically with the function 'allocate()'
+        (see efun/allocate).
+
+        Arrays are stored by reference, so all assignments of whole
+        arrays will just copy the address. The array will be
+        deallocated when no variable points to it any longer.
+
+        When a variable points to an array, items can be accessed with
+        indexing: 'arr[3]' as an example. The name of the array being
+        indexed can be any expression, even a function call:
+        'func()[2]'. It can also be another array, if this array has
+        pointers to arrays:
+
+        arr = allocate(2);
+        arr[0] = allocate(3);
+        arr[1] = allocate(3);
+
+        Now 'arr[1][2]' is a valid value.
+
+        The 'sizeof()' function (in true C a compiler-directive, not a
+        function) will give the number of elements in an array (see
+        efun/sizeof).
+
+NOTE
+        Nowadays it is most of the time preferable to use an array
+        constructor, a list surrounded by '({' and '})',
+        e.g. ({ 1, "xx", 2 }) will construct a new array with size 3,
+        initialized with 1, "xx" and 2 respectively.
+
+
+OPERATIONS
+
+        INDEXING
+        There are several very useful operations defined on arrays.
+        The most used is the indexing:
+                a=({ 0,1,2,3 });
+                return a[2];      // this will return 2
+        You also can count from the end of the array. Use <1 to specify
+        the last element in the array:
+                a=({ 0,1,2,3 });
+                return a[<3];     // this will return 1
+        With indexing you can also create sub-arrays:
+                a=({ 0,1,2,3,4,5,6,7 });
+                return a[3..5];   // this will return ({ 3,4,5 })
+                return a[2..<2];  // this will return ({ 2,3,4,5,6 })
+                return a[<5..<3]; // this will return ({ 3,4,5 })
+                return a[<6..5];  // this will return ({ 2,3,4,5 })
+                return a[3..3];   // this will return ({ 3 })
+                return a[3..2];   // this will return ({ })
+                return a[3..0];   // this will return ({ })
+                return a[5..100]; // this will return ({ 5,6,7 })
+                [x..] is interpreted as [x..<1]
+
+        ADDING
+        You can add two arrays. The result is one array with the elements
+        of both the former arrays:
+                a=({ 0,1 });
+                b=({ "a","b" });
+                return a+b;       // this will return ({ 0,1,"a","b" })
+                return b+a;       // this will return ({ "a","b",0,1 })
+
+        SUBTRACTING
+        You can erase all elements of one array that occur in another
+        array:
+                a=({ 0,1,2,3,4,5,6,7 });
+                b=({ 7,2,5,8,1,9 });
+                return a-b;       // this will return ({ 0,3,4,6 })
+                return b-a;       // this will return ({ 8,9 })
+
+        INTERJUNCTION
+        Use the &-operator to create the interjunction of two arrays:
+                a=({ 5,2,8,1,9,4 })
+                b=({ 1,6,7,3,4,5 })
+                return a&b;       // this will return ({ 1,4,5 })
+
+        ASSIGNING
+        Assigning can also be done to sub-arrays and is thus very powerful:
+                a=({ 0,1,2,3,4,5,6,7 });
+                a[<4..<3]=({ 8,9 });
+                return a;         // this will return ({ 0,1,2,3,8,9,6,7 })
+
+                a=({ 0,1,2,3,4,5,6,7 });
+                a[2..5]=({ });
+                return a;         // this will return ({ 0,1,6,7 })
+
+                a=({ 0,1,2,3,4 });
+                a[3..2]=({ 8,9 });
+                return a;         // this will return ({ 0,1,2,8,9,3,4 })
+
+                a=({ 0,1,2,3,4 });
+                a[3..0]=({ 8,9 });
+                return a;         // this will return ({ 0,1,2,8,9,1,2,3,4 })
+                                  // this is quite funny but true ;-)
+                                  // WARNING: If done unintentionally and
+                                  // within a loop, you can quickly cause
+                                  // the game to run out of memory!
+
+        GENERAL
+        Of course for any of the operators explained above you can use
+        the combined form of assigning and operating; that means the
+        operators +=, -= and &= work.
+
+
+TIPS
+        If you want to make sure that no element is more than once in an
+        array you can use the following:
+                a = m_indices(mkmapping(a));
+        This creates a mapping out of the array and recreates the array
+        at once. The elements in the array can be shuffled by this
+        procedure.
+
diff --git a/doc/LPC/block b/doc/LPC/block
new file mode 100644
index 0000000..29eb382
--- /dev/null
+++ b/doc/LPC/block
@@ -0,0 +1,48 @@
+NAME
+        block
+
+DESCRIPTION
+        A block is a special statment, that begins with '{', contains
+        a list of statements, and ends with '}'.
+
+        The block may define local variables. If for a variable no
+        initialisation is given, the variable is initialised to 0 every
+        time the block is entered. Otherwise, the initialisation
+        expression is evaluated and its result assigned to the variable
+        everytime the block is entered.
+
+        Example definitions are:
+
+          int i;
+          int j = 3;
+          int k = 3 * j, l;
+
+          Here, i and l are both initialised to 0; j is initialised
+          to 3, and k is initialised to 9 (3 * j).
+
+        Local variables defined in a block are visible only until the
+        end of the block. Definitions in an inner block hide definitions in
+        outer blocks.
+
+HISTORY
+        Up to 3.2.7 local variables were visible (from their point of
+        definition) in the whole function. That is, code like
+
+            do {
+                int res;
+
+                res = ...
+            } while (res == 5);
+            write(res);
+
+        was perfectly legal. It is no longer, as 'res' ceases to exist
+        with the closing '}' of the while().
+
+        Up to 3.5.0 you could get this old behaviour back with the 
+        #pragma no_local_scopes and switch it off again with 
+        #pragma local_scopes.
+
+        Since 3.5.0 it is not possible to disable the local scope behaviour.
+
+        Up to 3.2.8, local variables could not be initialised in their
+        definition.
diff --git a/doc/LPC/closure_guide b/doc/LPC/closure_guide
new file mode 100644
index 0000000..438ba46
--- /dev/null
+++ b/doc/LPC/closure_guide
@@ -0,0 +1,730 @@
+Closure Guide for LPC
+
+Table of Contents
+
+        1 Indroduction, Overview and Efun-Closures
+
+        2 Lfun-, Inline and Lambda-Closures
+        2.1 Lfun-Closures
+        2.2 Inline-Closures
+        2.3 Lambda-Closures
+        2.3.1 Advantages of Lambda-Closures
+        2.3.2 Free Variables in Lambda-Closure Constructs
+        2.3.3 Special Efun-Closures and Operator-Closures for Lambdas
+        2.4 Closures with Strange Names
+        2.5 Operator-Closures
+        2.6 Variable-Closures
+
+        3 Examples
+        3.1 Lfun-Closure
+        3.2 Lambda-Closure
+
+1 Introduction, Overview and Efun-Closures
+
+  A closure is a pointer to a function. That means that it is data like an
+  int or a string are. It may be assigned to a variable or given to anoth-
+  er function as argument.
+
+  To create a closure that points to an efun like write() you can write
+  the name of the efun prepended with "hash-tick": #'. #'write is a clo-
+  sure that points to the efun write().
+
+  I very often put parentheses around such a closure-notation because
+  otherwise my editor gets confused by the hashmark: (#'write). This is
+  especially of interest within lambda-closures (see below).
+
+  A closure can be evaluated (which means that the function it points to
+  is called) using the efuns funcall() or apply(), which also allow to
+  give arguments to the function. Example:
+
+    funcall(#'write,"hello");
+
+  This will result in the same as write("hello"); alone. The string
+  "hello" is given as first (and only) argument to the function the clo-
+  sure #'write points to.
+
+  The return value of the function the closure points to is returned by
+  the efun funcall() or apply(). (Since write() always returns 0 the re-
+  turn value of the example above will be 0.)
+
+  What are closures good for? With closures you can make much more univer-
+  sally usable functions. A good example is the function filter().
+  It gets an array and a closure as arguments. Then it calls the function
+  the closure points to for each element of the array:
+
+    filter(({ "bla","foo","bar" }),#'write);
+
+  This will call write("bla"), write("foo") and write("bar") in any order;
+  the order is undefined.
+  (In the current implementation the given closure is evaluated for all
+  elements from the first to the last, so the output will be "blafoobar".)
+
+  Furthermore the efun filter() examines the return value of each
+  call of the function the closure points to (the return value of the
+  write()s). If the value is true (not 0) then this element is put into
+  another array which filter() builds up. If the return value is
+  false (== 0) then this element is _not_ put into this array. When all
+  calls are done the slowly built up array is returned. Thus,
+  filter() filters from the given array all elements that the given
+  closure evaluates "true" for and returns an array of those. (The array
+  given to filter() itself is _not_ changed!)
+
+  A more sensical example for filterwould be this:
+
+    x = filter(users(),#'query_is_wizard);
+
+  users() is an efun that gets no arguments and returns an array of all
+  logged in players (wizards and players). query_is_wizard() is a
+  simul_efun that gets an object as first (and only) argument and returns
+  true (1) if this object is a wizard and 0 otherwise.
+
+  So, for each element of the array returned by users() the function
+  query_is_wizard() is called and only those for which 1 was returned are
+  collected into the result and then put into the variable x.
+
+  We now have all logged in wizards stored as array in the variable x.
+
+  Another example: We want to filter out all numbers that are greater than
+  42 from the array a of integers:
+
+    x = filter(({ 10,50,30,70 }),#'>,42);
+
+  (x will now be ({ 50,70 }).)
+
+  Here two things are new: first: we create a closure that points to an
+  operator; second: we use the possibility to give extra arguments to
+  filter().
+
+  Like all efuns the usual operators can be pointed to with a closure by
+  prepending #' to them. funcall(#'>,4,5) is exactly the same as (4>5).
+
+  The extra arguments given as third to last argument (as many as you
+  like) to filter() are given as second to last argument to the
+  function pointed to by the closure each time it is called.
+
+  Thus we now call (({ 10,50,30,70 })[0]>42), (({ 10,50,30,70 })[1]>42) ...
+  (which is (10>42), (50>42) ...) and return an array of all elements this
+  returns true for and store it into x.
+
+  If you want to create a closure to an efun of which you have the name
+  stored in a string you can create such an efun-closure with the efun
+  symbol_function():
+
+    symbol_function("write") // this will return #'write
+
+    funcall(symbol_function("write"),"foobar");  // == write("foobar");
+
+  This function does not very often occur in normal code but it is very
+  useful for tool-programming (eg the robe uses symbol_function() to allow
+  you call any efun you give).
+
+2 Lfun- and Lambda-Closures
+
+  Very often the possibilities closures to efuns offer are not sufficient
+  for the purpose one has. In nearly all cases three possibilities exist in
+  such cases: use an lfun- or inline-closure, or a lambda-closure.
+
+2.1 Lfun-Closures
+
+    The first possibility is rather easy: like with the efun-closures you
+    can create a pointer to a function in the same object you are by using
+    the #' to prepend it to a function name of a function declared above.
+    Example:
+
+      status foo(int x) {
+        return ((x*2) > 42);
+      }
+
+      int *bar() {
+        return filter(({ 10,50,30,70 }),#'foo);
+      }
+
+    Thus, #'foo is used like there was an efun of this name and doing the
+    job that is done in foo().
+
+2.2 Inline Closure
+
+    Inline closures are a variant of lfun closures, the difference being
+    that the function text is written right where the closure is used,
+    enclosed in a pair of '(:' and ':)'. The compiler will then take care
+    of creating a proper lfun and lfun-closure. The arguments passed to
+    such an inline closure are accessible by position: $1 would be the
+    first argument, $2 the second, and so on. With this, the
+    above example would read:
+
+      int * bar() {
+        return filter(({ 10,50,30,70 }), (: ($1 * 2) > 42 :));
+      }
+
+    or alternatively:
+
+      int * bar() {
+        return filter(({ 10,50,30,70 }), (: return ($1 * 2) > 42; :));
+      }
+
+    The difference between the two versions is that in the first form the text
+    of the inline closure must be an expression only, whereas in the second
+    form any legal statement is allowed. The compiler distinguishes the two
+    forms by the last character before the ':)': if it's a ';' or '}', the
+    compiler treats the closure as statement(s), otherwise as expression.
+
+    Inline closures may also nested, so that the following (not very useful)
+    example is legal, too:
+
+      return filter( ({ 10, 50, 30, 70 })
+                         , (: string *s;
+                              s = map(users(), (: $1->query_name() :));
+                              return s[random(sizeof(s))] + ($1 * 2);
+                            :));
+
+    The notation of inline closures is modelled after the MudOS functionals,
+    but there are a few important differences in behaviour.
+
+
+2.3 Lambda-Closures
+
+    Lambda-Closures take the idea of 'define it where you use it' one step
+    further. On first glance they may look like inline closures with an uglier
+    notation, but they offer a few increased possibilities. But first things
+    first.
+
+    The efun lambda() creates a function temporarily and returns a closure
+    pointing to this function. lambda() therefor gets two arrays as
+    arguments, the first is a list of all arguments the function shall expect
+    and the second array is the code of the function (in a more or less
+    complicated form; at least not in C- or LPC-syntax). The closure #'foo
+    from the example above could be notated as lambda-closure:
+
+      lambda(({ 'x }),({ (#'>),
+                         ({ (#'*),'x,2 }),
+                         42
+                      }))
+
+    Now, the first argument is ({ 'x }), an array of all arguments the
+    function shall expect: 1 argument (called 'x) is expected. Notice the
+    strange notation for this argument with one single leading tick. Like
+    The hash-tick to denote closures the leading tick is used to denote
+    things called "symbols". They do not differ much from strings and if
+    you do not want to have a deeper look into closures you can leave it
+    this way.
+
+    The second argument is an array. The first element of such an array
+    must be an efun- or an lfun-closure, the further elements are the
+    arguments for the function this closure points to. If such an argu-
+    ment is an array, it is treated alike; the first element must be a
+    closure and the remaining elements are arguments (which of course
+    also might be arrays ...).
+
+    This leads to a problem: sometimes you want to give an array as an
+    argument to a function. But arrays in an array given to lambda() are
+    interpreted as code-arrays. To allow you to give an array as an argu-
+    ment within an array given to lambda(), you can use the function
+    quote() to make your array to a quoted array (a quoted array is for
+    an array what a symbol is for a string):
+
+      lambda(0,({ (#'sizeof),
+                  quote(({ 10,50,30,70 }))
+               }))
+
+    For array constants, you can also use a single quote to the same
+    effect:
+
+      lambda(0,({ (#'sizeof),
+                  '({ 10,50,30,70 })
+               }))
+
+    This lambda-closure points to a function that will return 4 (it will
+    call sizeof() for the array ({ 10,50,30,70 })). Another thing: if
+    we want to create a function that expects no arguments, we can give
+    an empty array as first argument to lambda() but we can give 0 as
+    well to attain this. This is just an abbreviation.
+
+    Lambda-closure constructs can become quite large and hard to read. The
+    larger they become the harder the code is to read and you should avoid
+    extreme cases. Very often the possibility to use an lfun or an inline
+    instead of a large lambda shortens the code dramatically. Example:
+
+      status foo(object o) {
+        return environment(o)->query_level()>WL_APPRENTICE;
+      }
+
+      x=filter(a,#'foo);
+
+    does the same as
+
+      x=filter(a,lambda(({ 'o }),
+                              ({ (#'>),
+                                 ({ (#'call_other),
+                                    ({ (#'environment),'o }),
+                                    "query_level"
+                                 }),
+                                 WL_APPRENTICE
+                              })));
+
+    (Note that the syntax with the arrow "->" for call_other()s cannot be
+    used, #'-> does not exist. You have to use #'call_other for this and
+    give the name of the lfun to be called as a string.)
+
+    This example also demonstrates the two disadvantages of lambda closures.
+    First, they are very difficult to read, even for a simple example like
+    this. Second, the lambda closure is re-created everytime the
+    filter() is executed, even though the created code is always the
+    same.
+
+    'Why use lambdas at all then?' you may ask now. Well, read on.
+
+
+2.3.1 Advantages of Lambda Closures
+
+    The advantages of lambdas stem from the fact that they are created
+    at runtime from normal arrays.
+
+    This means that the behaviour of a lambda can be made dependant on data
+    available only at runtime. For example:
+
+      closure c;
+      c = lambda(0, ({#'-, ({ #'time }), time() }) );
+
+    Whenever you now call this closure ('funcall(c)') it will return the
+    elapsed time since the closure was created.
+
+    The second advantage of lambdas is that the arrays from which they
+    are compiled can be constructed at runtime. Imagine a customizable prompt
+    which can be configured to display the time, the environment, or both:
+
+      mixed code;
+
+      code = ({ "> " });
+      if (user_wants_time)
+        code = ({ #'+, ({ #'ctime }), code });
+      if (user_wants_environment)
+        code = ({ #'+, ({#'to_string, ({#'environment, ({#'this_player }) }) })
+                     , code });
+      set_prompt(lambda(0, code));
+
+
+2.3.2 Free Variables in Lambda-Closure Constructs
+
+      You can use local variables in lambda constructs without declaring
+      them, just use them. The only limitation is that you at first have
+      to assign something to them. Give them as symbols like you do with
+      the arguments. This feature does not make much sense without the use
+      of complexer flow controlling features described below.
+
+      The closure #'= is used to assign a value to something (like the
+      LPC-operator = is).
+
+2.3.3 Special Efun-Closures and Operator-Closures for Lambdas
+
+      There are some special closures that are supposed to be used only
+      within a lambda construct. With them you can create nearly all code
+      you can with regular LPC-code like loops and conditions.
+
+      #'? acts like the "if" statement in LPC. The first argument is the
+          condition, the second is the code to be executed if the condition
+          returns true. The following arguments can also be such couples of
+          code-arrays that state a condition and a possible result. If at
+          the end there is a single argument, it is used as the else-case
+          if no condition returned true.
+
+          lambda(({ 'x }),({ (#'?),             // if
+                             ({ (#'>),'x,5 }),  //    (x > 5)
+                             ({ (#'*),'x,2 }),  //       result is x * 2;
+                             ({ (#'<),'x,-5 }), // else if (x < -5)
+                             ({ (#'/),'x,2 }),  //    result is x/2;
+                             'x                 // else result is x;
+                          }))
+
+      #'?! is like the #'? but it negates all conditions after evaluation
+           and thus is like an ifnot in LPC (if there were one).
+
+      #', (which looks a bit strange) is the equivalent of the comma-operator
+          in LPC and says: evaluate all arguments and return the value of
+          the last. It is used to do several things inside a lambda-closure.
+
+          lambda(({ 'x }),({ (#',),  // two commas necessary!
+                                     // one for the closure and one as
+                                     // delimiter in the array
+                             ({ (#'write),"hello world!" }),
+                             ({ (#'say),"Foobar." })
+                          }))
+
+      #'while acts like the LPC statement "while" and repeats executing one
+              code-array while another returns true.
+              #'while expects two or more arguments: the condition as first
+              argument, then the result the whole expression shall have after
+              the condition turns false (this is in many cases of no interest)
+              and as third to last argument the body of the loop.
+
+              lambda(0,({ (#',),            // several things to do ...
+                          ({ (#'=),'i,0 }),    // i is a local variable of this
+                                               // lambda-closure and is
+                                               // initialized with 0 now.
+                          ({ (#'while),
+                             ({ (#'<),'i,10 }),   // condition: i < 10
+                             42,                  // result is not interesting,
+                                                  // but we must give one
+                             ({ (#'write),'i }),  // give out i
+                             ({ (#'+=),'i,1 })    // increase i
+                          })
+                       }))
+
+               The function this closure points to will give out the
+               numbers from 0 to 9 and then return 42.
+
+      #'do is like the do-while statement in LPC and is very much like the
+           #'while. The difference is that #'while tests the condition al-
+           ready before the body is evaluated for the first time, this means
+           that the body might not be evaluated even once. #'do evaluates
+           the body first and then the condition, thus the body is evaluated
+           at least one time.
+           Furthermore, the arguments for #'do are changed in order. #'do
+           expects as first to last but two the body of the loop, then the
+           condition (as last-but-one'th argument) and the result value as
+           last argument. So #'do must have at least two arguments: the
+           condition and the result.
+
+           lambda(0,({ (#',),          // several things to do ...
+                       ({ (#'=),'i,0 }),  // i is a local variable of this
+                                          // lambda-closure and is initialized
+                                          // with 0 now.
+                       ({ (#'do),
+                          ({ (#'write),'i }),  // give out i
+                          ({ (#'+=),'i,1 })    // increase i
+                          ({ (#'<),'i,10 }),   // condition: i < 10
+                          42                   // result is not interesting
+                       })
+                    }))
+
+      NOTE: There is no #'for in LPC, you should use #'while for this.
+
+      #'foreach is like the foreach() statement in LPC. It evaluates one or
+           more bodies repeatedly for every value in a giving string, array
+           or mapping. The result of the closure is 0.
+
+           #'foreach expects two or more arguments:
+            - a single variable symbol, or an array with several variable
+              symbols
+            - the value to iterate over
+            - zero or more bodes to evaluate in each iteration.
+
+           The single values retrieved from the given value are assigned
+           one after another to the variable(s), then the bodies are executed
+           for each assignment.
+
+           lambda(0, ({#'foreach, 'o, ({#'users})
+                                    , ({#'call_other, 'o, "die" })
+                     }));
+
+           lambda(0, ({#'foreach, ({'k, 'v}), ({ ...mapping...})
+                                    , ({#'printf, "%O:%O\n", 'k, 'v })
+                     }));
+
+      #'return gets one argument and acts like the "return" statement in LPC
+               in the function that is created by lambda(). It aborts the
+               execution of this function and returns the argument.
+
+               lambda(0,({ (#'while),// loop
+                           1,        // condition is 1 ==> endles loop
+                           42,       // return value (which will never be used)
+                           ({ (#'write),"grin" })
+                           ({ (#'?!),               // ifnot
+                              ({ (#'random),10 }),  //       (random(10))
+                              ({ (#'return),100 })  //   return 100;
+                           })
+                        }))
+
+                This function will enter an endles loop that will in each
+                turn give out "grin" and if random(10) returns 0 (which will
+                of course happen very soon) it will leave the function with
+                "return 100". The value 42 that is given as result of the
+                loop would be returned if the condition would evaluate to 0
+                which cannot be. (1 is never 0 ;-)
+
+      #'break is used like the "break" statement in LPC and aborts the exe-
+              cution of loops and switches.
+              It must not appear outside a loop or switch of the lambda
+              closure itself, it cannot abort the execution of the function
+              the closure points to!
+
+                lambda(0,({ (#'?),
+                            ({ (#'random),2 }),
+                            ({ (#'break) }), // this will cause the error
+                                             // "Unimplemented operator break
+                                             // for lambda()"
+                            "random was false!"
+                         }));
+
+              You can use ({ #'return,0 }) instead of ({ #'break }) in such
+              cases.
+
+      #'continue is used like the "continue" statement in LPC and jumps to
+                 the end of the current loop and continues with the loop
+                 condition.
+
+      #'default may be used within a #'switch-construct but be careful!
+                To call symbol_function("default") (which is done usually
+                by tools that allow closure-creation) might crash the
+                driver! So please do only use it within your LPC-files.
+                (NOTE: This driver bug is fixed somewhere below 3.2.1@131.)
+
+      #'.. may be used within a #'switch-construct but is not implemented
+           yet (3.2.1@131). But #'[..] works well instead of it.
+
+      #'switch is used to create closures which behave very much like the
+               switch-construct in LPC. To understand the following you
+               should already know the syntax and possibilities of the
+               latter one (which is mightier than the C-version of switch).
+
+               I will confront some LPC versions and the corresponding clo-
+               sure versions below.
+
+               LPC:                  Closure:
+                 switch (x) {          lambda(0,({ (#'switch), x,
+                 case 5:                           ({ 5 }),
+                   return "five";                  ({ (#'return),"five" }),
+                                                   (#',),
+                 case 6..9:                        ({ 6, (#'[..]), 9 }),
+                   return "six to nine";           ({ (#'return),
+                                                      "six to nine" }),
+                                                   (#',),
+                 case 1:                           ({ 1 }),
+                   write("one");                   ({ (#'write),"one" }),
+                   // fall through                 (#',),
+                 case 2:                           ({ 2,
+                 case 10:                             10 }),
+                   return "two or ten";            ({ (#'return),
+                                                      "two or ten" }),
+                                                   (#',),
+                 case 3..4:                        ({ 3, (#'[..]), 4 }),
+                   write("three to four");         ({ (#'write),
+                                                      "three to four" }),
+                   break;  // leave switch         (#'break),
+                 default:                          ({ (#'default) }),
+                   write("something else");        ({ (#'write),
+                                                      "something else" }),
+                   break;                          (#'break)
+                 }                              }))
+
+      #'&& evaluates the arguments from the first on and stops if one evalu-
+           ates to 0 and returns 0. If none evaluates to 0 it returns the
+           result of the last argument.
+
+      #'|| evaluates the arguments from the first on and stops if one evalu-
+           ates to true (not 0) and returns it. If all evaluate to 0 it
+           returns 0.
+
+      #'catch executes the closure given as argument, but catches any
+           runtime error (see catch(E)). Optionally the symbols 'nolog,
+           'publish and 'reserve may be given as additional arguments to
+           modify the behaviour of the catch.
+
+      #'sscanf acts similar to how a funcall would, but passes the third
+           and following arguments as lvalues, that is, values which can
+           be assigned to.
+
+      #'= and the #'<op>= variants are also special because the first
+           argument has to be an lvalue.
+
+2.4 Closures with Strange Names
+
+    #'negate is the unary minus that returns -x for the argument x.
+
+             map(({ 1,2,3 }),#'negate)
+
+             This returns ({ -1,-2,-3 }).
+
+    #'[ is used for the things that in LPC are done with
+             the []-operator (it indexes an array or a mapping).
+
+             lambda(0,({ #'[,quote(({ 10,50,30,70 })),2 })) ==> 30
+             lambda(0,({ #'[,([ "x":10;50, "y":30;70 ]),"x",1 })) ==> 50
+
+    #'[< is the same as #'[ but counts the elements from the
+               end (like indexing with [] and the "<").
+
+    #'[..] returns a subarray of the argument from the one
+             given index to the other given index, both counted from the
+             beginning of the array.
+
+    #'[..<]
+    #'[<..]
+    #'[<..<] same as above, but the indexes are counted from the end,
+
+                lambda(0,({ #'[..<],
+                            quote(({ 0,1,2,3,4,5,6,7 })),2,3
+                         }))
+
+                This will return ({ 2,3,4,5 }).
+    #'[..
+    #'[<.. same as above, but only the first index is given, the
+               subarray will go till the end of the original (like with
+               [x..]).
+
+    #'({ is used to create arrays (as with ({ }) in LPC). All arguments
+             become the elements of the array.
+
+             lambda(0,({ #'({,
+                         ({ (#'random),10 }),
+                         ({ (#'random),50 }),
+                         ({ (#'random),30 }),
+                         ({ (#'random),70 })
+                      }))
+
+             This returns ({ random(10),random(50),random(30),random(70) }).
+
+    #'([ is used to create mappings out of single entries (with seve-
+               ral values) like the ([ ]) in LPC. Very unusual is the fact
+               that this closure gets arrays as argument that are not eval-
+               uated, although they are not quoted.
+
+               lambda(0,({ #'([,
+                           ({ "x",1,2,3 }),
+                           ({ "y",4,5,6 })
+                        }));
+
+               This returns ([ "x": 1;2;3,
+                               "y": 4;5;6 ]).
+
+               However, the elements of the arrays are evaluated as lambda
+               expressions, so if you want to create a mapping from values
+               evaluated at call time, write them as lambda closures:
+
+               lambda(0, ({ #'([, ({ 1, ({ #'ctime }) }) }) )
+
+               will return ([ 1: <result of ctime() at call time ]).
+
+               Arrays can be put into the mapping by quoting:
+
+               lambda(0, ({ #'([, ({ 1, '({ 2 }) }) }) )
+
+               will return ([ 1: ({ 2 }) ])
+
+
+    #'[,] is nearly the same as #'[. The only difference
+                     shows up if you want to index a mapping with a width
+                     greater than 1 (with more than just one value per
+                     key) directly with funcall(). Example:
+                     funcall(#'[,([ 0:1;2, 3:4;5 ]),0,1)
+                     This will not work. Use #'[,] and it will
+                     work. If you want to use it in a lambda closure you
+                     do not have to use #'[,] and #'[ will
+                     do fine. On the other hand, #'[,] cannot
+                     work with arrays, so in nearly all cases use #'[
+                     and just in the described special case, use
+                     #'[,].
+                     This is a strange thing and I deem it a bug, so it
+                     might change in the future.
+
+2.5 Operator-Closures
+
+    Most of the closures that are used for things which are done by opera-
+    tors are in fact not operator-closures but efun-closures. But there are
+    a few which do not have the state of efun-closures but are called
+    "operator-closures". #'return is an example, a complete list of them is
+    given below.
+
+    These closures cannot be called directly using funcall() or apply() (or
+    other efuns like filter()), but must appear only in lambda-con-
+    structs.
+
+      funcall(#'return,4);  // does not work! This will raise an
+                            // Uncallable-closure error.
+      funcall(lambda(0,     // this is a correct example
+                     ({ (#'return),4 })
+                    ));
+
+    All operator-closures:
+    #'&&
+    #'||
+    #',
+    #'?
+    #'?!
+    #'=
+    #'<op>=
+    #'++
+    #'--
+    #'break
+    #'catch
+    #'continue
+    #'default
+    #'do
+    #'foreach
+    #'return
+    #'sscanf
+    #'switch
+    #'while
+    #'({
+    #'([
+
+    #'.. is very likely to be an operator closure too, but since it is
+    not implemented yet, I cannot say for sure.
+
+2.6 Variable-Closures
+
+    All object-global variables might be "closured" by prepending a #' to
+    them to allow access and/or manipulation of them. So if your object has
+    a global variable x you can use #'x within a closure.
+
+    Normally you will treat those expressions like lfun-closures: put them
+    into an array to get the value:
+
+    object.c:
+              int x;
+              int foo() {
+                return lambda(0,({ (#'write),({ (#'x) }) }));
+              }
+
+    Anybody who now calls object->foo() will get a closure which will, when
+    evaluated, write the actual value of object's global variable x.
+
+    Variable closures do not accept arguments.
+
+3 Examples
+
+  In this section I will give and explain some examples coming out of
+  praxis. If the explanation seems to be in some cases too detailed this
+  can be explained by the trial to allow the reader to read the examples
+  section first ;-)
+
+3.1 Lfun-Closure
+
+    An item with a complex long-description like a watch that shall always
+    show the actual time will usually base upon the complex/item-class and
+    give an lfun-closure as argument to the set_long()-method.
+
+    watch.c:
+             inherit "complex/item";
+
+             string my_long() {
+               return ("The watch is small and has a strange otherworldly"
+                       " aura about it.\n"
+                       "The current time is: "+ctime()+".\n");
+             }
+
+             void create() {
+               set_short("a little watch");
+               set_id(({ "watch","little watch" }));
+               set_long(#'my_long);  // the lfun-closure to the lfun my_long()
+             }
+
+3.2 Lambda-Closure
+
+    The example from 3.1 can also be written using a lambda-closure.
+
+    watch.c:
+             inherit "complex/item";
+
+             void create() {
+               set_short("a little watch");
+               set_id(({ "watch","little watch" }));
+               set_long(lambda(0,({ (#'+),
+                                    "The watch is small and has a strange"
+                                    " otherworldly aura about it.\n"
+                                    "The current time is: ",
+                                    ({ (#'+),
+                                       ({ (#'ctime) }),
+                                       ".\n"
+                                    })
+                                 })));
+             }
diff --git a/doc/LPC/closures b/doc/LPC/closures
new file mode 100644
index 0000000..ba5d804
--- /dev/null
+++ b/doc/LPC/closures
@@ -0,0 +1,331 @@
+CONCEPT
+        closures
+
+NOTE
+        This is the official man page concerning closures. If you find
+        it hard to read maybe the Closure Guide is an easier introduction
+        for you: See closure_guide(LPC) and closures-example(LPC).
+
+DESCRIPTION
+        Closures provide a means of creating code dynamically and
+        passing pieces of code as parameters, storing them in
+        variables. One might think of them as a very advanced form of
+        process_string(). However, this falls short of what you can
+        actually do with them.
+
+        The simplest kind of closures are efuns, lfuns or operators.
+        For example, #'this_player is an example of a closure. You can
+        assign it to a variable as in
+
+                closure f;
+                object p;
+                f = #'this_player;
+
+        and later use either the funcall() or apply() efun to evaluate
+        it. Like
+
+                p = funcall(f);
+
+        or
+
+                p = apply(f);
+
+        In both cases there p will afterwards hold the value of
+        this_player().  Of course, this is only a rather simple
+        application.
+
+        Inline closures are a variant of lfun closures, the difference
+        being that the function text is written right where the
+        closure is used.  Since they are pretty powerful by
+        themselves, inline closures have their own manpage.
+
+        More useful instances of closures can be created
+        using the lambda() efun. It is much like the lambda function
+        in LISP. For example, you can do the following:
+
+                f = lambda( ({ 'x }), ({ #'environment, 'x }) );
+
+        This will create a lambda closure and assign it to f. The
+        first argument to lambda is an array describing the arguments
+        (symbols) passed to the closure upon evaluation by funcall()
+        or apply(). You can now evaluate f, for example by means of
+        funcall(f,this_object()). This will result in the following
+        steps:
+
+                1. The value of this_object() will be bound to symbol x.
+                2. environment(x) evaluates to environment(this_object())
+                   and is returned as the result of the funcall().
+
+        One might wonder why there are two functions, funcall() and
+        apply(), to perform the seemingly same job, namely evaluating
+        a closure. Of course there is a subtle difference. If the last
+        argument to apply() is an array, then each of its elements
+        gets expanded to an additional paramater. The obvious use
+        would be #'call_other as in:
+
+                mixed eval(object ob,string func,mixed *args) {
+                  return apply(#'call_other,ob,func,args);
+                }
+
+        This will result in calling
+        ob->func(args[0],args[1],...,args[sizeof(args)-1]).  Using
+        funcall() instead of apply() would have given us
+        ob->func(args).
+
+        Of course, besides efuns there are closures for operators,
+        like #'+, '-, #'<, #'&&, etc.
+
+        Well, so far closures have been pretty much limited despite
+        their obvious flexibility. This changes now with the
+        introduction of conditional and loop operators. For example,
+        try:
+
+                closure max;
+                max = lambda( ({ 'x, 'y }),
+                              ({ #'? ,({ #'>, 'x, 'y }), 'x, 'y }) );
+                return funcall(max,7,3);
+
+        The above example will return 7. What happened? Of course #'?
+        is the conditional operator and its 'syntax' is as follows:
+
+                ({ #'?, cond1, val1, cond2, val2, ..., condn, valn,
+                  valdefault });
+
+        It evaluates cond1, cond2, ..., condn successively until it
+        gets a nonzero result and then returns the corresponding
+        value. If there is no condition evaluating to a nonzero
+        result, valdefault gets returned. If valdefault is omitted, 0
+        gets returned. #'?! works just like #'?, except that the !
+        operator is applied to conditions before testing. Therefore,
+        while #'? is somewhat like an if statement, #'?! resembles an
+        if_not statement if there were one.
+
+        There are also loops:
+
+                ({ #'do, loopbody1, ..., loopbodyN, loopcond, loopresult })
+
+        will evaluate the loopbodies until loopcond evaluates to 0 and
+        then return the value of loopresult. Symbols may be used as
+        variables, of course.
+
+                ({ #'while, loopcond, loopresult, loopbody1, ..., loopbodyN })
+
+        works similar but evaluates loopcond before the loopbodies.
+
+        The foreach() loop also exists:
+
+                ({ #'foreach, 'var, expr, loopbody1, ..., loopbodyN })
+                ({ #'foreach, ({ 'var1, ..., 'varN}) , expr
+                                        , loopbody1, ..., loopbodyN })
+
+
+        Now on to a couple of tricky things:
+
+        a) How do I write down an array within a lambda closure to
+           avoid interpretation as a subclosure?
+
+           ({ #'member, ({ "abc", "xyz" }), 'x }) will obviously
+           result in an error as soon as lambda() tries to interpret
+           "abc" as a closure operator. The solution is to quote the
+           array, as in: ({ #'member, '({ "abc", "xyz" }), 'x }).
+           Applying lambda() to this will not result in an error.
+           Instead, the quote will be stripped from the array and the
+           result regarded as a normal array literal. The same can be
+           achieved by using the efun quote(), e.g.:
+
+           ({ #'member, quote( ({ "abc", "xyz" }), 'x ) })
+
+        b) Isn't it a security risk to pass, say, a closure to the
+           master object which then evaluates it with all the
+           permissions it got?
+
+           Luckily, no. Each closure gets upon compilation bound to
+           the object defining it. That means that executing it first
+           sets this_object() to the object that defined it and then
+           evaluates the closure. This also allows us to call lfuns
+           which might otherwise be undefined in the calling object.
+
+           There is however, a variant of lambda(), called
+           unbound_lambda(), which works similar but does not allow
+           the use of lfuns and does not bind the closure to the
+           defining object. The drawback is that trying to evaluate it
+           by apply() or funcall() will result in an error. The
+           closure first needs to be bound by calling bind_lambda().
+           bind_lambda() normally takes one argument and transforms an
+           unbound closure into a closure bound to the object
+           executing the bind_lambda().
+
+           Privileged objects, like the master and the simul_efun
+           object (or those authorized by the privilege_violation()
+           function in the master) may also give an object as the
+           second argument to bind_lambda(). This will bind the
+           closure to that object. A sample application is:
+
+           dump_object(ob)
+           // will dump the variables of ob to /dump.o
+           {
+             closure save;
+             save = unbound_lambda( ({ }),
+                                    ({ #'save_object, "/open/dump" }) );
+             bind_lambda(save,ob);
+             funcall(save);
+           }
+
+           bind_lambda() can also be used with efun closures.
+
+        c) It might be an interesting application to create closures
+           dynamically as an alternative to writing LPC code to a file
+           and then loading it.  However, how do I avoid doing exactly
+           that if I need symbols like 'x or 'y?
+
+           To do that one uses the quote() efun. It takes a string as
+           its argument and transforms it into a symbol. For example,
+           writing quote("x") is exactly the same as writing 'x.
+
+        d) How do I test if a variable holds a closure?
+
+           Use the closurep() efun which works like all the other type
+           testing efuns. For symbols there is also symbolp()
+           available.
+
+        e) That means, I can do:
+           if (closurep(f)) return funcall(f); else return f; ?
+
+           Yes, but in the case of funcall() it is unnecessary. If
+           funcall() gets only one argument and it is not a closure it
+           will be returned unchanged. So return funcall(f); would
+           suffice.
+
+        f) I want to use a function in some object as a closure. How do I do
+           that?
+
+           There are several ways. If the function resides in
+           this_object(), just use #'func_name. If not, or if you want
+           to create the function dnynamically, use the efun
+           symbol_function(). It takes a string as it first and an
+           object as its second argument and returns a closure which
+           upon evaluation calls the given function in the given
+           object (and faster than call_other(), too, if done from
+           inside a loop, since function search will be done only when
+           calling symbol_function().
+
+        g) Can I create efun closures dynamically, too?
+
+           Yes, just use symbol_function() with a single argument.
+           Most useful for marker objects and the like. But
+           theoretically a security risk if not used properly and from
+           inside a security relevant object.  Take care, however,
+           that, if there is a simul_efun with the same name, it will
+           be preferred as in the case of #'function. Use the efun::
+           modifier to get the efun if you need it.
+
+        h) Are there other uses of closures except using them to store
+           code?
+
+           Lots. For example, you can use them within almost all of
+           the efuns where you give a function as an argument, like
+           filter(), sort_array() or walk_mapping().
+           sort_array(array,#'>) does indeed what is expected. Another
+           application is set_prompt(), where a closure can output
+           your own prompt based on the current time and other stuff
+           which changes all the time.
+
+        Finally, there are some special efun/operator closures:
+
+        #'[ : indexes an array.
+        #'[< : does the same, but starting at the end.
+        #'[..] : gets an array and two numbers
+                and returns a sub-array.
+        #'[..<] : same as above but the second index is
+                interpreted as counted from the left end.
+        #'[<..]  and
+        #'[<..<] : should be clear now.
+        #'[.. : takes only one index and returns the sub-
+                array from this index to the end.
+        #'[<.. : same as above but the index is interpreted
+                as counted from the left end.
+        #'({ : puts all arguments into an array.
+        #'([ : gets an unquoted (!) array which must include
+                at least one element as argument and returns a mapping of
+                the width of the given array's size with one entry that
+                contains the first element as key and the other elements
+                as values to the key.
+
+        #'negate is for unary minus.
+        #', may be followed by any number of closures,
+        e.g.: ({ (#',),
+                 ({#'= 'h, 'a, }), ({#'=, 'a, 'b }), ({#'=, 'b, 'h }) })
+        will swap 'a and 'b when compiled and executed.
+
+
+        Procedural elements:
+        ====================
+
+        definition of terms:
+          <block>  : zero or more values to be evaluated.
+          <test>   : one value to be evaluated as branch or loop condition.
+          <result> : one value to be evaluated at the end of the
+                     execution of the form; the value is returned.
+          <lvalue> : local variable/parameter, global variable, or an
+                     indexed lvalue.
+        useded EBNF operators:
+        { }     iteration
+        [ ]     option
+
+        forms:
+          ({#', <body> <result>})
+          ({#'? { <test> <result> } [ <result> ] })
+          ({#'?! { <test> <result> } [ <result> ] })
+          ({#'&& { test } })
+          ({#'|| { test } })
+          ({#'while <test> <result> <body>})    loop while test
+                                                evaluates non-zero.
+          ({#'do <body> <test> <result>})       loop till test
+                                                evaluates zero.
+          ({#'= { <lvalue> <value> } })         assignment
+                                                other assignment
+                                                operators work, too.
+
+        lisp similars:
+          #',           progn
+          #'?           cond
+          #'&&          and
+          #'||          or
+          #'while       do      /* but lisp has more syntactic candy here */
+          #'=           setq
+
+        A parameter / local variable 'foo' is referenced as 'foo , a
+        global variable as ({#'foo}) . In lvalue positions
+        (assignment), you need not enclose global variable closures in
+        arrays.
+
+        Call by reference parameters are given with ({#'&, <lvalue>})
+
+        Some special efuns:
+        #'[             indexing
+        #'[<            indexing from the end
+        #'negate        unary -
+
+        Unbound lambda closures
+        =======================
+
+        These closures are not bound to any object. They are created
+        with the efun unbound_lambda() . They cannot contain
+        references to global variables, and all lfun closures are
+        inserted as is, since there is no native object for this
+        closure.  You can bind and rebind unbound lambda closures to
+        an object with efun bind_lambda() You need to bind it before
+        it can be called. Ordinary objects can obly bind to
+        themselves, binding to other objects causes a privilege
+        violation().  The point is that previous_object for calls done
+        from inside the closure will reflect the object doing
+        bind_lambda(), and all object / uid based security will also
+        refer to this object.
+
+
+AUTHOR
+        MacBeth, Amylaar, Hyp
+
+SEE ALSO
+        closures-abstract(LPC), closures-example(LPC), closure_guide(LPC)
+        inline-closures(LPC)
diff --git a/doc/LPC/closures-abstract b/doc/LPC/closures-abstract
new file mode 100644
index 0000000..6b1d932
--- /dev/null
+++ b/doc/LPC/closures-abstract
@@ -0,0 +1,82 @@
+Procedural elements:
+====================
+
+definition of terms:
+  <block>     : zero or more values to be evaluated.
+  <test>      : one value to be evaluated as branch or loop condition.
+  <result>    : one value to be evaluated at the end of the execution of
+                the form; the value is returned.
+  <lvalue>    : local variable/parameter, global variable, or an indexed
+                lvalue.
+  <expression>: one value to be evaluated.
+  <integer>   : an integer constant
+  <string>    : a string constant, or 0.
+used EBNF operators:
+{ }        iteration
+[ ]        option
+|        alternative
+
+forms:
+  ({#', <body> <result>})
+  ({#'? { <test> <result> } [ <result> ] })
+  ({#'?! { <test> <result> } [ <result> ] })
+  ({#'&& { test } })
+  ({#'|| { test } })
+  ({#'while <test> <result> <body>...})        loop while test evaluates non-zero.
+  ({#'do <body> <test> <result>})        loop till test evaluates zero.
+  ({#'foreach <var> <expr> <body>...})        loop over all values of <expr>.
+  ({#'foreach ({ <var>...<var> }) <expr> <body>...})
+  ({#'= { <lvalue> <value> } })                assignment
+                			other assignment operators work too.
+  case_label: <integer> | <string> | #'default
+  generalized_case_label: case_label | <integer> #'.. <integer>
+  case_label_list: case_label | ({ { generalized_case_label } })
+  case_delimiter: #', | #'break
+  ({#'switch <expression> { case_label_list <result> case_delimiter } })
+        Evaluate expression, then evaluate the result form labeled with
+        the value equal to the value evaluated from expression.
+        If no matching label exists, the value of #'switch is 0.
+  ({#'catch, <body> [, 'nolog ] [, 'publish ], [, 'reserve, <expr>  })
+        Evaluates the <body> and catches any runtime error. If the symbol
+        'nolog is also given, a caught error is not logged. If the
+        symbol 'publish is also given, master::runtime_error() is
+        called for the caught error. If the symbol 'reserve with a
+        following expression is given, this value is used as the
+        computing reserve.
+
+
+lisp similars:
+  #',                progn
+  #'?                cond
+  #'&&                and
+  #'||                or
+  #'while        do         /* but lisp has more syntactic candy here */
+  #'=                setq
+
+A parameter / local variable 'foo' is referenced as 'foo , a global
+variable as ({#'foo}) . In lvalue positions (assignment), you need not
+enclose global variable closures in arrays.
+
+Call by reference parameters are given with ({#'&, <lvalue>})
+
+Some special efuns:
+#'[                indexing
+#'[<                indexing from the end
+#'negate        unary -
+
+Unbound lambda closures
+=======================
+
+These closures are not bound to any object. They are created with the efun
+unbound_lambda() . They cannot contain references to global variables, and
+all lfun closures are inserted as is, since there is no native object for
+this closure.
+You can bind and rebind unbound lambda closures to an object with efun
+bind_lambda() You need to bind it before it can be called. Ordinary objects
+can obly bind to themselves, binding to other objects causes a privilege
+violation().
+The point is that previous_object for calls done from inside the closure
+will reflect the object doing bind_lambda(), and all object / uid based
+security will also refer to this object.
+
+
diff --git a/doc/LPC/closures-example b/doc/LPC/closures-example
new file mode 100644
index 0000000..f50fd35
--- /dev/null
+++ b/doc/LPC/closures-example
@@ -0,0 +1,202 @@
+CONCEPT
+        closures example
+
+DESCRIPTION
+        This document contains small examples of the usage of
+        (lambda-)closures. For technical details see the closures(LPC)
+        doc. For hints when to use which type of closure, see the end
+        of this doc.
+
+
+        Many Muds use 'details' to add more flavour. 'Details' are
+        items which can be looked at, but are not implemented as own
+        objects, but instead simulated by the environment.
+        Lets assume that the function
+
+          AddDetail(string keyword, string|closure desc)
+
+        adds the detail 'keyword' to the room, which, when look at,
+        returns the string 'desc' resp. the result of the execution of
+        closure 'desc' as the detail description to the player.
+
+        Now imagine that one wants to equip a room with magic runes,
+        which read as 'Hello <playername>!\n" when looked at.
+        Obviously
+
+          AddDetail("runes", sprintf( "Hello %s!\n"
+                                    , this_player()->QueryName()));
+
+        is not sufficient, as the 'this_player()' is executed to early
+        and just once: for the player loading the room.
+
+        The solution is to use closures. First, the solution using
+        lfun-closures:
+
+          private string _detail_runes () {
+            return sprintf("Hello %s!\n", this_player()->QueryName());
+          }
+            ...
+          AddDetail("runes", #'_detail_runes);
+
+        or with an inline closure:
+
+          AddDetail("runes"
+                   , (: sprintf("Hello %s!\n", this_player()->QueryName()) :)
+                   );
+
+
+        Simple? Here is the same code, this time as lambda-closure:
+
+          AddDetail( "runes"
+                   , lambda(0
+                     , ({#'sprintf, "Hello %s!\n"
+                                  , ({#'call_other, ({#'this_player})
+                                                  , "QueryName" })
+                       })
+                   ));
+
+        Why the extra ({ }) around '#'this_player'? #'this_player
+        alone is just a symbol, symbolizing the efun this_player(),
+        but call_other() needs an object as first argument. Therefore,
+        the #'this_player has to be interpreted as function to
+        evaluate, which is enforced by enclosing it in ({ }). The same
+        reason also dictates the enclosing of the whole #'call_other
+        expression into ({ }).
+        Note also the missing #'return: it is not needed. The result
+        of a lambda-closure is the last value computed.
+
+
+        Another example: Task is to reduce the HP of every living in a
+        room by 10, unless the result would be negative.
+        Selecting all livings in a room is simply
+
+          filter(all_inventory(room), #'living)
+
+        The tricky part is to reduce the HP. Again, first the
+        lfun-closure solution:
+
+          private _reduce_hp (object liv) {
+            int hp;
+            hp = liv->QueryHP();
+            if (hp > 10)
+              liv->SetHP(hp-10);
+          }
+            ...
+
+          map( filter(all_inventory(room), #'living)
+                   , #'_reduce_hp)
+
+        or as an inline closure:
+
+          map( filter(all_inventory(room), #'living)
+                   , (: int hp;
+                        hp = liv->QueryHP();
+                        if (hp > 10)
+                          liv->SetHP(hp - 10);
+                      :) );
+
+        Both filter() and map() pass the actual array item
+        being filtered/mapped as first argument to the closure.
+
+        Now, the lambda-closure solution:
+
+          map( filter(all_inventory(room), #'living)
+          , lambda( ({ 'liv })
+            , ({'#, , ({#'=, 'hp, ({#'call_other, 'liv, "QueryHP" }) })
+                    , ({#'?, ({#'>, 'hp, 10 })
+                           , ({#'call_other, 'liv, "SetHP"
+                                           , ({#'-, 'hp, 10 })
+                             })
+                      })
+              })
+            ) // of lambda()
+          );
+
+        It is worthy to point out how local variables like 'hp' are
+        declared in a lambda-closure: not at all. They are just used
+        by writing their symbol 'hp . Same applies to the closures
+        parameter 'liv .
+        The lambda-closure solution is not recommended for three
+        reasons: it is complicated, does not use the powers of
+        lambda(), and the lambda() is recompiled every time this
+        statement is executed!
+
+
+        So far, lambda-closures seem to be just complicated, and in
+        fact: they are. Their powers lie elsewhere.
+
+        Imagine a computation, like for skill resolution, which
+        involves two object properties multiplied with factors and
+        then added.
+        The straightforward solution would be a function like:
+
+          int Compute (object obj, string stat1, int factor1
+                                 , string stat2, int factor2)
+          {
+            return   call_other(obj, "Query"+stat1) * factor1
+                   + call_other(obj, "Query"+stat2) * factor2;
+          }
+
+        Each call to Compute() involves several operations (computing
+        the function names and resolving the call_other()s) which in
+        fact need to be done just once. Using lambda-closures, one can
+        construct and compile a piece of code which behaves like a
+        Compute() tailored for a specific stat/factor combination:
+
+          closure ConstructCompute (object obj, string stat1, int factor1
+                                              , string stat2, int factor2)
+          {
+            mixed code;
+
+            // Construct the first multiplication.
+            // The symbol_function() creates a symbol for the
+            // lfun 'Query<stat1>', speeding up later calls.
+            // Note again the extra ({ }) around the created symbol.
+
+            code = ({#'*, ({ symbol_function("Query"+stat1, obj) })
+                        , factor1 });
+
+            // Construct the second multiplication, and the addition
+            // of both terms.
+
+            code = ({#'+, code
+                        , ({#'*, ({ symbol_function("Query"+stat2, obj) })
+                               , factor2 })
+                   });
+
+            // Compile the code and return the generated closure.
+            return lambda(0, code);
+          }
+
+        Once the closure is compiled,
+
+          str_dex_fun = ConstructCompute(obj, "Str", 10, "Dex", 90);
+
+        it can be used with a simple 'funcall(str_dex_fun)'.
+
+
+DESCRIPTION -- When to use which closure?
+        First, a closure is only then useful if it needn't to live any
+        longer than the object defining it. Reason: when the defining
+        object gets destructed, the closure will vanish, too.
+
+        Efun-, lfun- and inline closures should be used where useful, as they
+        mostly do the job and are easy to read. The disadvantage of lfun- and
+        inline closures is that they make a replace_program() impossible
+        - but since such objects tend to not being replaceable at all, this is
+        no real loss.
+
+        Lambda closures are needed if the actions of the closure are
+        heavily depending on some data available only at runtime, like
+        the actual inventory of a certain player.
+        If you use lfun-closures and find yourself shoving around
+        runtime data in arguments or (gasp!) global variables, it is
+        time to think about using a lambda-closure, compiling the
+        value hard into it.
+        The disadvantages of lambda closures are clear: they are damn
+        hard to read, and each lambda() statement requires extra time to
+        compile the closure.
+
+
+SEE ALSO
+        closures(LPC), closure_guide(LPC), closures-abstract(LPC)
diff --git a/doc/LPC/closures2 b/doc/LPC/closures2
new file mode 100644
index 0000000..fc52894
--- /dev/null
+++ b/doc/LPC/closures2
@@ -0,0 +1,369 @@
+Closures provide a means of creating code dynamically and passing pieces
+of code as parameters, storing them in variables. One might think of them
+as a very advanced form of process_string(). However, this falls short of
+what you can actually do with them.
+
+The simplest kind of closures are efuns, lfuns or operators. For
+example, #'this_player is an example of a closure. You can assign it
+to a variable as in
+
+	closure f;
+	object p;
+	f = #'this_player;
+
+and later use either the funcall() or apply() efun to evaluate it. Like
+
+	p = funcall(f);
+
+or
+	p = apply(f);
+
+In both cases there p will afterwards hold the value of this_player().
+Of course, this is only a rather simple application. More useful
+instances of closures can be created using the lambda() efun. It is much
+like the lambda function in LISP. For example, you can do the following:
+
+	f = lambda( ({ 'x }), ({ #'environment, 'x }) );
+
+This will create a lambda closure and assign it to f. The first argument
+to lambda is an array describing the arguments (symbols) passed to the
+closure upon evaluation by funcall() or apply(). You can now evaluate f,
+for example by means of funcall(f,this_object()). This will result in
+the following steps:
+
+	1. The value of this_object() will be bound to symbol x.
+	2. environment(x) evaluates to environment(this_object())
+	   and is returned as the result of the funcall().
+
+One might wonder why there are two functions, funcall() and apply(), to
+perform the seemingly same job, namely evaluating a closure. Of course
+there is a subtle difference. If the last argument to apply() is an array,
+then each of its elements gets expanded to an additional paramater. The
+obvious use would be #'call_other as in:
+
+	mixed eval(object ob,string func,mixed *args)
+	{
+	  return apply(#'call_other,ob,func,args);
+	}
+
+This will result in calling ob->func(args[0],args[1],...,args[sizeof(args)-1]).
+Using funcall() instead of apply() would have given us ob->func(args).
+
+Of course, besides efuns there are closures for operators, like #'+,
+#'-, #'<, #'&&, etc.
+
+Well, so far closures have been pretty much limited despite their
+obvious flexibility. This changes now with the introduction of
+conditional and loop operators. For example, try:
+
+	closure max;
+	max = lambda( ({ 'x, 'y }), ({ #'? ,({ #'>, 'x, 'y}), 'x, 'y }) });
+	return funcall(max,7,3);
+
+The above example will return 7. What happened? Of course #'? is the
+conditional operator and its 'syntax' is as follows:
+
+	({ #'?, cond1, val1, cond2, val2, ..., condn, valn, valdefault });
+
+It evaluates cond1, cond2, ..., condn successively until it gets a
+nonzero result and then returns the corresponding value. If there is no
+condition evaluating to a nonzero result, valdefault gets returned. If
+valdefault is omitted, 0 gets returned. #'?! works just like #'?, except
+that the ! operator is applied to conditions before testing. Therefore,
+while #'? is somewhat like an if statement, #'?! resembles an if_not
+statement if there were one.
+
+	There are also loops:
+	({ #'do, loopbody, loopcond, loopresult })
+	will evaluate loopbody until loopcond evaluates to 0 and
+	then return the value of loopresult. Symbols my be used
+	as variables, of course.
+
+	({ #'while, loopcond, loopresult, loopbody })
+	works similar but evaluates loopcond before loopbody.
+
+There are, however, some questions open:
+
+a) How do I write down an array within a lambda closure to avoid
+   interpretation as a subclosure?
+   ({ #'member_array, 'x, ({ "abc", "xyz }) }) will obviously result in
+   an error as soon as lambda() tries to interpret "abc" as a closure
+   operator. The solution is to quote the array, as in:
+   ({ #'member_array, 'x, '({ "abc", "xyz }) }). Applying lambda() to
+   this will not result in an error. Instead, the quote will be stripped
+   from the array and the result regarded as a normal array literal. The
+   same can be achieved by using the efun quote(), e.g.:
+   ({ #'member_array, 'x, quote( ({ "abc", "xyz }) ) })
+b) Isn't it a security risk to pass, say, a closure to the master object
+   which then evaluates it with all the permissions it got?
+   Luckily, no. Each closure gets upon compilation bound to the object
+   defining it. That means that executing it first sets this_object()
+   to the object that defined it and then evaluates the closure. This
+   also allows us to call lfuns which might otherwise be undefined in
+   the calling object.
+   There is however, a variant of lambda(), called unbound_lambda(),
+   which works similar but does not allow the use of lfuns and does not
+   bind the closure to the defining object. The drawback is that trying
+   to evaluate it by apply() or funcall() will result in an error. The
+   closure first needs to be bound by calling bind_lambda().
+   bind_lambda() normally takes one argument and transforms an unbound
+   closure into a closure bound to the object executing the
+   bind_lambda().
+   Privileged objects, like the master and the simul_efun object (or
+   those authorized by the privilege_violation() function in the master)
+   may also give an object as the second argument to bind_lambda(). This
+   will bind the closure to that object. A sample application is:
+
+   dump_object(ob)
+   // will dump the variables of ob to /dump.o
+   {
+     closure save;
+     save = unbound_lambda( ({ }), ({ #'save_object, "/open/dump" }) );
+     bind_lambda(save,ob);
+     funcall(save);
+   }
+
+   bind_lambda() can also be used with efun closures.
+
+c) It might be an interesting application to create closures dynamically
+   as an alternative to writing LPC code to a file and then loading it.
+   However, how do I avoid doing exactly that if I need symbols like 'x
+   or 'y?
+   To do that one uses the quote() efun. It takes a string as its
+   argument and transforms it into a symbol. For example, writing
+   quote("x") is exactly the same as writing 'x.
+
+d) How do I test if a variable holds a closure?
+   Use the closurep() efun which works like all the other type testing
+   efuns. For symbols there is also symbolp() available.
+
+e) That means, I can do:
+   if (closurep(f)) return funcall(f); else return f; ?
+   Yes, but in the case of funcall() it is unnecessary. If funcall()
+   gets only one argument and it is not a closure it will be returned
+   unchanged. So return funcall(f); would suffice.
+
+f) I want to use a function in some object as a closure. How do I do
+   that?
+   There are several ways. If the function resides in this_object(),
+   just use #'func_name. If not, or if you want to create the function
+   dnynamically, use the efun symbol_function(). It takes a string as
+   it first and an object as its second argument and returns a closure
+   which upon evaluation calls the given function in the given object
+   (and faster than call_other(), too, if done from inside a loop,
+   since function search will be done only when calling symbol_function().
+
+g) Can I create efun closures dynamically, too?
+   Yes, just use symbol_function() with a single argument. Most useful
+   for marker objects and the like. But theoretically a security risk
+   if not used properly and from inside a security relevant object.
+   Take care, however, that, if there is a simul_efun with the same
+   name, it will be preferred as in the case of #'function. Use the
+   efun:: modifier to get the efun if you need it.
+
+h) Are there other uses of closures except using them to store code?
+   Lots. For example, you can use them within almost all of the
+   efuns where you give a function as an argument, like filter(),
+   sort_array() or walk_mapping(). sort_array(array,#'>) does indeed
+   what is expected. Another application is set_prompt(), where a
+   closure can output your own prompt based on the current time and other
+   stuff which changes all the time.
+
+Finally, there are some special efun/operator closures:
+
+#'[ indexes an array.
+#'[< does the same, but starting at the end.
+#'negate is for unary minus.
+#', may be followed by any number of closures,
+e.g.: ({ #', ({#'= 'h, 'a, }), ({#'=, 'a, 'b }), ({#'=, 'b, 'h }) })
+will swap 'a and 'b when compiled and executed.
+
+------------
+An example from Amylaar:
+
+#I have tested the replace_program() functionality with one example, which I
+#include below. The room is commonly known as /room/orc_valley.c .
+#A prerequisite to make this work is to have valued properties in room.c .
+#The property C_EXTRA_RESET, if defined, is evaluated at reset time in
+#the reset() of the used room.c .
+#Moreover, you need a function to query an unprocessed property to use
+#orc_valley.c from fortress.c (That is, don't do an automatic funcall there.)
+#If you can't supply such a function, you have to set the property "get_orc"
+#at the end of orc_valley.c 's extra_reset() with:
+#    add_prop("get_orc", lambda(0, get_orc) );
+#which will set the property to a function that returns the function that
+#is in the variable get_orc at the time you do the add_prop() call.
+#
+#Back to fortress.c : Assume you have the function successfully queried and
+#stored in the variable get_orc. Now you can compute your extra_reset()
+#function by:
+#    get_orc = lambda( 0, ({#'funcall, get_orc, 8, 40}) );
+#which creates the usual 8 orcs with an a_chat chance of 40.
+#
+#Here comes the orc_valley.c source:
+#
+#    ----------- cut here ------- cut here -------- cut here ------------
+#
+##include "room.h"
+##include "/sys/stdproperties.h"
+##undef EXTRA_RESET
+##define EXTRA_RESET extra_reset();
+#
+#extra_reset() {
+#    closure get_orc;
+#
+#    replace_program("room/room"); /* Must come first. */
+#    get_orc = lambda( ({'num_orcs, 'chat_chance}),
+#       ({#'?!, ({#'present, "orc", ({#'previous_object}) }),
+#           ({#'do,
+#               ({#'=, 'orc, ({#'clone_object, "obj/monster"}) }),
+#               ({#'=, 'i, 9}),
+#               ({#'do,
+#                   ({#'call_other, 'orc, "set_level",
+#                       ({#'+, ({#'random, 2}), 1}) }),
+#                   ({#'call_other, 'orc,
+#                       ({#'[,
+#                           quote(({"set_aggressive", "set_ac", "set_short",
+#                              "set_al", "set_ep", "set_hp", "set_race",
+#                              "set_alias", "set_name"})), ({#'-=, 'i, 1}) }),
+#                       ({#'[,
+#                           quote(({1, 0, "An orc", -60, 1014, 30, "orc",
+#                              "dirty crap", "orc"})), 'i}) }),
+#               'i, 0}),
+#               ({#'call_other, 'orc, "load_a_chat", 'chat_chance,
+#                   quote(({ "Orc says: Kill 'em!\n",
+#                       "Orc says: Bloody humans!\n",
+#                       "Orc says: Stop 'em!\n",
+#                       "Orc says: Get 'em!\n",
+#                       "Orc says: Let's rip out his guts!\n",
+#                       "Orc says: Kill 'em before they run away!\n",
+#                       "Orc says: What is that human doing here!\n",
+#                   })) }),
+#               ({#'=, 'n, ({#'*, ({#'random, 3}), 5}) }),
+#               ({#'=, 'weapon, ({#'clone_object, "obj/weapon"}) }),
+#               ({#'=, 'i, 5}),
+#               ({#'do,
+#                   ({#'call_other, 'weapon,
+#                       ({#'[,
+#                           quote(({ "set_alt_name", "set_weight", "set_value",
+#                               "set_class", "set_name"})), ({#'-=, 'i, 1}) }),
+#                       ({#'[,
+#                           quote(({ "knife", 1, 8,  5, "knife",
+#                               "knife", 1, 15, 7, "curved knife",
+#                               "axe",   2, 25, 9, "hand axe",  })),
+#                           ({#'+, 'n, 'i}) }) }),
+#               'i, 0}),
+#               ({#'transfer, 'weapon, 'orc}),
+#               ({#'command,
+#                   ({#'+, "wield ",
+#                       ({#'call_other, 'weapon, "query_name"}) }), 'orc}),
+#               ({#'move_object, 'orc, ({#'previous_object}) }),
+#           ({#'-=, 'num_orcs, 1}), 0})
+#       })
+#    );
+#    add_prop("get_orc", get_orc);
+#    get_orc = lambda( 0, ({#'funcall, get_orc, 2, 50}) );
+#    add_prop(C_EXTRA_RESET, get_orc);
+#    funcall(get_orc);
+#}
+#
+#TWO_EXIT("room/slope", "east",
+#        "room/fortress", "north",
+#        "The orc valley",
+#        "You are in the orc valley. This place is inhabited by orcs.\n" +
+#        "There is a fortress to the north, with lot of signs of orcs.\n", 1)
+#
+#    ----------- cut here ------- cut here -------- cut here ------------
+#
+Procedural elements:
+====================
+
+definition of terms:
+  <block>  : zero or more values to be evaluated.
+  <test>   : one value to be evaluated as branch or loop condition.
+  <result> : one value to be evaluated at the end of the execution of the
+             form; the value is returned.
+  <lvalue> : local variable/parameter, global variable, or an indexed lvalue.
+useded EBNF operators:
+{ }     iteration
+[ ]     option
+
+forms:
+  ({#', <body> <result>})
+  ({#'? { <test> <result> } [ <result> ] })
+  ({#'?! { <test> <result> } [ <result> ] })
+  ({#'&& { test } })
+  ({#'|| { test } })
+  ({#'while <test> <result> <body>})    loop while test evaluates non-zero.
+  ({#'do <body> <test> <result>})       loop till test evaluates zero.
+  ({#'= { <lvalue> <value> } })         assignment
+                                        other assignment operators work too.
+
+lisp similars:
+  #',           progn
+  #'?           cond
+  #'&&          and
+  #'||          or
+  #'while       do      /* but lisp has more syntactic candy here */
+  #'=           setq
+
+A parameter / local variable 'foo' is referenced as 'foo , a global
+variable as ({#'foo}) . In lvalue positions (assignment), you need not
+enclose global variable closures in arrays.
+
+Call by reference parameters are given with ({#'&, <lvalue>})
+
+Some special efuns:
+#'[             indexing
+#'[<            indexing from the end
+#'negate        unary -
+
+Unbound lambda closures
+=======================
+
+These closures are not bound to any object. They are created with the efun
+unbound_lambda() . They cannot contain references to global variables, and
+all lfun closures are inserted as is, since there is no native object for
+this closure.
+You can bind and rebind unbound lambda closures to an object with efun
+bind_lambda() You need to bind it before it can be called. Ordinary objects
+can obly bind to themselves, binding to other objects causes a privilege
+violation().
+The point is that previous_object for calls done from inside the closure
+will reflect the object doing bind_lambda(), and all object / uid based
+security will also refer to this object.
+
+
+The following is mostly vapourware.
+Well, another application would be that some things in the driver can be,
+sort of, microprogrammed.
+The master object could set some hooks in inaugurate_master(), like creating
+the code for move_object(), using a primitive low_move_object() or
+__move_object() or such. All calls of init(), exit(), etc. can thus be
+controlled on mudlib level.
+The driver would do an implicit bind_lambda() to the victim when the closure
+is used.
+
+e.g.
+({#'?, ({#'=, 'ob, ({#'first_inventory, 'destination}) }),
+    ({#'do,
+        ({#'call_other, 'ob, "init"}),
+    ({#'=, 'ob, ({#'next_inventory, 'ob}) }), 0 })
+})
+
+or
+
+({#'filter_objects, ({#'all_inventory, 'destination}), "init"})
+/* Won't show init failures due to move/destruct */
+
+is equivalent to
+
+if (ob = first_inventory(destination) ) {
+    do {
+        ob->init();
+    } while(ob = next_inventory(ob) );
+}
+
+and it's speed is mainly determined by the call_other. Thus, it shouldn't be
+noticably slower than the current C code in move_object().
+
diff --git a/doc/LPC/comments b/doc/LPC/comments
new file mode 100644
index 0000000..a3b0fd0
--- /dev/null
+++ b/doc/LPC/comments
@@ -0,0 +1,44 @@
+NAME
+        comments
+
+SYNTAX
+        /* block comment text */
+        // line comment text <end of line>
+
+
+DESCRIPTION
+        Comments are used to stored arbitrary text in the LPC program
+        source. It is a good idea if some if this text explains the
+        deeper intentions behind the actual LPC statements.
+
+        There are block comments and line comments.
+
+        Block comments start with a '/*' and end with a '*/'. They cannot
+        be nested, so
+
+          /* this /* is */ illegal */
+
+        will treat '/* this /* is */' as the comment.
+
+        Line comments start with '//' and continue until the unescaped(!)
+        end of the line (as in the new C standard).
+
+        It is not possible to next block and line comments within
+        each other. Meaning: '//' within /* ... */ has no special meaning,
+        neither does '/*' or '*/' have after a //.
+
+EXAMPLES
+        /* Simple block comment */
+
+        /* Block comments can
+           span several lines */
+
+        // Simple line comment
+
+        // Line comments can \
+           span several lines, too!
+
+        //#define LONG_MACRO The unique behaviour \
+           or line comments regarding the end of line \
+           can be used for example to comment out a \
+           large macro with just to keystrokes.
diff --git a/doc/LPC/do-while b/doc/LPC/do-while
new file mode 100644
index 0000000..8f69b2a
--- /dev/null
+++ b/doc/LPC/do-while
@@ -0,0 +1,15 @@
+NAME
+        do-while
+
+SYNTAX
+        do { statement } while(expr);
+
+DESCRIPTION
+        Execute 'statment' until 'expr' evaulates to 0.
+
+        A 'break' in the 'statement' will terminate the loop. A
+        'continue' will continue the execution from the beginning of
+        the loop.
+
+SEE ALSO
+        for(LPC), foreach(LPC), while(LPC), if(LPC), switch(LPC)
diff --git a/doc/LPC/ed0 b/doc/LPC/ed0
new file mode 100644
index 0000000..0edac7f
--- /dev/null
+++ b/doc/LPC/ed0
@@ -0,0 +1,39 @@
+NAME
+        ed0
+
+DESCRIPTION
+        When in 'ed', the prompt is ':'.
+
+        Ed has two modes, command mode and insert mode. The insert
+        mode has no prompt. You exit the insert mode by typing a
+        single '.' on a line.
+
+        All commands have the following syntax:
+
+        X,Ycmd
+
+        or
+
+        Xcmd
+
+        For example:
+
+        1,10p
+        Will print line 1 to 10.
+        1,5d
+        Will delete line 1 to 5.
+        8p
+        Will print line 8.
+        A '.' is the "current line". The current line is the last line
+        referenced. If you want to print last line + 10 more:
+        .,.+10p
+
+NOTE
+        These manpages seem a bit antique, though still correct. For a
+        better detailed help, invoke ed and use the ``h'' command.
+        Also you could look into the man page for ed(1) on you nearest
+        Unix box. And for a bit of fun you can try the good old
+        quiz(6), invoke as ``quiz function ed-command''.
+
+SEE ALSO
+        ed1(LPC), ed(E)
diff --git a/doc/LPC/ed1 b/doc/LPC/ed1
new file mode 100644
index 0000000..25f3ac2
--- /dev/null
+++ b/doc/LPC/ed1
@@ -0,0 +1,32 @@
+NAME
+        ed1
+
+DESCRIPTION
+        Commands that use a line range:
+        If no line is given, then curent line is printed.
+
+        p        Print line.
+        d        Delete line.
+        l        Print line with control characters.
+        r file        Read in a file after the line specified.
+        s        Substitute patterns. See special documentation.
+        z        Print 10 lines.
+        a        Start insert mode after specified line. Exit with
+                '.'<return>.
+        i        Start insert mode before specified line. Exit with
+                '.'<return>.
+
+        Commands used without line specification:
+
+        q        Quit. Won't work if file is changed.
+        Q        Quit and discard all changes if not saved.
+        w        Write the file out.
+        w file        Write the file out with name 'file'.
+        e file        Edit a file.
+        !cmd        Give a game command. For example "say Wait, I am busy".
+
+        As line numbers '.' is current line, and '$' is last line of
+        file. Thus '1,$p' will always print all of the file.
+
+SEE ALSO
+        ed2(LPC)
diff --git a/doc/LPC/ed2 b/doc/LPC/ed2
new file mode 100644
index 0000000..85d520e
--- /dev/null
+++ b/doc/LPC/ed2
@@ -0,0 +1,25 @@
+NAME
+        ed2
+
+DESCRIPTION
+        Substitutions are very advanced.
+
+        First a simple example:
+
+        s/apa/bepa/
+        This will substitue the 'apa' in current line to 'bepa'.
+        If an 'p' is appended, you will also immediately see the result.
+
+        1,$s/apa/bepa/
+        Same, but all lines in file. Only first occurence on every line.
+
+        Any character can used instead of '/':
+        s!apa!bepa!g
+        The 'g' specifies that all occurences of apa on this line are
+        changed to bepa.
+
+        The pattern that are supposed to be replaced, can be a regular
+        expression. See ed3 about that.
+
+SEE ALSO
+        ed3(LPC)
diff --git a/doc/LPC/ed3 b/doc/LPC/ed3
new file mode 100644
index 0000000..380c008
--- /dev/null
+++ b/doc/LPC/ed3
@@ -0,0 +1,30 @@
+NAME
+        ed3
+
+DESCRIPTION
+        Searching is done with:
+        /hello/
+        Find first line in of after current line.
+        Just // will repeat the search.
+
+        The patterns are regular expressions, where some characters
+        have a special meaning:
+        .        Match any character.
+        x*        Match any numbers of x (0 or more).
+        [abc]        Match 'a', 'b' or 'c'.
+        [0-9]        Match any digit 0 - 9.
+        [a-z]        Match any lowercase letter.
+        \x        Match 'x' where 'x' can be any character except '('
+                and ')'.
+
+EXAMPLE
+        s/ab.d/ABCD/
+        Substitute any string 'abXd' against 'ABCD' where X can be any
+        character.
+
+NOTE
+        This only half the truth, there is lots more magic in the
+        regexps.
+
+SEE ALSO
+        regexp(E), ed4(LPC)
diff --git a/doc/LPC/ed4 b/doc/LPC/ed4
new file mode 100644
index 0000000..2d5303c
--- /dev/null
+++ b/doc/LPC/ed4
@@ -0,0 +1,12 @@
+NAME
+        ed4
+
+DESCRIPTION
+        How to copy from a standard file.
+
+        Enter ed. Then do 'r /room/vill_green.c'. Now you have
+        something in the buffer. Change it into what you want it to
+        be. Then 'w /players/peter/hall.c'. Or 'w hall.c'.
+
+SEE ALSO
+        ed5(LPC)
diff --git a/doc/LPC/ed5 b/doc/LPC/ed5
new file mode 100644
index 0000000..9156ff3
--- /dev/null
+++ b/doc/LPC/ed5
@@ -0,0 +1,47 @@
+NAME
+        ed5
+
+DESCRIPTION
+        = : prints current line
+        a : append lines
+        c : change, that is, delate, than insert
+        d : delete line(s)
+        E <filename> :  discard current buffer and edit the file named
+                        <filename>
+        e <filename> : like e, but refuse if file has been changed
+        f : print current filename
+        f <filename> : set filename
+        i : insert line(s)
+        j : with no or one argument: join line with following line
+        j : with two arguments : join line range given
+        k<letter> : set mark <letter> to current line. <letter> must
+                be in the range [a-z] . The mark can be used
+                thereinafter as a line address, with a leading slash.
+                (e.g. ka to set mark a, /ap to print marked line)
+        l : print line with control characters
+        <start>,<end>m<dest> : move block (lines from start to end)
+                                behind line # dest
+        <line>m<dest>        : move single line
+        m<dest>                : move current line
+        M : remove Ctrl-M (CR) characters.
+        p : print line
+        P : print line
+        Q : quit, discarding the buffer
+        q : the same, but refuse if file has been changed since last
+            write
+        r : read in file. If no adress is given, at the last insert
+            position, if also nothing was inserted, at the end of the
+            buffer
+        s : substitute
+        <start>,<end>t<dest>        : copy block ( lines from start to end )
+                                  behind line position dest
+        <line>t<dest>                : copy single line
+        t<dest>                        : copy current line
+        w : write file
+        W : write file
+        x : write file if buffer has been changed since last change,
+            then quit
+        z : show approx. a screenful of lines
+
+SEE ALSO
+        ed6(LPC)
diff --git a/doc/LPC/ed6 b/doc/LPC/ed6
new file mode 100644
index 0000000..8b80a70
--- /dev/null
+++ b/doc/LPC/ed6
@@ -0,0 +1,32 @@
+NAME
+        ed6
+
+DESCRIPTION
+        This is the list of extended ed commands that Xio unearthed
+        somewhere, thanks!
+
+        a) never use 1,$p to print out an editfile, because you will
+          be thrown out 'cause of too much text transfereed to you.
+
+        b) $: jump to end of file.
+
+        c) ?anything? and ?? : search from bottom to up. (like '/'
+           from beginning to end of file. (also with substitutions,
+           try out..)
+
+        d) ( g/xxx/p search global xxx and print corresponding lines,
+           /xxx/s/new/old/p : search xxx, substitute new to old in this
+           line and print out. (try this concatenations with other
+           commands)
+
+        e) 1,nmx ( see ed5 ) , but also: 1,ntx : don't move the lines,
+           but make a copy of them.
+
+        f) x,y w name : save lines x to y to file name (if you don't
+           know the line numbers : '=' current line number)
+
+        g) s/$/text/p : append text to the end of current LINE and
+           print line
+
+        h) s/^/text/p : insert text at beginning og current LINE and
+           print line
diff --git a/doc/LPC/efuns b/doc/LPC/efuns
new file mode 100644
index 0000000..ca5b224
--- /dev/null
+++ b/doc/LPC/efuns
@@ -0,0 +1,16 @@
+CONCEPT
+        efuns
+
+DESCRIPTION
+        Efuns are "system calls" in the LPC driver, the C program
+        which compiles and executes the LPC programs of the mudlib.
+        These are hardcoded functions which perform basic tasks which
+        would be ineffective or impossible to be implemented in the
+        mudlib.
+
+        There are efuns for accessing the underlying filesystem, for
+        creating, moving and destructing objects, for writing
+        messages to users, for manipulation of LPC data types.
+
+SEE ALSO
+        efun(E), lfuns(LPC), applied(A), master(M)
diff --git a/doc/LPC/escape b/doc/LPC/escape
new file mode 100644
index 0000000..8518749
--- /dev/null
+++ b/doc/LPC/escape
@@ -0,0 +1,81 @@
+CONCEPT
+        character escape codes
+
+DESCRIPTION
+	Character escape codes are used to represent some common
+	special characters that would be awkward or impossible to
+	enter in the source program directly. The escape characters
+	come in two varieties: 'character escapes', which can be
+	used to represent some particular formatting and special
+	characters, and 'numeric escapes', which allow a character to
+	be specified by its numeric encoding.
+
+	Escapes begin always with a backslash '\'. If the following
+	characters could not be treated as a valid escape the backslash
+	is merely ignored.
+
+	The following character escapes are available in LPC (the code
+	may differ from platform to platform):
+
+	  \a    Code 007    Bell
+          \b    Code 008    Backspace
+          \e    Code 027    Escape
+	  \f    Code 012    Formfeed
+	  \n    Code 010    Newline
+	  \r    Code 013    Carriage-Return
+	  \t    Code 009    Tabulator
+	  \\    Code 092    Backslash itself
+	  \'    Code 039    Single quote
+	  \"    Code 034    Double quote
+
+	The single quote may appear without preceding backslash in character
+	constants, and the double quote may appear without a backslash in
+	string constants.
+
+	The numeric escapes could be used to express a character directly
+	by its code in binary, octal, decimal or hexadecimal notation.
+	
+	  \0b   Beginning of binary notation
+	  \0o   Beginning of octal notation
+	  \0x   Beginning of hexadecimal notation
+	  \x    Beginning of hexadecimal notation
+
+	A backslash followed by a digit ([0-9]) which does not map to one
+	of the above starts an escape in decimal notation.
+
+	A numeric escape terminates when N digits have been used up or
+	when the first character that is not a valid digit in that
+	notation is encountered. N is 2 for hexadeximals, 3 for
+	decimals and octals and 8 for binarys.
+
+	If the specified code is greater than 255 a warning is issued and
+	the value modulo 256 is used.
+
+EXAMPLES
+	Put a newline at the end of user output
+	  "You enter.\n"
+
+	Alert the user
+	  "Beeep.\a Wake up\n"
+
+	Put a double quote in a string
+	  "You say \"hello\"\n"
+
+	Write the line from above
+	  "\"You say \\\"hello\\\"\\n\""
+
+	Put a single quote in a string
+	  "You say 'hello'\n"
+
+	Some forms to write "abcde"
+	  "abcde"
+	  "ab\99de"              (with c's code being 99)
+	  "ab\099de"
+	  "ab\x63de"             (99 = 0x63)
+	  "ab\0x63de"
+
+	The following string consists of two characters
+	  "\0111"                (\011 and 1)
+
+	The following string consists of three characters
+	  "\0o090"               (\000 and 9 and 0)
diff --git a/doc/LPC/for b/doc/LPC/for
new file mode 100644
index 0000000..e7a988d
--- /dev/null
+++ b/doc/LPC/for
@@ -0,0 +1,36 @@
+NAME
+        for
+
+SYNTAX
+        for(init; expr2; expr3) statement;
+
+DESCRIPTION
+        Execute <init> once. Then, while <expr2> returns a non-zero
+        value, execute <statement>. Every time <statement> has been
+        executed, or a 'continue' statement has been executed, execute
+        <expr3> before next loop.
+
+        <init> is usually a series of one or more expressions (remember
+        that assignments are expressions, too), separated by commas.
+        Additionally it is also allowed to define new local variables
+        here and assign them an initial value. The scope of such variables
+        is the whole for statement.
+
+        Examples for legal <init> expressions are:
+
+           for (i = 0; ...
+           for (i = 0, j = 0; ...
+           for (i = 0, int j = i; ...
+           for (int j = 4; ...
+
+        Illegal <init> expressions are:
+
+           for (int i; ...      : no value assigned
+           for (int i += 4; ... : only plain assignments allowed
+
+        A 'break' in the 'statement' will terminate the loop. A
+        'continue' will continue the execution from the beginning of
+        the loop.
+
+SEE ALSO
+    foreach(LPC), if(LPC), do-while(LPC), while(LPC), switch(LPC)
diff --git a/doc/LPC/foreach b/doc/LPC/foreach
new file mode 100644
index 0000000..7e6060b
--- /dev/null
+++ b/doc/LPC/foreach
@@ -0,0 +1,132 @@
+NAME
+        foreach
+
+SYNTAX
+        foreach (<var> : <expr>) <statement>;
+        foreach (<var>, <var2>, ... ,<varN> : <expr>) <statement>;
+
+        foreach (<var> : <expr1> .. <expr2>) <statement>;
+        foreach (<var>, <var2>, ... ,<varN> : <expr1>..<expr2> ) <statement>;
+
+        /* MudOS compatibility only - not for new code: */
+        foreach (<var> in <expr>) <statement>;
+        foreach (<var>, <var2>, ... ,<varN> in <expr>) <statement>;
+
+DESCRIPTION
+        The instruction evaluates its range specification - either a
+        simple <expr> which can yield an array, a struct, a string, a
+        mapping or an integer, or an integer range <expr1> through
+        <expr2> - and executes <statement> once for each value in the
+        range. The respective value is assigned to <var> right before
+        <statement> is executed.
+
+        A 'break' in the <statement> will terminate the loop. A
+        'continue' will continue the execution from the beginning of
+        the loop.
+
+        Every <var> specification can declare a new local variable, whose
+        scope is the whole foreach() statement.
+
+
+        The normal form (one <expr>):
+
+            <expr> is evaluated and has to yield an array, a struct, a
+            string or a mapping (or reference to the former), or an
+            integer.
+
+            If <expr> is a array, struct, or string, the values of
+            <expr> (in case of the string, the integer values of the
+            characters) are then assigned one by one in order of
+            occurence to <var>, and <statement> is executed for every
+            assignment.
+
+            If <expr> is a mapping, the keys are assigned one by one
+            to <var>, and the values for each key are assigned in
+            order to <var2>..<varN>.  If there are more values than
+            variable, the extraneous values are ignored. Due to the
+            nature of mappings, a specific order of the keys can not
+            be guaranteed.
+
+            If <expr> evaluates to a reference to an array, mapping, or
+            string, the loop will assign references to the values into
+            the variables. This allows the loop body to change the contents
+            of the original data.
+
+            If <expr> evalutes to an integer, the loop will count up <var>
+            from 0 to <expr>-1, basically implementing a count loop.
+
+            If there are more variables than necessary, the unneeded ones
+            are not changed.
+
+
+        The ranged form (<expr1> .. <expr2>):
+
+            <expr1> and <expr2> are evaluated and must yield integers.
+            The loop will count up <var> from <expr1> to <expr2>, basically
+            implementing a counted loop.
+
+            If <expr1> is less than <expr2>, the loop will terminate at once.
+
+            If there are more than variable, the unneeded ones are not
+            changed.
+
+
+
+        WHAT HAPPENS IF <expr> IS CHANGED IN THE LOOP?
+
+        If <expr> yields an array or struct:
+         - assignments to single elements or to array ranges effect
+           the values assigned to the variable:
+             a = ({1, 2, 3})
+             foreach(x : a) { a[1..2] = ({4, 5}); write(x+" "); }
+           will write ("1 4 5 ").
+         - operations which implicitely copy the array or struct (this
+           includes range assignments which change the size) don't
+           have an effect on the loop.
+
+        If <expr> yields a mapping, the loop will run over the indices
+        the mapping had at the begin of the loop. Deleted indices are silently
+        skipped, new indices ignored, but changes of the data of existing
+        indices are acknowledged.
+
+        If <expr> yields a string, the value used at the start of the loop
+        remains.
+
+
+WARNING
+        The additional syntax forms using "in" as keyword are meant
+        to make re-engineering of MudOS objects easier. Do not use them
+        for newly written code, as they may not be available in future.
+
+
+EXAMPLES
+        // Call quit() in all interactive users
+        foreach(o : users()) o->quit();
+        foreach(object o : users()) o->quit();
+
+        // Print the contents of a mapping <m>
+        foreach(key, value : m) printf("%O:%O\n", key, value);
+        foreach(mixed key, mixed value : m) printf("%O:%O\n", key, value);
+
+        // Don't change the content of a string: s remains "FOOBAR".
+        s = "FOOBAR";
+        foreach(i : s) i += 32;
+
+        // Do change the content of a string: s will become "foobar".
+        s = "FOOBAR";
+        foreach(i : &s) i += 32;
+
+        // Count from 0 to 5
+        foreach(i : 6) printf("%d\n", i);
+
+        // Count from 1 to 6
+        foreach(i : 1 .. 6) printf("%d\n", i);
+
+HISTORY
+        LDMud 3.3.44 introduced the use of references, the loop over
+          an integer expression, and the loop over an integer range.
+        LDMud 3.3.266 added support for structs.
+
+
+SEE ALSO
+        for(LPC)
diff --git a/doc/LPC/functions b/doc/LPC/functions
new file mode 100644
index 0000000..50c39a0
--- /dev/null
+++ b/doc/LPC/functions
@@ -0,0 +1,174 @@
+CONCEPT
+        functions
+
+DESCRIPTION
+        Functions are named blocks of code which are be called with
+        a number of argument values, and which return a result value
+        to the caller.
+
+        Functions are defined in an object and are also known as
+        "local funs" or short "lfuns".
+
+
+        DEFINING A FUNCTION
+
+        A function definition takes the form
+
+          <modifiers> <type> name ( <arguments> ) {
+             statements...
+          }
+
+        The parts in detail:
+          - <modifiers> can be any one of "static", "private", "public"
+              and "protected" (see modifiers(LPC)), optionally combined
+              with "varargs" (see varargs(LPC)) and/or "nomask".
+              If not specified, the function behaves as if it was
+              specified as "public", but this visibility can be restricted
+              in derived object through non-public inheritance.
+          - <type> is the type of the result returned by the function.
+              If specified as "void", the function is compiled to return
+              the value 0 under all circumstances. If not specified, the
+              type is assumed to be "mixed", furthermore typechecking is
+              disabled for this function.
+          - name is the name of the function, e.g. "short", or "Nice_Try",
+              under which it is made known.
+          - <arguments> is a list of variable definitions in the
+              normal '<type> <name>' style, separated by comma.
+              Examples: () : no argument taken
+                        (int a) : takes on integer argument
+                        (mixed a, object *b): takes two arguments, one
+                           arbitrary type, one array of objects.
+          - { statements... } defines the code for this function. This
+              is a normal block (see block(LPC)) and as such can define
+              its own local variables.
+
+
+        DECLARING A FUNCTION
+
+        A function declaration makes the name and type of a function known
+        to the compiler with the assertion that the code for this function
+        will be provided "elsewhere".
+
+        The form is:
+
+          <modifiers> <type> name ( <arguments> );
+
+        Typical uses are:
+          - to declare in advance functions which are called before they
+            can be defined; for example if the create() function of an object
+            calls other functions which are defined after the create().
+          - to declare functions which will be provided by an inheriting
+            object.
+
+        Calling a declared but undefined function results in a runtime error.
+
+
+        CALLING A FUNCTION
+
+        Functions in other objects are called with the call_other() efun,
+        which can be shortened to '->':
+
+           ob->fun(a, b, c)
+           call_other(ob, "fun", a, b, c)
+
+        Note: See the entry H_DEFAULT_METHOD in hooks(C) for a modification
+        of this behaviour.
+
+        Functions in the same object are called just by writing their name,
+        followed by the arguments in parenthesis:
+
+           short()
+           compute(a)
+           do_that(a, "foo")
+
+        Array function arguments can be 'flattened' with the '...' operator.
+        For example:
+
+           mixed * m = ({ "foo", "bar" });
+           fun(m..., 1);
+
+        will be executed as:
+
+           fun("foo", "bar", 1);
+
+
+        If the number of values passed to the function does not match the
+        number of expected arguments (and if type checking is not enabled), the
+        driver will perform the necessary adaption at call time: excess
+        values are ignored, missing values are substituted by the number 0.
+        The values passed to the called function are massaged by the driver
+        to match the argument list
+
+
+        FUNCTIONS AND INHERITANCE
+
+        A "public" or "protected" (== "static") function defined in one
+        object is also visible in all inheriting objects. The exception from
+        this rule is when an inheriting child redefines ("overloads") the
+        inherited function with its own. When compiling with type checking,
+        the argument list of the redefined function has to match the
+        original one.
+
+        When a function is called, the driver looks for the function first
+        in the object called, and if not found there, then in the inherited
+        objects.
+
+        To explicitely call an inherited function (useful when a redefining
+        functions wants to use the original one), the "::" operator is used:
+
+            ::create()
+            ::compute(a)
+
+        The named function is searched only in the inherited objects, and
+        the first found is used.
+
+
+        If the function is inherited from several objects and a specific
+        one is to be called, the "::" can be extended to contain the
+        partial or full name of the inherited object:
+
+            inherit "/obj/cooker";
+            inherit "/obj/container";
+
+            tainer::create()
+            container::create()
+            "tainer"::create()
+            "container"::create()
+            "obj/container"::create()
+            "/obj/container"::create()
+
+        all call the create() in the container inherit. Note that the
+        name given to the :: operator is matched against the ends of
+        the inherited names.
+
+
+        One special form of this call is
+
+            efun::find_object()
+
+        which bypasses any redefinition of an efun (here find_object())
+        and directly calls the efun itself. This is only possible for
+        efun-redefinitions which do not use the "nomask" modifier.
+
+
+        Additionally, a call to a function inherited from several objects
+        can be instructed to call _all_ inherited functions through the
+        use of the wildcards "*" (match any number of arbitrary characters)
+        and "?" (match one arbitrary character):
+
+            inherit "/obj/cooker";
+            inherit "/obj/container";
+
+            "*"::create()
+            "co*"::create()
+            "*er"::create()
+
+        all call both inherited create()s. The function called this way
+        must not take arguments, and the single results from all calls are
+        combined into one array used as final result. If there is no such
+        function inherited at all, the statement will just return
+        an empty array.
+
+SEE ALSO
+        types(LPC), modifiers(LPC), varargs(LPC), references(LPC),
+        call_other(E), simul_efun(C), call_out(E)
diff --git a/doc/LPC/if b/doc/LPC/if
new file mode 100644
index 0000000..33bbff2
--- /dev/null
+++ b/doc/LPC/if
@@ -0,0 +1,39 @@
+NAME
+        if
+
+SYNTAX
+        if (expr1) statement1;
+        else if (expr2) statement2;
+        ...
+        else if (exprN) statementN;
+        else statementX;
+
+DESCRIPTION
+        The if() statement implements the conditional execution of statements.
+        The expressions 'expr1' .. 'exprN' are evaluate in the order they
+        appear until one of the expressions returns non-0 ('true'). At that
+        point, the statement associated with the expression is executed, and
+        the program continues after the if() statement. If none of the
+        expressions evaluate to 'true', the statementX in the 'else'-branch
+        is executed.
+
+        Both the 'else if' branches and the 'else' branch are optional, and
+        there can be any number of 'else if' branches - but there must be one
+        'if' branch, and the branches must be in the order given above.
+
+        Any 'else' or 'else if' always relates to the immediately preceeding
+        'if' resp. 'else if' conditional. This means that
+
+          if (a)
+          if (b) do_b;
+          else do_c;
+
+        is interpreted as
+
+          if (a) {
+            if (b) do_b;
+            else   do_c;
+          }
+
+SEE ALSO
+        for(LPC), foreach(LPC), do-while(LPC), while(LPC), switch(LPC)
diff --git a/doc/LPC/inherit b/doc/LPC/inherit
new file mode 100644
index 0000000..0e4c0f2
--- /dev/null
+++ b/doc/LPC/inherit
@@ -0,0 +1,9 @@
+NAME
+        inherit
+
+DESCRIPTION
+        The concept of inheritance and the inherit statement are
+        explained in detail in the man page for ``inheritance''.
+
+SEE ALSO
+        inheritance(C)
diff --git a/doc/LPC/inheritance b/doc/LPC/inheritance
new file mode 100644
index 0000000..23fb804
--- /dev/null
+++ b/doc/LPC/inheritance
@@ -0,0 +1,181 @@
+KONZEPT
+     inheritance
+
+BESCHREIBUNG
+     Mittels Vererbung kann man das Verhalten und/oder die implementierten
+     Methoden eines Objektes in ein neues Objekt hineinerben.
+
+     1. Wozu ist Vererbung gut
+     1.1. Erben von Implementationen: Strukturieren von Bibliotheken
+     Mit Vererbung der Implementation koennen aufeinander aufbauende und gut
+     wart-/nutzbare Strukturen geschaffen werden:
+     
+     /std/thing/description beinhaltet
+     - wie ein Objekt aussieht/welche Details es gibt
+     - wie man das Objekt finden/identifizieren kann
+     /std/thing/moving beinhaltet
+     - wie man ein Objekt bewegen kann
+     /std/thing erbt
+     - /std/thing/description und
+     - /std/thing/moving
+     - damit den Code aus beiden Objekten (und noch andere)
+
+     Sowohl thing/description als auch thing/moving sind nicht als
+     eigenstaendige Objekte sinnvoll nutzbar, sind abstrakt.
+
+     1.2. Erben von Schnittstellen und Verhalten      
+     Durch das Erben von /std/thing werden Schnittstelle und auch
+     Verhalten von /std/thing geerbt:
+     
+     -- keks.c --
+     inherit "/std/thing";
+     --
+     
+     Dadurch koennen jetzt andere Objekte, wie NPCs oder Spieler mit dem
+     Keks-Objekt so interagieren, als wenn es ein /std/thing waere.
+
+     Morgengrauen stellt eine grosse Bibliothek von miteinander sinnvoll
+     agierenden Objekten unter /std zur Verfuegung, Die dort verfuegbaren
+     Objekte sind groesstenteils selbsterklaerend, wie /std/npc,
+     /std/armour oder /std/weapon.
+
+     Das Keks-Objekt muss erweitert werden, wenn es sich vom normalen
+     Ding unterscheiden soll. Typischerweise geschieht das durch
+     Ueberschreiben der Initialisierungmethode namens "create". 
+       
+     2. Ueberschreiben/Erweitern von Verhalten/Methoden
+     2.1. Ueberschreiben
+     Um das Verhalten von geerbten Methoden zu erweitern, muss diese
+     ueberschrieben werden:
+     
+     -- keks.c --
+     ...
+     void create() {
+       SetProp(P_NAME, "Keks");
+       SetProp(P_GENDER, MALE);
+       AddId(({"keks"}));
+     }
+     --
+     
+     Allerdings wuerde jetzt der normale Code von "create" in /std/thing
+     nicht mehr ausgefuehrt werden. Mit dem 'scope'-Operator :: wird
+     innerhalb einer ueberschriebenen Methode auf deren bisherige
+     Implementation zugegriffen:
+
+     -- keks.c --
+     ...
+     void create() {
+       ::create();
+       SetProp(P_NAME, "Keks");
+       SetProp(P_GENDER, MALE);
+       AddId(({"keks"}));
+     }
+     --
+
+     Auf geerbte globale Variablen kann normal zugegriffen werden, wenn 
+     diese nicht vor direktem Zugriff durch erbende Objekte geschuetzt
+     wurden. Also in ihrer Sichtbarkeit veraendert wurde.
+     
+     Ueberschreiben von Methoden in den davon erbenden Objekten kann durch
+     das Schluesselwort 'nomask' verboten werden.
+
+     2.2. Sichtbarkeit von Methoden und Variablen
+     Es ist moeglich, Methoden und Variablen mit einem Modifikator fuer
+     ihre Sichtbarkeit zu versehen, der auch bei der Vererbung zum
+     Tragen kommt:
+     - 'public' Methoden sind von aussen/innen in Eltern/Kind zugreifbar
+     - 'protected' Methoden sind nur von innen in Eltern/Kind zugreifbar
+     - 'private' Methoden sind nur von innen in Eltern zugreifbar
+                 (also nur im definierenden Objekt selbst)   
+
+     2.3 Laufzeit-Polymorphie (vielgestaltes Verhalten)
+     Methoden werden in LPC immer erst zum Zeitpunkt ihres Aufrufs
+     gebunden, also nicht schon beim Laden. Beispielsweise koennen
+     wir unseren Keks essbar machen:
+
+     -- keks.c --
+     ...
+     void create() {
+       ...
+       AddCmd("iss&@ID", "action_essen", "Was willst du essen?");
+     }
+     
+     int action_essen() {
+       if(this_player()->eat_food(1, 0, 
+                                 "Du bekommst "+QueryPronoun(WEN)+
+				 " nicht mehr hineingestopft.\n")>0) {
+         write("Du isst "+name(WEN,1)+".\n");
+         say(this_player()->Name(WER)+" isst "+name(WEN)+".\n");
+         remove();
+       }
+       return 1;
+     }
+     --
+     
+     und jetzt in einem davon erbenden Kruemelkeks diesen beim Entfernen
+     im "remove" kruemeln lassen:
+     
+     -- kruemelkeks.c --
+     inherit "/doc/beispiele/inherit/keks.c";
+     ...
+     varargs int remove(int silent) {
+       if(!silent && living(environment()))
+         tell_object(environment(), Name(WER,1)+
+	                            " kruemelt ein letztes Mal.\n");
+       return ::remove(silent);
+     }
+     --
+     
+     Trotzdem wir "action_essen" nicht modifiziert haben, wird von dieser
+     Methode in einem Kruemelkeks immer automatisch die aktuelle und
+     kruemelende "remove" aufgerufen.
+
+     3. Multiple Inheritance
+     In LPC ist multiple Vererbung moeglich. Das heisst, man kann von 
+     mehreren Objekten erben. Das kann zu Konflikten fuehren, zum Beispiel 
+     wenn eine Methode in zwei Objekten von denen geerbt wurde vorkommt. 
+     
+     Diese Konflikte sollte man dann "per Hand" loesen in dem man diese 
+     spezielle Methode ueberschreibt und mittels des scope-Operators die 
+     gewuenschte(n) geerbt(en) Methode(n) aufruft:
+
+     inherit "/std/weapon";
+     inherit "/std/lightsource";
+
+     void create() {
+       weapon::create();
+       lightsource::create();
+       ...
+     }
+
+     void init() {
+       weapon::init();
+       lightsource::init();
+       // oder sehr generell und unkontrolliert:
+       // "*"::init();
+     }
+
+     Schwerwiegende Konflikte koennen auftreten, wenn eine gleichnamige
+     Variable aus verschiedenen Objekten geerbt wird. Die Variablen
+     existieren im letztlich erbenden Objekt zweimal und die verschiedenen
+     geerbten Methoden greifen auf ihre jeweilige Variante zu.
+
+     Beispiel ist die sog. "Masche" oder der "Diamond of Death": 
+
+                        A    (Ursprungsobjekt mit globaler Variable x)   
+                       / \
+                      B   C  (B, C erben von A und manipulieren beide x)
+                       \ /
+                        D    (D erbt von B und A)
+
+     Mit dem Schluesselwort 'virtual' kann die Doppelung beim Erben
+     in B und C unterbunden werden.
+
+SIEHE AUCH:
+     inherit
+     private, protected, public, nomask
+     virtual
+     objekte, oop
+     /doc/beispiele/inherit
+
+2.Feb 2008 Gloinson
diff --git a/doc/LPC/initialisation b/doc/LPC/initialisation
new file mode 100644
index 0000000..61f3c2b
--- /dev/null
+++ b/doc/LPC/initialisation
@@ -0,0 +1,93 @@
+CONCEPT
+
+        VARIABLE INITIALIZATION
+
+DESCRIPTION
+        Global variables, like their local counterparts, can be defined
+        with an initial value:
+
+            int * a = ({ 3, 4 });
+
+        The initialization value can be any legal LPC expression,
+        including function calls. The code for the initializations is
+        collected in a compiler-generated function __INIT() which is
+        called even before the create-hook is applied on the object.
+
+        During initialization, blueprints and clones are treated
+        slightly differently:
+
+        Blueprint variables are always all initialized using __INIT().
+
+        For clones the programmer can select whether the clone's
+        variables should also be initialized with __INIT(), or if they
+        should be assigned from the current blueprint values
+        ('shared with the blueprint'). The latter method is useful for
+        example if blueprints and clones shall share arrays or
+        mappings.
+
+        The selection is performed with the two pragmas
+        'init_variables' and 'share_variables'. The status of this
+        pragma at the point of the first variable definition counts,
+        and is applied to all variables in the program.
+
+        The clone initialization method is evaluated per-program, i.e.
+        if an inherited program defines 'share_variables' and the child
+        program doesn't, only the inherited variables are initialized
+        from the blueprint, and all others from __INIT().
+
+        The default setting for the pragma is configured into the
+        driver, but can also be chosen when starting the driver.
+        
+EXAMPLE
+        For the object
+
+          ----------
+          inherit "a";
+          int a = 4;
+          int b;
+          ----------
+
+        the compiler executes the equivalent of these __INIT() functions:
+
+        #pragma share_variables:
+
+            unknown __INIT()
+            {
+                "a"::__INIT();
+                if (clonep(this_object()))
+                {
+                    a = (blueprint of this_object())->a;
+                }
+                else
+                {
+                    a = 4;
+                }
+                return 1;
+            }
+
+
+        #pragma init_variables:
+
+            unknown __INIT()
+            {
+                "a"::__INIT();
+                a = 4;
+                return 1;
+            }
+
+
+        In either case the variable 'b' (in fact all variables) are
+        set to '0' as part of the loading/cloning process before the
+        driver performs the specific initialisation.
+
+WARNING
+        Do not call __INIT() yourself, overload, or use it directly in
+        any other way. The implementation of the variable
+        initialization may change at any time.
+
+HISTORY
+        Before LDMud 3.3.378, the choice between sharing and initializing
+          variables was a fixed configuration choice of the driver.
+
+SEE ALSO
+        pragma(LPC), create(H), invocation(D)
diff --git a/doc/LPC/inline-closures b/doc/LPC/inline-closures
new file mode 100644
index 0000000..3a2ecdd
--- /dev/null
+++ b/doc/LPC/inline-closures
@@ -0,0 +1,131 @@
+CONCEPT
+        inline closures
+
+SYNTAX
+        function <returntype> ( <arguments> ) : <context> { <code> }
+
+        (: <statements> ; <expr>, ... , <expr> :)
+
+
+DESCRIPTION
+        Inline closures are a way to program closures which are
+        compiled at the time an object is loaded, but can access
+        values from their enclosing function at runtime.
+
+        Example:
+
+          closure factory (int arg) {
+            return function int (int val) { return val * arg; };
+          }
+
+          closure f1 = factory(2);
+          closure f2 = factory(3);
+          funcall(f1, 3) -> will yield 6.
+          funcall(f2, 3) -> will yield 9.
+
+        The closure here 'inherits' the current value of the local
+        variable 'arg' at the time the closure is created. These
+        values are called the "context" of the closures - they are
+        stored in a special set of variables in the closure.
+
+        One specific feature of the closure context is that it can be
+        changed from within the closure, and that these changes remain
+        permanent:
+
+          closure factory (int arg) {
+            return function int (int val) { return val * arg++; };
+          }
+
+          closure f = factory(2);
+          funcall(f, 3) -> will yield 6.
+          funcall(f, 3) -> will now yield 9!
+
+        But changes of the closure context will not reflect on the
+        local variable it was copied from and vice versa.
+
+        In addition to the implicite context inherited from the
+        defining function, additional context variables can be defined
+        in the closure:
+
+          closure factory (int arg) {
+            return function int (int val) : int x = 2 * arg
+                                          { return val * x; };
+          }
+
+          closure f = factory(2);
+          funcall(f, 3) -> will yield 12.
+
+        It is possible to define multiple context variables with and
+        without initialisation:
+
+          closure factory (int arg) {
+            return function int (int val) : int y, x = 2 * arg;
+                                            int z
+                                          { return val * x; };
+          }
+
+        These explicite context variables are useful when the closures
+        needs to keep a state, or to improve performance:
+
+          mapping m = ...;
+          closure slow (int arg) {
+            return function mixed () { return m[arg]; }
+          }
+          closure fast (int arg) {
+            return function mixed () : mixed val = m[arg] { return val; }
+          }
+
+        In the above example, the fast() function executes the lookup
+        m[arg] only once when the inline closure is created; the
+        slow() function on the other hand returns a closures which
+        looks up m[arg] every time it is called. A second effect is
+        that the results of the slow closure change when m changes;
+        the result of the fast closure is always the same.
+
+
+        In the definition of an inline closure, some elements are
+        optional:
+
+          <returntype>     defaults to 'mixed'
+          ( <arguments> )  defaults to '(mixed $1 ...  mixed $9)'
+          : <context>      no default
+
+
+        The special (: :) form is meant for simple expressions (and
+        MudOS compatibility). The form
+
+          (: <statements> ; <expr>, ..., <expr> :)
+
+        is the shorthand notation for
+
+          function { <statements>; return <expr>, ..., <expr>; }
+
+        For example the two statements
+
+          sort_array(arr, function { return $1 < $2; } )
+          sort_array(arr, (: $1 < $2 :) )
+
+        do the same. The example also demonstrates that both the <statements>
+        and the <expr> part in this form are optional.
+
+
+
+NOTES
+        The macro __LPC_INLINE_CLOSURES__ is defined when the
+        inline closures as described here are available. If not
+        defined, the driver implements a more restricted version
+        ('(: :)' syntax only, no context variables) for backwards
+        compatibility.
+
+        Inline closures are not to be confused with inline functions
+        known from other languages.
+
+HISTORY
+        LDMud 3.2.7 implemented the older, restricted form of inline
+        closures.
+        LDMud 3.3.271 implemented the full form of inline closures.
+        LDMud 3.3.275 re-allowed statements in the (: :) form.
+
+SEE ALSO
+        closures-abstract(LPC), closures-example(LPC), closure_guide(LPC)
+        closures(LPC)
diff --git a/doc/LPC/integers b/doc/LPC/integers
new file mode 100644
index 0000000..edbd848
--- /dev/null
+++ b/doc/LPC/integers
@@ -0,0 +1,40 @@
+NAME
+        integers
+
+DESCRIPTION
+        int is the fastest data type in LPC.
+
+        An integer contains a whole number between
+        -2147483648 and 2147483647.
+
+        Operations with integers:
+          +  plus               &   AND    << SHIFT right
+          -  minus              |   OR     >> SHIFT left
+          *  multiply           ^   XOR
+          /  divide (whole)     ~   NOT    =  Assign value
+          %  divide (modulo)    +=  add    -= subtract        
+
+        The result of a boolean expression is also an integer:
+          0 (false)
+          1 (true)
+
+        Boolean operators are:
+          !  (not)
+          == (equal)
+          || (or)
+          && (and)
+
+FUNCTIONS
+        int to_int(string)
+        int to_int(float)
+        int sscanf(string str, string fmt, mixed var1, mixed var2, ...)
+        void printf(string format, ...)
+
+REMARKS
+        Single characters in strings are also integers.
+
+SEE ALSO
+        arrays, mappings, operators, strings, types
+
+LAST CHANGED
+        Wednesday, 7th May, 2003, by Amaryllis
diff --git a/doc/LPC/lfuns b/doc/LPC/lfuns
new file mode 100644
index 0000000..a9c559d
--- /dev/null
+++ b/doc/LPC/lfuns
@@ -0,0 +1,31 @@
+CONCEPT
+        lfuns
+
+DESCRIPTION
+        A lfun is a LPC function within an object which is public and can
+        be called by other objects. In OO terms, lfuns are "methods"
+        which you can send "messages" to.
+
+        Calling lfuns is done by using the efun call_other(), which
+        takes as arguments the object in which the lfun is to be called,
+        the name of the lfun to be called in the object, and additional
+        and optional arguments.
+
+        An example looks like this:
+
+        call_other(drink, "QueryShort");
+
+        This call may also be written as
+
+        drink->QueryShort();
+
+        This means call_other(object, "function", args...) can also be
+        written as object->function(args...). The second form is
+        preferred as it is easier to read.
+
+        Some lfuns have a special meaning for the LPC driver, because
+        they are applied by the interpreter instead from an LPC object.
+        To distinguish those, they are called ``applied lfuns''.
+
+SEE ALSO
+        efuns(LPC), efun(E), applied(A), master(M), call_other(E)
diff --git a/doc/LPC/lpc b/doc/LPC/lpc
new file mode 100644
index 0000000..c03df0f
--- /dev/null
+++ b/doc/LPC/lpc
@@ -0,0 +1,9 @@
+NAME
+        lpc
+
+DESCRIPTION
+        This directory contains man pages about various aspects of the
+        LPC language as it is provided by Amylaars parser/driver.
+
+SEE ALSO
+        concepts(C), driver(D), efun(E), applied(A), master(M)
diff --git a/doc/LPC/mappings b/doc/LPC/mappings
new file mode 100644
index 0000000..381e3c8
--- /dev/null
+++ b/doc/LPC/mappings
@@ -0,0 +1,474 @@
+CONCEPT
+        mappings
+
+LAST UPDATE
+        Mon, 15 Mar 1999
+
+DESCRIPTION
+
+  A step-by-step introduction to mappings:
+  ----------------------------------------
+
+  1. What is a mapping?
+
+    A mapping is a datatype which allows to store data associated to a key.
+  In other languages  they are also  known  as 'dictionaries' or  'alists'.
+  There are also alists in LPC but they are not a separate datatype but are
+  implemented on  top of arrays.  Alists are  the predecessors of mappings.
+  The keys and the values  can be of  any type.  But most common  datatypes
+  for keys are strings, integers and objects.  Others like arrays, mappings
+  or closures aren't a good choice because comparision between i.e.  arrays
+  often returns false  even if they equal  in content.  This is because the
+  driver compares i.e. two arrays by their internal pointers and not by
+  their content. The reason for this is simple: speed.
+
+    Mappings  are allways  treated  as references    when passing  them  to
+  functions. This means when you pass a mapping  to another object and this
+  object modifies the mapping the modification will  take place in a global
+  scope - visible to all objects holding this mapping in a variable.
+
+
+  2. What are mappings good for?
+
+    The term 'dictionary'  probably describes the  use  of a mapping  best.
+  Opposed  to arrays mappings don't have  a specific  order. They provide a
+  mechanism to   create  a set  of associations  between  values.  Such  an
+  association consists of a unique  key and data  that is identified by the
+  key. Think of  a dictionary  where you have  a  word and a definition  of
+  it. You use the word to lookup its definition.
+
+    Mappings can be used i.e.  to hold  aliases for commands. The key would
+  then be the  name of  the alias and  the  data the command(s) behind   an
+  alias.  Or they can be used for  the exits of a  room.  The keys would be
+  the directions where one can go  to and the associated  data would be the
+  file names of the  rooms.  But mappings can  also be used  as a kind of a
+  sparse array.   A  sparse array is  an  array where most of  the elements
+  aren't used  (occupied by 0).  I.e.  if  you want to  store values at the
+  position 0, 13  and 37642 of an  array you would  have to create an array
+  with a size of at least 37643.  This  costs a lot  of memory so a mapping
+  would be  more useful because you would  then use the  numbers 0,  13 and
+  37642 as a key and not as an index to a position  (actually the keys of a
+  mapping are sometimes  called indices  but this  is just  because the way
+  data is accessed in a mapping is similar to  arrays: by the [] operator).
+  This also allows to  query all occupied   positions of a sparse array  by
+  querying for all  the keys of  the mapping opposed  to an array where you
+  have to iterate over all elements.
+
+
+  3. How do I create a mapping?
+
+    There are several ways to do so. The most convenient is the following:
+
+      mapping map;
+      map = ([ key0: value00; ...; value0n,
+               ... : ...    ; ...; ...    ,
+               keyn: valuen0; ...; valuenn ]);
+
+    As you can see, a key may  have more than  one value assigned.  But the
+  amount of values per key must always be equal.  It  is  even  possible to
+  have mappings without any values!
+    Another  method is  to use the   efun mkmapping().  This  efun gets two
+  arguments with the first beeing an array of keys and the following beeing
+  arrays of values:
+
+      mapping map;
+      map = mkmapping (({ key0   , ..., keyn    }),
+                       ({ value00, ..., value0n }),
+                       ({ ...    , ..., ...     }),
+                       ({ valuen0, ..., valuenn }));
+
+    If the efun only gets one argument, then this argument will be taken as
+  an array of keys and a mapping  without values will  be returned.
+
+    An empty mapping can be created by using the above described methods by
+  simply ommitting the keys and values:
+
+      mapping map;
+      map = ([]);
+  or:
+      map = mkmapping(({}), ({}));
+
+    Or  by  using the efun   m_allocate().  This efun gets  as  first
+  argument the  amount  of keys which will  be  added soon and  an optional
+  second argument specifying the width of the mapping:
+
+      map = m_allocate(n, width);
+
+    The value <n>  may be a bit  confusing  since mappings shrink and  grow
+  dynamically. This value just tells the driver how 'long' this  mapping is
+  going to be  so proper memory  allocations  will be  performed to  reduce
+  the overhead of memory reallocation.  I.e.  if you want to read in a file
+  and store the  read data in  a mapping  you probably  know  the amount of
+  keys.  So you allocate  a mapping with this  efun and tell the driver how
+  much memory should  be allocated  by specifing  a proper <n>  value.
+  Thus causing  a    speedup when adding  the  read   data to the   mapping
+  afterwards.    The <width> just specifies how   many  values per key this
+  mapping is   going to have. If  no  width is given, 1  will  be  taken as
+  default.
+
+  An empty mapping created with '([])' will always have a width of 1. To
+  create empty mappings with other widths, write it as
+
+      map = ([:width ]);
+
+  <width> can be any expression returning an integer value (including
+  function calls), and in fact this notation is just a fancy way of
+  writing
+
+      map = m_allocate(0, width);
+
+
+
+  4. How can I modify the data of a mapping?
+
+    Adding a  new key is similiar to   modifying the associated  data of an
+  existing key:
+
+      map += ([ key: value0; ...; valuen ]);
+
+    Or in case only a single value should be modified:
+
+      map[key, n] = valuen;
+
+    If  <n> is out of  range or if <key> doesn't  exists and <n> is greater
+  than 0 an "Illegal index" error will be reported. If <n> is equal to 0 or
+  the mapping only has a single value per key one can abbreviate it with:
+
+      map[key] = value;
+
+    If there is no <key> (and <n> is equal to 0 or  not specified at all) a
+  new one will be added automatically.
+
+    Deletion   of a key    is  done with    the  -=  operator or  the  efun
+  m_delete(). A mapping can only be substracted by one without any values:
+
+      map -= ([ key ]);
+  or:
+      map -= ([ key0, ..., keyn ]);
+
+  The efun takes a mapping as first and a key as second argument:
+
+      m_delete(map, key);
+
+    The  efun   m_delete() returns  the mapping   but because  mappings are
+  handled as references there is no need of an assignment like:
+
+      map = m_delete(map, key);
+
+
+  5. How can I access the data stored in a mapping?
+
+    This can be done by:
+
+      valuen = map[key, n];
+
+    Or in case of a mapping with just one value per key:
+
+      value0 = map[key];
+
+    If there is no  <key> in the mapping  and <n> is  0 or not specified at
+  all (which is the same) a 0 will be returned or if <n>  is greater than 0
+  an "Illegal index" error will be reported.
+
+
+  6. How can I test for the existance of a key?
+
+    A  return value of 0 is  sufficient for most applications but sometimes
+  the ambiguity  between an existing value of  0 and  a nonexisting key can
+  lead   to  a  problem.  Therefore   one  can use   the  efun member()  or
+  mapping_contains() to check if there actually is a key in the mapping:
+
+      if (member(map, key)) {
+        ...
+      }
+  or:
+      if (mapping_contains(&value0, ..., &valuen, map, key)) {
+        ...
+      }
+
+    This also shows how  one can retrieve all values   associated to a  key
+  from a mapping in a single step. The '&' is  the reference operator which
+  is neccesary to let the efun store the values in the variables.
+
+    In case   of  mappings   with   no  values,   the  efun   member()  and
+  mapping_contains() are equal in their behaviour  and their way of calling
+  because mapping_contains() won't get any reference variables to store the
+  values in (obviously, because there aren't any).
+
+     Also normally member() is known to return the postion of an element in
+  a list (i.e.  a  character in a  string or data   in an array) and if  an
+  element couldn't be  found -1 is returned.   But in the case  of mappings
+  there are no such things as order and postion. So member() only returns 0
+  or 1.
+
+
+  7. How can I copy a mapping?
+
+    A  mapping can  be  copied   with  the  +  operator   or by the    efun
+  copy_mapping():
+
+      newmap = ([]) + map;
+  or:
+      newmap = copy_mapping(map);
+
+    A mapping should only be copied when it is neccesary to get an own copy
+  of it that  must not be  shared by other objects.
+
+
+  8. How can I get all keys of a mapping?
+
+    The  efun m_indices() gets a mapping  as argument  and returns an array
+  holding all keys defined in this mapping:
+
+      keys = m_indices(map);
+
+
+  9. How can I get all the values of a mapping?
+
+    The efun m_values() gets  a mapping as  argument  and returns  an array
+  holding all the first (second, ...) values of it.
+
+      values0 = m_values(map);     returns the first values
+      values0 = m_values(map, 0);  dito
+      values1 = m_values(map, 1);  returns the second values
+        etc
+
+
+  10. How can I determine the size of a mapping?
+
+    Because a mapping is a kind of rectangle it has two sizes: a length and
+  a width.  There are three different efuns  to query these values. The first
+  two are the  efuns sizeof(), which returns the  amount of key-value
+  associations (the length of  a mapping), and widthof(), which returns the
+  number of values per key (the width). The third is the efun get_type_info().
+  get_type_info() is meant  to be a function  to identify a datatype.   Its
+  return value is an  array of two  numerical values.  The first  specifies
+  the datatype   of the argument and   the second is a   datatype dependend
+  value. In the case of a mapping the first value  is T_MAPPING (which is a
+  value defined in  <lpctypes.h>) and the  second the amount of values  per
+  key (a.k.a.  columns or the width  of the mapping  - actually it would be
+  correct to say that the width of a mapping is the  amount of columns plus
+  one for the keys but this is uncommon).
+
+
+  11. What is the best method to iterate over a mapping?
+
+    First of all the main purpose of a mapping is not meant to  be a set of
+  data to iterate over. Afterall the keys in a mapping have no specific but
+  a random order (at least on the LPC side).  But  still it is possible and
+  sometimes even neccesary to do so.
+
+    If all key-value associations  should be processed  then one should use
+  walk_mapping().  If all keys of a mapping should be processed to create a
+  new mapping being a subset of the given one, then filter_mapping() should
+  be  used.  If all  keys  are going to  be  processed and  to create a new
+  mapping with the  same set of keys as  the given mapping, then one  would
+  use map_mapping().  But in the case of an  iteration that should/can stop
+  even if not all data is processed it is probably wise to iterate over the
+  mapping by first querying for the keys and then to iterate over them with
+  a for() or a while() loop and querying the values by 'hand'.
+
+    The efun walk_mapping() gets  a mapping as  first argument and the name
+  of a function  as second one. All the  following arguments are treated as
+  extras which  will  be  passed to the   function specified  with the  2nd
+  argument. Instead of a string for the name of a function a closure can be
+  used, too. Nothing will be returned:
+
+      ...
+      walk_mapping(map, "func", xarg0, ..., xargn);
+      ...
+
+      void func(mixed key, mixed value0, ..., mixed valuen,
+                mixed xarg0, ..., mixed xargn) {
+        ...
+      }
+
+    func() will be called for all key-value associations  and gets as first
+  argument the key.  The next arguments are the  values behind the key  and
+  are passed as references.  The  rest  of the  passed arguments are  those
+  specified as extras. Because the values are passed as references (opposed
+  to  copies) it is possible  to modify them  from  inside func() by simply
+  assigning new value to the variables <value0>, ..., <valuen>.
+
+    The efun filter_mapping() calls  a function for  each key in  a mapping
+  and creates a new mapping  which only contains key-value associations for
+  which the called function returned true (not  equal 0 that is). The first
+  argument is the mapping to iterate over and the second is a function name
+  given as a string or a closure:
+
+      ...
+      submap = filter_mapping(map, "func", xarg0, ..., xargn);
+      ...
+
+      int func(mixed key, mixed xarg0, ..., mixed xargn) {
+        ...
+      }
+
+    func() gets  as first argument the key  and the others are those passed
+  as extras to filter_mapping().
+
+    The efun map_mapping() gets a mapping as first argument and a string as
+  a function name (or again a closure) as  second argument.  Any additional
+  arguments are again used  as extras that will  be passed to the iteration
+  function. This efun returns a new mapping with the same keys as the given
+  one.  The values  returned by the function  that is invoked  for each key
+  will be used as the associated data behind each key of the new mapping:
+
+      ...
+      newmap = map_mapping(map, "func", xarg0, ..., xargn);
+      ...
+
+      mixed func(mixed key, mixed xarg0, ..., mixed xargn) {
+        ...
+      }
+
+    func() gets  as first argument the key  and the others are those passed
+  as extras to map_mapping().
+
+    Because a function can only return  a single value  (even when it is an
+  array) it restricts the use  of map_mapping() to  only allow creation  of
+  mappings with a single value per key.
+
+
+  12. Is it possible to join/intersect/cut mappings with another?
+
+    Joining mappings is only possible, if  they have the same width (amount
+  of values per key). One can use the + and += operator:
+
+      map = map1 + map2 + ... + mapn;
+      map += map1 + map2 + ... + mapn;
+
+    Intersection     of   two   mappings is    only      possible by  using
+  filter_mapping(). There is  no efun or operator  which features this. The
+  'easiest' way may be the following function:
+
+      mapping intersect_mapping(mapping map1, mapping map2) {
+        closure cl;
+
+        cl = lambda(({ 'key }), ({ #'member, map2, 'key }));
+        return filter_mapping(map1, cl, map2);
+      }
+
+    This function returns a  new mapping which   consists of all  key-value
+  associations   of  <map1>  for which  an  equal  key  could   be found in
+  <map2>. This function uses  a closure which returns 0  or 1  depending on
+  wether a key from <map1> is contained in <map2> or not.
+
+    Cutting out  all key-value associations of a   mapping for which  a key
+  could be  found in another mapping  can  be done  by using  the  - and -=
+  operator:
+
+      mapping cut_mapping(mapping map1, mapping map2) {
+        return map1 - mkmapping(m_indices(map2));
+      }
+
+    Because a maping can  only be substracted by one  without any values we
+  first have to create such by using m_indices() and mkmapping().
+
+
+  13. What are those mappings without any values (besides keys) good for?
+
+    Because the way how the driver  searches for a  key in a mapping is
+  rather fast, those mappings can be used as a  set of elements with a fast
+  method for testing if an element is  contained in the set. This technique
+  is called hashing (further  explanation   would lead  too far)  which  is
+  faster  than searching for  values  in array  (which  is done in a linear
+  fashion).
+
+    Another (maybe  more pratical) use  of these  mappings  are to create a
+  array of unique values out of an array with several equal values:
+
+      uniques = m_indices(mkmapping(array));
+
+    mkmapping() uses  <array> to  create  a mapping without any  values but
+  just keys. And  because a mapping can only  have unique keys all multiple
+  values in <array> are taken as one.  The call of m_indices() then returns
+  an  array  of  these  unique keys.  Actually we  only  make  use of those
+  mappings temporarily.
+
+
+  14. How can I convert an alist into a  mapping and vice versa?
+
+    There are no special efuns which handle such conversions. But it can be
+  done by the following functions:
+
+      mapping alist_to_mapping(mixed *alist) {
+        return apply(#'mkmapping, alist);
+      }
+
+    The efun apply() takes a closure and an array of values and passes each
+  element of the  array as an  argument  to the  closure. Because  an alist
+  consists of an array of arrays with the first beeing the list of keys and
+  the others the values associated to each key passing them as arguments to
+  the efun closure #'mkmapping via apply() causes the creation of a mapping
+  out of an alist.
+
+      mixed *mapping_to_alist(mapping map) {
+        mixed *alist;
+        symbol *vars;
+        string var;
+        closure cl;
+        int width;
+
+        width = get_type_info(map)[1];
+        alist = allocate(width + 1);
+        vars  = allocate(width + 2);
+        for (var = "a"; width; var[0]++, width--) {
+          alist[width] = ({});
+          vars[width]  = quote(var);
+        }
+        alist[0] = ({});
+        vars[0]  = 'key;
+        vars[<1] = 'alist;
+        cl = lambda(vars, ({ #'=, 'alist, ({ #'insert_alist }) + vars }));
+        walk_mapping(map, cl, &alist);
+        return alist;
+      }
+
+    This function is  a bit more  complicated  than the other  and detailed
+  description would lead   too far of   the topic.  This  function has  one
+  restriction:  it can only turn a  mappings with up to  26  values per key
+  into an  alist.    But  this  should  be   sufficient for probably    all
+  applications which use mappings.
+
+  And Hyps further comment on this:
+        The function mapping_to_alist() is also not that
+        clever because insert_alist() allways creates a new
+        alist.  A second (optional) argument to m_values() to
+        specify the value column would be better. Besides
+        this, the conversion of a mapping into an alist could
+        be done by to_array().
+
+  15. Dirty Mappings
+
+  'Dirty mappings' are nothing the LPC programmer directly is involved
+  with, however, as it relates to the way mappings are implemented
+  internally by the gamedriver. However, as this term shows up in
+  various driver statistics, it is explained here.
+
+  There are two fundamental approaches to implement mappings:
+
+    1. Store all data entries in an array-like structure, in sorted order. 
+    2. Store all data in a hashtable, each entry allocaed separately.
+
+  Method 1 is very space efficient, as it doesn't need much overhead
+  per entry; however, insertions and deletions of entries are
+  relatively slow as all other entries need to be moved.     
+  Method 2 is very fast as nothing needs to be moved in memory,
+  however it has a large overhead.
+
+  The gamedriver uses a hybrid method: at the basis is a mapping
+  implementation based on arrays. However the driver uses a hash table
+  in addition to handle all the ongoing insertions and deletions.
+  Every once in a while, the contents of the hash table are sorted
+  into the base array, reasoning that any entry surviving for longer
+  time in the hash table is worth keeping in a more space-efficient
+  manner. 'Dirty' mappings are such mappings with both an array and a
+  hash part, 'clean' mappings are those with just an array part.
+
+HISTORY
+        The ([:width ]) notation was added in LDMud 3.2.9/3.3.208 .
+
+SEE ALSO
+        alists(LPC), closures(LPC), structs(LPC), mkmapping(E),
+        walk_mapping(E)
diff --git a/doc/LPC/modifiers b/doc/LPC/modifiers
new file mode 100644
index 0000000..a30904e
--- /dev/null
+++ b/doc/LPC/modifiers
@@ -0,0 +1,182 @@
+CONCEPT
+        modifiers
+
+DESCRIPTION
+        A modifier changes the syntactic and/or semantic behaviour of
+        an object-global variable or a function in an object.
+        The existing modifiers are described below.
+        To use a modifier just prepend it to the declaration. If several
+        modifiers are to be used their order does not matter:
+
+        private int bar;                         // example for a variable
+        protected nomask int foo() { return 3; } // example for a function
+
+        For functions:
+        ~~~~~~~~~~~~~~
+        private   -- such functions can only be called with an internal
+                     call from within this file. Not even inheriting
+                     objects can call these functions. You can nevertheless
+                     build an lfun-closure with #' out of a private function
+                     (but you cannot save and restore it).
+        protected -- such functions can be called from within the object,
+                     or from inheriting objects; but in neither case
+                     with call_other(). It is possible to create #' closures
+                     or use symbol_function() from within the object.
+                     Its use is preferred over the older "static".
+        static    -- such functions can be called from within the object
+                     in either way (internal call or with call_other()).
+                     Inheriting objects can call such functions.
+                     But it is not possible to call static functions from
+                     other objects via call_other().
+                     The use of 'static' in new code is not recommended.
+                     Note that an add_action() is treated like a call
+                     from within the object except the player who got the
+                     add_action() was forced (thus it is a simple way to
+                     secure an add_action() against forces, although this
+                     method has the severe disadvantages of raising an error
+                     at the force so better use the security system).
+                     Also efuns like call_out() or input_to() can call
+                     these functions if given as a string.
+        public    -- this is the default type. Such functions can be called
+                     from within the file as well as from inheriting objects
+                     and other objects via call_other().
+                     To declare a function public only results in the
+                     impossibility to change the accessibility at the
+                     inherit statement (see below). No error will occur,
+                     only the type will not be modified by the inherit
+                     statement.
+        nomask    -- such functions cannot be overridden by inheriting
+                     objects. If you have the fun foo() defined in your
+                     object and inherit an object which also has declared
+                     a function foo() and this nomask, you will get an
+                     compile error if you try to load your object.
+                     Furthermore a shadow will fail if it tries to shadow
+                     a nomask declared function.
+        varargs   -- this changes the syntax of the function in a way that
+                     not all of the arguments in the declaration must be
+                     given at the call. This is often very usefull if some
+                     of the arguments shall be omitable (the omitted
+                     arguments are set to 0 if the function is called with
+                     fewer arguments than specified).
+                     This is mainly within the object really necessary;
+                     call_other()s usually (that is if they do not have a
+                     certain pragma ('man pragma')) do not need the called
+                     function to be declared varargs to omit any arguments,
+                     but it is good style to use this modifier to document
+                     the code by this.
+        deprecated - Whenever this function is called, a warning is issued.
+                     Usually this is done at compile-time. Exceptions are
+                     call_others and symbol_function() which warn at run-time.
+
+        For object-global variables:
+        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+        private   -- such variables can only be accessed from within the
+                     same object. Not even inheriting objects can access
+                     private variables.
+                     It is a good style to declare all internal variables
+                     private to prevent inheriting objects from accessing
+                     the variables directly without using functions.
+        nosave    -- such variables are neither stored with save_object()
+                     nor restored with restore_object(). This can be very
+                     useful if you want a room to use save_object() and
+                     restore_object() to save your own defined variables
+                     but not the hundreds of variables inherited from a
+                     room-class (e.g. /complex/room). You then use the modifier
+                     at the inherit statement (see below).
+                     Note that nosave and private do not overlap in any
+                     way. They are absolutely independant.
+        static    -- the old name for 'nosave'. Its use is deprecated.
+        public    -- declares the variable public. It cannot be declared
+                     private or static by inheriting. No error will occur,
+                     only the type will not be modified by the inherit
+                     statement.
+        deprecated - Whenever this variable is used, a warning is issue.
+                     Usually this is done at compile-time, but
+                     symbol_variable() warns at run-time.
+
+        It is no good style to let inheriting objects have access to
+        internal variables so declare them as private and offer functions
+        to query and change the variables if possible.
+
+        It is also possible to redeclare all variables and/or functions
+        of an inherited object for the own object at the inheriting
+        statement:
+
+        private functions nosave variables inherit "complex/room";
+        public variables inherit "complex/room";
+        private functions inherit "complex/room";
+
+        To redeclare a function or a variable declared public in the
+        inherited object to be private or protected is not possible.
+
+        There also exists a modifier explicitly for the inherit statement:
+
+        virtual   -- inherits the given object virtually. This only makes
+                     sense in a complex inherit tree.
+                     If an object is inherited normally (not virtually)
+                     twice somewhere in the inherit tree the intern
+                     variables exist twice. If inherited virtually they
+                     exist only once.
+                     Example:
+                     A inherits B and C.
+                     B inherits D.
+                     C inherits D.
+                     If the inheritance of D is virtual in B and C
+                     D's variables exist only once in A. If A changes
+                     D's variables via functions of B this also changes
+                     the variables of D as known by C.
+
+                     virtual:               non-virtual:
+                        A                        A
+                       / \                      / \
+                      B   C                    B   C
+                       \ /                     |   |
+                        D                      D   D
+
+
+        To simplify the adoption of existing code, LPC allows to specify
+        a default visibility for functions and variables, using a syntax
+        similar to the inherit syntax:
+
+          default private;
+
+            All variables and functions are by default private.
+
+          default private variables public functions;
+
+            All variables are by default private, but functions are public.
+
+        Only the modifiers 'private', 'public' and 'protected' (and 'static'
+        for functions only) are allowed here.
+
+        The default visibility thus set affects only variables/functions with
+        no explicite visibility:
+
+          default private;
+
+          int private_var;
+          public int public_var;
+
+        The definition is valid from the point of the 'default' statement
+        until the end of the file, or until the next 'default' statement:
+
+          default private;
+
+          int private_var;
+
+          default public;
+
+          int public_var;
+
+        Note that this default visibility does not affect inherits.
+
+
+HISTORY
+        The modifier 'static' for variables was renamed to 'nosave'
+        with LDMud 3.2.8. 'static' is still recognized as an alias.
+
+        The default visibility was added in LDMud 3.2.9 as experimental
+        feature.
+
+SEE ALSO
+            closures(LPC), inheritance(LPC), functions(LPC), types(LPC)
diff --git a/doc/LPC/operators b/doc/LPC/operators
new file mode 100644
index 0000000..18406a3
--- /dev/null
+++ b/doc/LPC/operators
@@ -0,0 +1,213 @@
+NAME
+        operators
+
+DESCRIPTION
+
+        These are the operators availailable in LPC. They are listed
+        in the order of precedence (low priority first):
+
+
+        expr1 , expr2        Evaluate 'expr1' and then 'expr2'. The
+                        returned value is the result of 'expr2'. The
+                        returned value of 'expr1' is thrown away.
+
+        var = expr        Evaluate 'expr', and assign the value to
+                        'var'. The new value of 'var' is the result.
+
+        var += expr        Assign the value of 'expr' + 'var' to 'var'.
+                        This is mostly equivalent to "var = var + expr".
+
+        var -= expr        Similar to '+=' above.
+        var &= expr
+        var |= expr
+        var ^= expr
+        var <<= expr
+        var >>= expr
+        var >>>= expr
+        var *= expr
+        var %= expr
+        var /= expr
+        var &&= expr
+        var ||= expr
+
+        expr1 ? expr2 : expr3
+                        Evaluates 'expr1' and branches according to
+                        its truth value. If it is true, the 'expr2' is
+                        evaluated and returned as result, else
+                        'expr3'.
+
+        expr1 || expr2        The result is true if 'expr1' or 'expr2' is
+                        true. 'expr2' is not evaluated if 'expr1' was
+                        true.
+
+        expr1 && expr2        The result is true i 'expr1' and 'expr2' is
+                        true. 'expr2' is not evaluated if 'expr1' was
+                        false.
+
+        expr1 | expr2        The result is the bitwise or of 'expr1' and
+                        'expr2'.
+                        For arrays, the union set is computed: all elements
+                        from <expr1> plus all those from <expr2> which
+                        are not in <expr1>.
+
+        expr1 ^ expr2        The result is the bitwise xor of 'expr1' and
+                        'expr2'.
+                        For arrays, the symmetric difference is computed:
+                        all elements from <expr1> which are not in <expr2>,
+                        plus all those from <expr2> which are not in <expr1>.
+
+        expr1 & expr2        The result is the bitwise and of 'expr1' and
+                        'expr2'.
+
+                        For arrays and strings, the intersection set
+                        (all elements resp. characters from expr1 which
+                        which are also in the expr2) is computed.
+                        Note: "aab" & "a" -> "aa"
+                         but  ({ 'a','a','b' }) & ({ 'a' }) -> ({ 'a' })
+                        Eventually the array behaviour will be changed
+                        to match the string behaviour.
+
+                        Intersecting an array with a mapping is equivalent
+                        to intersecting the array with the indices of the
+                        mapping: array & mapping = array & m_indices(mapping)
+
+                        Mappings can be intersected with another mapping
+                        or an array. The resulting mapping holds all
+                        those entries from the first mapping, which are
+                        also mentioned in the second mapping (as index)
+                        resp. in the array.
+
+        expr1 == expr2        Compare values. Valid for strings, numbers,
+                              objects and closures.
+
+        expr1 != expr1        Compare values. Valid for strings, numbers,
+                              objects and closures.
+
+        expr1 > expr2        Valid for strings and numbers.
+
+        expr1 >= expr2        Valid for strings and numbers.
+
+        expr1 < expr2        Valid for strings and numbers.
+
+        expr1 <= expr2        Valid for strings and numbers.
+
+        expr1 << expr2        Shift 'expr1' left by 'expr2' bits; the sign
+                              bit is not preserved.
+
+        expr1 >> expr2        Shift 'expr1' right by 'expr2' bits.
+                        This shift preserves the sign of 'expr1'.
+
+        expr1 >>> expr2        Shift 'expr1' right by 'expr2' bits.
+                        This shift does not preserve the sign of 'expr1',
+                        instead it shifts in 0 bits.
+
+        expr1 + expr2        Add 'expr1' and 'expr2'. If numbers, then
+                        arithmetic addition is used. If one of the
+                        expressions are a string, then that string is
+                        concatenated with the other value.
+                        If the expressions are arrays, the result is
+                        the right array appended to the left.
+                        If the expressions are mappings of equal width,
+                        the result is merger of the two mappings. If one
+                        key exists in both mappings, the element from the
+                        right mapping appears in the result. If the two
+                        mappings are of different width, the result is
+                        <expr1> if non-empty, and <expr2> otherwise.
+
+        expr1 - expr2        Subtract 'expr2' from 'expr1'. Valid for
+                        numbers, strings, arrays, mappings.
+                        For arrays and strings, all occurences of the
+                        elements resp. characters in 'expr2' are removed
+                        from 'expr1', and the result is returned.
+                        For mapping, all occurances of elemens in 'expr1'
+                        which have a matching key in 'expr2' are removed, and
+                        the result is returned.
+
+        expr1 * expr2        Multiply 'expr1' with 'expr2'.
+                        If strings or arrays are multiplied with a number
+                        (zero or positive), the result is a repetition of the
+                        original string or array.
+
+        expr1 % expr2        The modulo operator of numeric arguments.
+
+        expr1 / expr2        Integer division.
+
+        ++ var                Increment the value of variable 'var', and
+                        return the new value.
+
+        -- var                Decrement the value of variable 'var', and
+                        return the new value.
+
+        - var                Compute the negative value of 'var'.
+
+        ! var                Compute the logical 'not' of an integer.
+
+        ~ var                The boolean 'not' of an integer.
+
+        ( type ) var    Return the value of <var> converted to <type>.
+                        <type> can be 'string', 'int', 'object', 'float'
+                        or 'int*'. <var> must be of a specific type
+                        for a conversion to take place; if <var> is 'mixed'
+                        or unknown, the cast is purely declarative.
+                        Also, if the declared type of <var> is that of <type>,
+                        the value is not changed.
+
+                        NB. The literal number 0 is of unknown type, as
+                        it doubles as 'not initialized' for strings, objects,
+                        and arrays.
+
+                        The operator acts like the efuns
+                        to_string(), to_int(), to_object(), to_float()
+                        and to_array(). It is advisable to use the
+                        efuns directly instead of the cast.
+
+        ({ type }) var  <var> is now assumed to have the type <type>.
+                        This is purely declarative, the actual value
+                        of <var> is not changed.
+
+        var ++                Increment the value of variable 'var', and
+                        return the old value.
+
+        var --                Decrement the value of variable 'var', and
+                        return the old value.
+
+        expr1[expr2]        The array or mapping given by 'expr1' is
+                        indexed by 'expr2'.
+
+        expr1[expr2..expr3] Extracts a
+                        piece from an array or string.
+                        expr2 or expr3 may be omitted, default is the begin
+                        or end of expr1.
+                        Negative numbers for expr2 or expr3
+                        mean ``count from before the beginning'', i.e.
+                        foo[-2..-1] is an empty array or string.
+                        foo[<2..<1] gives the 2nd and last element of
+                        the array resp. chars of the string.
+
+        expr1->name(...) The symbolic form of call_other(). 'expr1'
+                        gives either an object or a string which is
+                        used as the file_name of an object, and calls
+                        the function 'name' in this object.
+
+        ident::name(...)
+                        Call the inherited function 'name' with the
+                        given parameters in the parent 'ident'.
+                        'ident' may be given as string containing the
+                        full pathname, or as identifier containing the
+                        pure basename.
+                        If 'ident' is omitted, the last inherited
+                        function of this 'name' is called.
+
+        ({ })                Array constructor.
+        ([ ])                Mapping constructor.
+
+NOTE
+        The closure operators are not described here.
+
+HISTORY
+        LDMud 3.2.9 added '>>>', '>>>=', '&&=' and '||='.
+        LDMud 3.2.10 extended '&' to mappings.
+        LDMud 3.3 extended '|' and '^' to arrays.
+
+SEE ALSO
+        arrays(LPC), alists(LPC), mappings(LPC), closures(LPC)
diff --git a/doc/LPC/pragma b/doc/LPC/pragma
new file mode 100644
index 0000000..d26f326
--- /dev/null
+++ b/doc/LPC/pragma
@@ -0,0 +1,116 @@
+NAME
+        pragma
+
+DESCRIPTION
+        The preprocessor directive #pragma can be used to select
+        several compilation options. Multiple options can be selected
+        in one #pragma directive by separating them with commas.
+
+        no_clone: The blueprint object can't be cloned.
+        no_inherit: The program can't be inherited.
+        no_shadow: The program can't be shadowed (similar to declaring
+                all functions as 'nomask').
+
+        init_variables: Clone variables are initialized by __INIT().
+        share_variables: Clone variables are initialized from the
+                blueprint.
+
+        weak_types: no type checking (this is the default).
+        strict_types: all functions must be declared with argument
+                prototypes, and the return values of call_other() must
+                be casted.
+        strong_types: all functions must be declared with complete
+                types of return value and parameters.
+        save_types: the declaration data is kept after compilation and
+                checked at runtime. This is important for type-safe
+                inheritance.
+
+        rtt_checks: runtime checks during execution of this program will be
+                enabled. The interpreter will check for correct datatypes of
+                arguments on function calls. (Later it will include checks
+                upon assignments.)
+                Don't confuse this with strong/strict_types, they only
+                check at compile time.
+                strong_types/strict_types is seriously recommended.
+                This pragma implicitly enables save_types as well.
+        no_rtt_checks: disable runtime type checks for this program (default).
+
+        pedantic: Certain warnings are treated as errors:
+                - failure to pass enough arguments to simul efuns
+        sloppy: Turns off pedantic (the default).
+
+        range_check: Use of questionable ranges (ranges of negative sizes,
+                or with bounds beyond the array's size) cause a runtime
+                warning.
+        no_range_check: Turns off range_check (the default).
+
+        warn_deprecated: Use of deprecated efuns or indexing operations
+                causes the compiler to issue a warning (the default).
+        no_warn_deprecated: Turns off warn_deprecated.
+
+        warn_empty_casts: A cast of a value to its own type generates
+                a warning (the default). Exception are casts to type
+                'mixed'.
+        no_warn_empty_casts: Turns off warn_empty_casts.
+
+        warn_missing_return: Warn if a value-returning function is missing
+                a return statement (the default). If possible, the driver
+                will try to detect this at compile time; otherwise a runtime
+                warning will be generated when the function is executed.
+                The check applies only to functions with a declared return
+                type other than 'void'.
+        no_warn_missing_return: Turn off warn_missing_return.
+
+        warn_function_inconsistent: If an inherited function is
+                overloaded with inconsistent return types or arguments,
+                a warning is generated; or if pragma_pedantic is in effect,
+                an error. By default this is active.
+        no_warn_function_inconsistent: An inherited function can
+                be overloaded with inconsistent return types or arguments,
+                as long as pragma_pedantic is not in effect.
+
+                This pragma is meant to easen the adaption of legacy
+                mudlib code - in general one should fix the warnings,
+                not turn them off.
+
+        When an object is compiled with type testing (#pragma
+        strict_types), all types are saved of the arguments for that
+        function during compilation.  If the #pragma save_types is
+        specified, then the types are saved even after compilation, to
+        be used when the object is inherited.
+
+        The following two pragmas are available if the driver was
+        compiled with DEBUG and TRACE_CODE options:
+
+        set_code_window: Sets an offset to the current program writing
+                position. Use this BEFORE a piece of code where you
+                want to check to what bytecodes it is compiled.
+        show_code_window: shows some bytes starting at or near the
+                last point set_code_window was called.
+
+EXAMPLES
+        #pragma strict_types
+        #pragma no_clone, no_inherit
+
+HISTORY
+        LDMud 3.2.7 added local_scopes, no_local_scopes, no_clone
+        and no_inherit.
+        LDMud 3.2.8 added weak_types, pedantic and sloppy.
+        LDMud 3.2.9 allowed to specify multiple pragmas in one directive.
+        LDMud 3.2.9 added (no_)warn_deprecated.
+        LDMud 3.2.10 added (no_)warn_empty_casts.
+        Starting with LDMud 3.2.10, #pragma xxx_types in an included file are
+          no longer valid only until the end of the file, but remain active
+          when processing returns to the including file.
+        LDMud 3.2.11 added (no_)warn_function_inconsistent.
+        LDMud 3.3.378 added init_variables, share_variables.
+        LDMud 3.3.357 added (no_)warn_missing_return.
+        LDMud 3.3.646 added (no_)range_check.
+        LDMud 3.5.0 removed combine_strings and no_combine_strings.
+        LDMud 3.5.0 removed local_scopes and no_local_scopes.
+        LDMud 3.5.0 removed verbose_errors (making its behaviour mandatory).
+        LDMud 3.5.0 enabled warn_deprecated by default.
+
+SEE ALSO
+        inheritance(LPC), initialisation(LPC), objects(C),
+        operators(LPC)
diff --git a/doc/LPC/preprocessor b/doc/LPC/preprocessor
new file mode 100644
index 0000000..61593f0
--- /dev/null
+++ b/doc/LPC/preprocessor
@@ -0,0 +1,23 @@
+NAME
+        preprocessor
+
+DESCRIPTION
+        The LPC driver understands the following preprocessor
+        directives:
+
+        #include, #define, #if, #ifdef, #ifndef, #else, #elif,
+        #endif, #undef
+                same as in ANSI C
+
+        #line <num>
+                line numbers start at <num> with the next line
+
+        #echo
+                the rest of the line is printed to the error output
+                (stderr), thus can be captured into a log file
+
+        #pragma
+                see the separate man page
+
+SEE ALSO
+        pragma(LPC), predefined(D)
diff --git a/doc/LPC/references b/doc/LPC/references
new file mode 100644
index 0000000..c1d60f0
--- /dev/null
+++ b/doc/LPC/references
@@ -0,0 +1,49 @@
+CONCEPT
+        references
+
+DESCRIPTION
+        Call by reference can be used to have a function that passes
+        more than one value to the caller, without using arrays that
+        have to be unpacked thereinafter.
+        There is nothing special to declare in the calling function,
+        you simply do an assignment to a parameter of the function.
+        The caller has to pass references explicitely; this is done by
+        prefixing an lvalue with '&' .
+        To pass a reference to an element of an array, you have to
+        enclose the indexed lvalue in round brackets.
+
+EXAMPLE
+
+        void assign(mixed destination, mixed source) {
+            destination = source;
+        }
+
+        void extract_number(int destination, string source) {
+            sscanf(source, "%d", destination);
+        }
+
+        void test() {
+            int i;
+            float f;
+            mixed *a;
+
+            extract_number(&i, "42 palantirs");
+            assign(&f, 3.141592653589793);
+            assign(&a, ({ i, f }));
+            assign(&(a[<0..<1]), ({1,2,3,"sink","x","y","x"}));
+            assign(&(a[5][0]), 'w');
+            assign(&(a[5][<1]), 'g');
+            printf("%O", a));
+        }
+
+        ({ /* sizeof() == 9 */
+          42,
+          3.14159,
+          1,
+          2,
+          3,
+          "wing",
+          "x",
+          "y",
+          "x"
+        })
diff --git a/doc/LPC/strings b/doc/LPC/strings
new file mode 100644
index 0000000..15820ef
--- /dev/null
+++ b/doc/LPC/strings
@@ -0,0 +1,65 @@
+NAME
+        strings
+
+DESCRIPTION
+        A string is a data type in LPC.
+
+        It consists of several ASCII characters (letters), numbers
+        and special characters. ASCII characters may contain of
+        values between -128 and 127 (e.g. 'A' (65) or '5' (53)), but
+        0 is not allowed (because strings are 'null terminated',
+        which means that marks the end of a string).
+
+        Notations for strings:
+        "abc" + "def" "ghi" + 5 + "jkl" + to_string( ({'m','n'}) )
+        == "abcdefghi5jklmn"
+
+        Special characters must be escaped with a leading '\':
+          \n   (new line)
+          \t   (tabulator)
+          \b   (backspace)
+          ...
+
+        The single characters can be accessed like an array:
+          string s;
+          int i,j;
+
+          s="test";
+
+          s[0]       (ASCII Code (value) of the first character)     ='t'
+          s[<1]      (last character)                                ='t'
+          s[0..0]    (string composed of the first char)             ="t"
+          s[1..<2]   (string from second to character before last)   ="es"
+          s[2..]     (string from third to last character)           ="st"
+          ...
+
+        String manipulations:
+          s[0]=s[0]-32    ("test" -> "Test")
+          s[1..<2]="o"    ("test" -> "tot")
+          ...
+
+FUNCTIONS
+        int strlen(string str)
+        int member(string s, int elem)
+        int strstr (string str, string str2, int pos)
+        int to_int(string)
+        mixed *to_array(string)
+        string to_string(mixed)
+        string upperstring(string str)
+        string lowerstring(string str)
+        string lower_case(string str)
+        string capitalize(string str)
+        string break_string(string str, int width, int space, int leave_lfs)
+        string sprintf(string fmt, ...)
+        int sscanf(string str, string fmt, mixed var1, mixed var2, ...)
+        string *new_explode(string str, string del)
+        string *explode(string str, string del);
+        string implode(mixed *arr, string del)
+        string *regexplode (string text, string pattern)
+        string *regexp(string *list, string pattern)
+
+SEE ALSO
+        arrays, integers, mappings, operators, types
+
+LAST CHANGED
+        12. Mar 2004 Gloinson
diff --git a/doc/LPC/structs b/doc/LPC/structs
new file mode 100644
index 0000000..217b0a6
--- /dev/null
+++ b/doc/LPC/structs
@@ -0,0 +1,227 @@
+CONCEPT
+        structs
+
+INTRODUCTION
+        structs are, next to arrays and mappings, a way to group a
+        collection of value together.
+
+        A struct holds a fixed number of values, called 'members', and
+        allows to access them by their given name. The name is resolved
+        when the LPC code is compiled, making struct member access as fast
+        as array member access.
+
+        structs are passed by reference.
+
+
+DEFINITION
+        A new struct type has to be defined at the top level of an
+        object. For example
+
+            struct Foo {
+              int        one, *two;
+              struct Bar three;
+            };
+
+        defines the new struct 'Foo' with three members: integer 'one',
+        integer array 'two', and struct Bar 'three'
+
+        It is possible to 'inherit' structs from each other. Given above
+        definition of struct Foo, the following definition
+
+            struct Quux (Foo) {
+              int four;
+            };
+
+        is equivalent to the definition
+
+            struct Quux {
+              int        one, *two;
+              struct Bar three;
+              int four;
+            };
+
+
+        The usual visibility modifiers apply, e.g.
+
+            protected struct Bang {...};
+
+
+        struct definitions are promoted through inheritance like functions,
+        with the difference that all structs live in the same flat namespace.
+        This means: a struct defined in a program is visible in _all_
+        inherited programs, regardless of how deep the inheritance is
+        nested.  This also means that in one program there must not be
+        two structs, inherited or not, with the same name.
+
+
+        To declare a struct without defining it, write:
+
+            struct Quux;
+
+        This notation is useful if you have two structs referencing
+        each other:
+
+            struct Quux;
+
+            struct Bar {
+              struct Quux quux;
+            };
+            struct Quux {
+              struct Bar bar;
+            };
+
+
+USAGE
+        To use a struct, its definition must be visible - either because it
+        is defined in the object compiled, or it has been inherited.
+        (Note: #include'ing structs does not what you think it does: in
+        LPC it constructs a new struct type whereever it is included).
+
+
+        A variable to hold a struct is defined like this:
+
+            struct Foo var;
+
+        and similar for function arguments:
+
+            void fun (struct Foo arg)
+
+
+        Just writing 'struct Foo var' however does not _create_ a struct,
+        it just creates a variable capable of holding one. To assign a value
+        to the variable upon creation, assign it with a struct value, either
+        from another variable or from a literal struct:
+
+            struct Foo var = (<Foo>);
+
+
+        Literal structs are written using (<>) as delimiters:
+
+            (<Foo>)
+                creates an empty instance of struct Foo
+
+            (<Foo> 1, ({ 2 }), bar)
+                creates an instance of struct Foo, and assigns 1 to member
+                'one', ({ 2 }) to member 'two', and the content of variable
+                bar to member 'three'.
+
+            (<Foo> two: ({ 2 }) )
+               creates an instance of struct Foo which is all empty except
+               for member 'two' which is assigned the value ({ 2 }).
+
+        It is not possible to use both named and unnamed initializers
+        in the same literal.
+
+
+        A struct member is accessed using the -> operator:
+
+            struct Foo var = ...;
+
+            var->one = 1;
+
+
+        It is possible to compute struct lookups at runtime:
+
+            struct Foo bar = ...;
+            string member = "one";
+
+            bar->(member) = 1; // sets bar->one to 1
+            bar->(0) = 1;      // sets bar->one to 1
+
+
+        When using struct values held in variables/expressions of type
+        'mixed', the 'mixed' value should to be casted to the struct
+        value. The cast can be omitted if the looked-up member exists
+        in only one struct (and its children) known to the compiler:
+
+            struct Foo { int one; };
+            struct Bar { int two; };
+            struct Baz { int two; };
+            mixed var;
+
+                        var->one  // looks up Foo->one
+            (struct Foo)var->one  // looks up Foo->one
+                        var->two  // ERROR: ambiguous lookup
+            (struct Bar)var->one  // looks up Bar->one
+
+
+USAGE IN CLOSURES
+        The #'(< operator can be used in lambda closures to create a
+        struct; the type of the struct is given by the 'template'
+        struct passed as first argument. The content of the template
+        struct is irrelevant, so an empty struct suffices. For
+        example, to create an instance of struct Foo:
+        
+            ({ #'(<, (<Foo>), 1, ({ 2 }), (<Bar>) })
+
+        The order of the member values is the order in which they
+        appear in the struct definition.
+
+        To access a struct member in a lambda closure, use the #'->
+        operator with the name of the member as double-quoted symbol
+        or literal string:
+
+            ({ #'->, struct-expression, ''one })
+            ({ #'->, struct-expression, "one" })
+
+
+MISCELLANEOUS
+        Internally structs can be identified by the ID string
+        returned from get_type_info(). This string contains the name
+        of the struct, the name of the program its type was defined in,
+        and the ID number of the program. However, do not rely on
+        a particular format of this string!
+
+        Support for structs is signaled by the macro __LPC_STRUCTS__.
+
+        Since structs are tied to the program they are defined in,
+        re-compiling a program creates new struct types which are
+        in principle incompatible to the old ones. However, the LPC
+        compiler checks if the newly compiled structs have the same
+        structure as their older counterparts of the same name
+        (and defining program). If the structures conform, the existing
+        older struct types are used instead of the new ones. This way
+        an accidental of for example /std/types.c doesn't break
+        the whole mud.
+
+
+EXAMPLES
+        Suppose we have two objects: a monster, and a monster
+        coordinate tracker, and we want to use a struct to store the
+        coordinate:
+
+          -- monster_coordinate.c --
+            struct Coordinate { int x; int y; };
+
+          -- monster_tracker.c --
+            inherit "monster_coordinate";
+
+            void track (struct Coordinate coord) { ... }
+
+          -- monster.c --
+            inherit "monster_coordinate";
+
+            int move (..) {
+              ...
+              "monster_tracker"->track( (<Coordinate> my_x, my_y) );
+            }
+
+        Note that using '#include "monster_coordinate.c"' instead of inherit
+        won't work. While the objects would compile, the first call to
+        track() would cause a runtime error of the type 
+
+          Illegal type to struct->(): struct Coordinate (/monster.c #234),
+                                      expected struct Coordinate
+                                      (/monster_tracker.c #552)
+
+
+HISTORY
+        structs were fully implemented first in LDMud 3.3.246.
+        The implementation was revised in LDMud 3.3.344.
+        The reactivation of unchanged structs in object updates was
+        implemented in LDMud 3.3.417.
+
+
+SEE ALSO
+        mappings(LPC), get_type_info(E), structp(E), to_mapping(E),
+        to_struct(E), struct_info(E), baseof(E)
diff --git a/doc/LPC/switch b/doc/LPC/switch
new file mode 100644
index 0000000..9bca596
--- /dev/null
+++ b/doc/LPC/switch
@@ -0,0 +1,93 @@
+NAME
+        switch
+
+SYNTAX
+        switch (expr) block
+
+DESCRIPTION
+        Branch to the case label in statement that matches expr.
+        If no matching case label is found (by value or by type),
+        branch to the default label in statement.
+
+        A case label has the form
+
+                case expr_n :
+
+        where expr_n must be constant, or the form
+
+                case expr_n1 .. expr_n2 :
+
+        where expr_n1 and expr_n2 must be numeric constants and
+        expr_n1 < expr_n2.
+
+        Either all case labels have to be strings or all have to be
+        numeric. Only 0 is special: it is allowed in a switch
+        statement where all other labels are strings.
+
+        A default label has the form
+
+                default :
+
+        The default label defaults to the end of statement if not
+        given explicitly.
+
+        Whenever a 'break' statement is executed inside 'statement' a
+        branch to the end of the switch statement is performed.
+
+EXAMPLE
+        Typical usage:
+
+            switch(random(100)) {
+              case 0 .. 22 : write("Nothing happens"); break;
+              case 23 .. 27 :
+                write("You are surrounded by a golden glow");
+                this_player()->heal_self(random(3));
+                break;
+              case 28 .. 32 :
+                write("The water was poisoned!\n");
+                this_player()->add_exp(this_player()->hit_player(random(4)));
+                break;
+              case 33 : write("You hear a voice whispering: "+random_hint());
+              /* fall through */
+              case 34 :
+                write("While you didn't pay attention, a water demon "
+                      "snatches a coin out of your purse!\n");
+                this_player()->add_money(-1);
+                break;
+              default : write "You hear some strange noises\n"; break;
+              case 42 : return;
+              case 99 : write("It tastes good.\n";
+            }
+
+NOTE
+        In C, the grammar for switch() is
+
+            switch (expr) statement
+
+        allowing constructs like
+
+            switch (expr)
+              while (expr2)
+              {
+              case 1: ...
+              case 2: ...
+              }
+
+        In LPC a switch has to be followed by a block that contains the
+        case labels directly. In contrast to C the group of statements
+        following a case label have their own lexical scope so that
+        variable declarations may not cross case labels.
+
+HISTORY
+        LDMud 3.2.10 constrained the grammar to require a block for the
+          switch() body, not just a statement. This differs from the C
+          syntax, but was necessary as the compiler didn't handle
+          the statement case correctly.
+        LDMud 3.3 allowed to pass values of the wrong type to switch(), the
+          driver would in that case use the default case. Before, values of
+          the wrong type caused a runtime error.
+        LDMud 3.3.718 disallowed case labels in inner blocks and variable
+          declarations that cross case labels.
+
+SEE ALSO
+        for(LPC), foreach(LPC), do-while(LPC), if(LPC), while(LPC)
diff --git a/doc/LPC/types b/doc/LPC/types
new file mode 100644
index 0000000..903a1be
--- /dev/null
+++ b/doc/LPC/types
@@ -0,0 +1,136 @@
+CONCEPT
+    types
+
+DESCRIPTION
+
+    Variables can have the following types:
+
+    o int       An integer. Normally full 32 bits signed, yielding a
+                range of at least -2,147,483,648 to 2,147,483,647. The
+                exact available range is given by the predefined
+                macros __INT_MIN__ and __INT_MAX__.
+
+                Integer values can be specified in decimal, in
+                sedecimal when preceeded by '0x' (e.g. 0x11), binary
+                when preceeded by '0b' (e.g. 0b00010001), octal when
+                preceeded by '0o' (e.g. 0o21) and as character
+                yielding the charset value for the character as the number
+                to use (e.g. '0' yields 48 on ASCII machines).
+
+                Character values are enclosed in single-quotes ('),
+                with the sequence ''' returning the single-quote
+                itself. Instead of the literal character an
+                escape-sequence can be written between the
+                single-quotes:
+                  \N   : the character code N in decimal
+                  \0xN : the character code N in sedecimal
+                  \xN  : the character code N in sedecimal
+                  \0oN : the character code N in octal
+                  \0bN : the character code N in binary
+                  \a   : BEL (0x07)
+                  \b   : Backspace (0x08)
+                  \t   : Tab (0x09)
+                  \e   : Escape (0x1b)
+                  \n   : Newline (0x0a)
+                  \f   : Formfeed (0x0c)
+                  \r   : Carriage Return (0x0d)
+                  \<other character>: the given character
+
+    o status    OUTDATED - status was planned to be an optimized
+                boolean format, but this was never actually
+                implemented. status does work; however, since it
+                is only an alias for type 'int', just use int.
+
+    o string    Strings in lpc are true strings, not arrays of characters
+                as in C (and not pointers to strings). Strings are
+                mutable -- that is, the contents of a string can be
+                modified as needed.
+
+                The text of a string is written between double-quotes
+                ("). A string can written over several lines when the
+                lineends are escaped (like a macro), however a better
+                solution is to write one string per line and let the
+                gamedriver concatenate them.
+
+                String text typically consists of literal characters,
+                but escape-sequences can be used instead of
+                characters:
+                  \<CR>     : Carriage Return (0x0d)
+                  \<CR><LF> : ignored
+                  \<LF>     : ignored
+                  \<LF><CR> : ignored
+
+                  \N   : the character code N in decimal
+                  \0xN : the character code N in sedecimal
+                  \xN  : the character code N in sedecimal
+                  \0oN : the character code N in octal
+                  \0bN : the character code N in binary
+                  \a   : BEL (0x07)
+                  \b   : Backspace (0x08)
+                  \t   : Tab (0x09)
+                  \e   : Escape (0x1b)
+                  \n   : Newline (0x0a)
+                  \f   : Formfeed (0x0c)
+                  \r   : Carriage Return (0x0d)
+                  \"   : The double quote (")
+                  \<other character>: the given character
+
+                Adjacent string literals are automatically
+                concatenated by the driver when the LPC program is
+                compiled. String literals joined with '+' are
+                concatenated by the LPC compiler as well.
+
+    o object    Pointer to an object. Objects are always passed by
+                reference.
+
+    o array     Pointer to a vector of values, which could also
+                be an alist. Arrays take the form ({ n1, n2, n3 })
+                and may contain any type or a mix of types. Arrays
+                are always passed by reference. Note that the size
+                of arrays in LPC, unlike most programming languages,
+                CAN be changed at run-time.
+
+    o mapping   An 'associative array' consisting of values indexed by
+                keys. The indices can be any kind of datatype.
+                Mappings take the form ([ key1: value1, key2: value2 ]).
+                By default, mappings are passed by reference.
+
+    o closure   References to executable code, both to local
+                functions, efuns and to functions compiled at
+                run-time ("lambda closures").
+
+    o symbol    Identifier names, which in essence are quoted strings.
+                They are used to compute lambda closures, e.g. instead
+                of ({..., 'ident, ... }) you can write declare a
+                'symbol' variable foo, compute a value for it, and then
+                create the closure as ({ ..., foo, ... })
+
+    o float     A floating point number in the absolute range
+                __FLOAT_MIN__ to __FLOAT_MAX__ (typically 1e-38 to 1e+38).
+                Floating point numbers are signified by a '.'
+                appearing, e.g. '1' is integer 1, but '1.' is
+                floating-point 1 .
+
+    o mixed     A variable allowed to take a value of any type (int,
+                string, object, array, mapping, float or closure).
+
+    o struct    A collection of values. See structs(LPC).
+
+    o union     A range of types, either of which the variable
+                can contain at runtime. See unions(LPC).
+
+    All uninitialized variables have the value 0.
+
+    The type of a variable is really only for documentation. Unless
+    you define #pragma strong_types or rtt_checks, variables can
+    actually be of any type and has no effect at all on the program.
+    However, it's extremely bad style to declare one type but use
+    another, so please try to avoid this.
+
+    A pointer to a destructed object will always have the value 0.
+
+
+SEE ALSO
+    alists(LPC), arrays(LPC), mappings(LPC), closures(LPC), structs(LPC),
+    unions(LPC), typeof(E), get_type_info(E), inheritance(LPC),
+    pragma(LPC), modifiers(LPC), escape(LPC)
diff --git a/doc/LPC/unions b/doc/LPC/unions
new file mode 100644
index 0000000..65a841d
--- /dev/null
+++ b/doc/LPC/unions
@@ -0,0 +1,30 @@
+CONCEPT
+        unions
+
+DESCRIPTION
+        Unions types are a declaration at compile time that a variable,
+        function parameter or function return value can be one of
+        several types.
+
+        Except for type checks using #pragma rtt_checks they have no
+        impact at runtime. There is no runtime union type, the concrete
+        value type is one of the possibilities of the union type.
+
+        Union types have no type names for themselves, they are declared
+        anonymously with the declaration of the variable, function
+        parameter or return type:
+
+            int|string var;
+            int|float fun(object|closure f);
+
+        When using union types as array member types they must be
+        enclosed with < >:
+
+            <int|string>* arr;    /* An array of ints and strings. */
+            int*|string*  arr;    /* Either an array of ints or
+                                     an array of strings.          */
+
+            /* There must be a whitespace between two consecutive <
+               to be not confused with the << operator:            */
+            < <int|string>*|object >* arr;
+
diff --git a/doc/LPC/varargs b/doc/LPC/varargs
new file mode 100644
index 0000000..ef21837
--- /dev/null
+++ b/doc/LPC/varargs
@@ -0,0 +1,75 @@
+CONCEPT
+    varargs
+
+DESCRIPTION
+    A function uses "varargs", short for "variable arguments", if
+    it intentionally may be called with less or more arguments
+    than formally specified.
+
+    The proper order to define a function call is:
+
+        [ modifier ] [ varargs ] [ return type ] function( args...)
+
+     Any other order will result in an error.
+
+
+    Given a function definition like this:
+
+        void fun (string arg1, int arg2, int arg3)
+
+    fun() has to be called with exactly three parameters: one
+    string and two integers.
+
+
+    If the function is defined as
+
+        varargs void fun (string arg1, int arg2, int arg3)
+
+    it is possible to call the function with just arg1, or arg1
+    and arg2. The remaining unspecified arguments (arg2 and arg3,
+    resp. arg3) are in these cases assumed to be 0.
+
+
+    To pass more arguments than specified, the functions last
+    parameter must be defined as following:
+
+        void fun (string arg1, int arg2, varargs int * arg3)
+
+    This allows fun() to be called with two or more arguments.
+    The arguments, except those assigned to the other parameters,
+    in this case arg1 and arg2, and collected into an array which
+    is then passed as arg3. For example
+
+        fun("foo", 1)       -> arg3 == ({ })
+        fun("foo", 1, 2)    -> arg3 == ({ 2 })
+        fun("foo", 1, 2, 3) -> arg3 == ({ 2, 3 })
+
+    The type of the varargs argument has to be an array of the
+    expected type (int*, object*, string*, ...); in this example,
+    only integers are allowed. To accept arguments of any kind,
+    define the parameter as 'varargs mixed' or 'varargs mixed*'.
+
+    To 'flatten' the received argument array in your own function
+    calls, use the efun apply(); e.g.:
+
+        apply(#'call_out, "bar", 1, arg3)
+
+    or the 'flatten arguments' operator:
+
+       call_out("bar", 1, arg3...)
+
+    The two varargs variants can of course be combined:
+
+        varargs void fun (string arg1, int arg2, varargs int* arg3)
+
+    defines a function which may be called with any number of
+    arguments.
+
+
+HISTORY
+    The possibility to pass more arguments than formally specified
+    was introduced in 3.2.1@132. Before, the excess arguments were
+    silently ignored.
+
+SEE ALSO
+    pragma(LPC), apply(E), modifiers(LPC)
diff --git a/doc/LPC/while b/doc/LPC/while
new file mode 100644
index 0000000..adc4708
--- /dev/null
+++ b/doc/LPC/while
@@ -0,0 +1,15 @@
+NAME
+        while
+
+SYNTAX
+        while (expr) statement;
+
+DESCRIPTION
+        While 'expr' evaluates to non 0, execute statement.
+
+        A 'break' in the 'statement' will terminate the loop. A
+        'continue' will continue the execution from the beginning of
+        the loop.
+
+SEE ALSO
+        for(LPC), foreach(LPC), do-while(LPC), if(LPC), switch(LPC)