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)
