diff --git a/std/hook_provider.c b/std/hook_provider.c
new file mode 100644
index 0000000..00b8ca3
--- /dev/null
+++ b/std/hook_provider.c
@@ -0,0 +1,493 @@
+// MorgenGrauen MUDlib
+//
+// /std/hook_provider.c  - Hooksystem
+//
+// $Id: hook_provider.c 9453 2016-02-04 21:22:54Z Zesstra $
+
+#pragma strong_types
+#pragma save_types
+#pragma no_clone
+#pragma range_check
+#pragma pedantic
+
+#define NEED_PROTOTYPES
+#include <hook.h>
+#undef NEED_PROTOTYPES
+
+// get the object fur closure <cl> (where the code is!)
+#define GET_OBJECT(cl) get_type_info(cl,2)
+
+// Struct describing one hook consumer. <cl> will be called when the hook is
+// triggered. The lower <prio>, the earlier the consumer will be called.
+// <type> is a consumertype, e.g. surveyor, listener etc. (see hook.h)
+struct hook_entry_s {
+  closure cl;
+  int prio;
+  int endtime;
+  int type;
+};
+
+// Struct holding the consumers of one specific hook.
+// the value arrays are guarenteed to exist, but may be empty.
+struct hook_s {
+  struct hook_entry_s *surveyors;
+  struct hook_entry_s *hmods;
+  struct hook_entry_s *dmods;
+  struct hook_entry_s *listeners;
+};
+
+/* hook mapping
+   the list of all offered hooks in the following structure:
+   ([hookid: (<hook_s>), ...
+   )]
+*/
+private nosave mapping hookMapping=([]);
+
+protected void CleanHookMapping(int *hookids);
+
+// Debugging - ggf. ueberschreiben
+protected int h_dbg() {return 0;}
+
+void HookTestOffer(int id, int stat){
+  if(h_dbg()) {
+      offerHook(id,stat);
+  }
+}
+
+void HookTestTrigger(int id, mixed data){
+  if(h_dbg()) {
+      HookFlow(id,data);
+  }
+}
+
+// NOTE: if you have the closure, you can call the lfun, even if it is
+// private. Therefore access to this data should be restricted to
+// this_object().
+// These two functions should be used for debugging purposes.
+protected mapping HCopyHookMapping(){
+  return deep_copy(hookMapping);
+}
+
+protected mapping HCopyHookConsumers(int hookid){
+  if(member(hookMapping,hookid)) {
+      CleanHookMapping(({hookid}));
+      return deep_copy(hookMapping[hookid]);
+  }
+  return 0;
+}
+
+// Ggf. zum Ueberschreiben.
+int HConsumerTypeIsAllowed(int type, object consumer){
+  return 1;
+}
+
+int HPriorityIsAllowed(int prio, object consumer){
+  return 1;
+}
+
+// clean internal hook data structures of stale hook consumers.
+protected void CleanHookMapping(int *hookids){
+  // hooks enthaelt die aufzuraeumenden Hooks. Wenn kein Array -> alle Hooks
+  if (!pointerp(hookids))
+    hookids=m_indices(hookMapping);
+
+  foreach(int hookid : hookids) { // alle Hooks
+    struct hook_s hooks = hookMapping[hookid];
+    if (!structp(hooks))
+      continue;
+    // ueber alle Consumertypen laufen
+    foreach (string consumertype: H_CONSUMERNAMES)
+    {
+      // Yeah - compute struct lookup at runtime... ;-)
+      struct hook_entry_s *consumers = hooks->(consumertype);
+      // Hookeintraege / Consumer
+      foreach(struct hook_entry_s h : &consumers) {
+        // alle abgelaufenen Eintraege oder solche mit zerstoerten Objekten
+        // nullen
+        if (!h->cl || h->endtime < time() )
+            h = 0;
+      }
+      // 0 noch rauswerfen.
+      hooks->(consumertype) -= ({0});
+    }
+  }
+}
+
+protected void offerHook(int hookid, int offerstate)
+{
+  H_DMSG(sprintf("offerHook hookid %d offerstate %d\n",hookid,offerstate));
+  if (hookid>0)
+  {
+      if (offerstate) {
+          if (!member(hookMapping,hookid)) {
+              struct hook_s hook = (<hook_s>
+                  surveyors: ({}),
+                  hmods: ({}),
+                  dmods: ({}),
+                  listeners: ({}) );
+              hookMapping[hookid] = hook;
+          }
+      }
+      else {
+          if (member(hookMapping,hookid)) {
+            m_delete(hookMapping,hookid);
+          }
+      }
+  }
+  H_DMSG(sprintf("  result %O\n",hookMapping));
+}
+
+// hookConsumerInfo() liefert Array von hook_entry_s zurueck. D.h. bei Abfrage
+// von Objekten alle Closures dieses Objekts und jede davon erzeugt ein
+// Element hook_entry_s im Ergebnisarray. Bei Abfrage von Closures hat das
+// Array immer genau 1 oder kein Element.
+// WARNING: whoever has a hook_entry_s can change/delete the hook!
+//          NEVER return the original to an external caller!
+// NOTE: whoever has the cl from hook_entry_s can call it, even if the lfun
+//       is private (and this object the only one knowing it).
+protected mixed * hookConsumerInfo(int hookid, object|closure consumer)
+{
+  closure filter_cl;
+
+  if (!member(hookMapping,hookid))
+    return ({});
+
+  // Closure zum Filtern bestimmen - je nachdem, was gesucht wird.
+  if (closurep(consumer))
+  {
+    filter_cl = function int (struct hook_entry_s h)
+                { return h->cl == consumer
+                         && h->endtime >= time(); };
+  }
+  else if (objectp(consumer))
+  {
+    filter_cl = function int (struct hook_entry_s h)
+                { return GET_OBJECT(h->cl) == consumer
+                         && h->endtime >= time(); };
+  }
+  else
+  {
+    return ({});
+  }
+
+  struct hook_s hook = hookMapping[hookid];
+  struct hook_entry_s *result = ({});
+  foreach (string consumertype: H_CONSUMERNAMES )
+  {
+    result += filter(hook->(consumertype), filter_cl);
+  }
+  return result;
+}
+
+int HIsHookConsumer(int hookid, mixed consumer) {
+  return sizeof(hookConsumerInfo(hookid,consumer)) != 0;
+}
+
+int* HListHooks() {
+  return m_indices(hookMapping);
+}
+
+int HUnregisterFromHook(int hookid, mixed consumer) {
+
+  H_DMSG(sprintf("HUnregisterFromHook hookid %d consumer %O\n",hookid,consumer));
+  if (objectp(consumer))
+    consumer = symbol_function("HookCallback", consumer);
+  if (!closurep(consumer))
+    return 0;
+
+  struct hook_entry_s *info = hookConsumerInfo(hookid,consumer);
+
+  // it should never happen that a closure is registered more than once, i.e.
+  // the result contains more than one element.
+  if (sizeof(info)) {
+      struct hook_entry_s h = info[0];
+      h->cl = 0;
+      H_DMSG(sprintf("  result %O\n", hookMapping));
+      // the now invalid h will be cleaned up later.
+      return 1;
+  }
+  return 0;
+}
+
+// surveyors are asked for registration permittance
+protected int askSurveyorsForRegistrationAllowance(
+                  struct hook_entry_s *surveyors, object consumer,int hookid,
+                  int hookprio,int consumertype)
+{
+  H_DMSG(sprintf("askSurveyorsForRegistrationAllowance surveyors %O, "
+        "consumer %O, hookid %d, hookprio %d, consumertype %d\n",
+        surveyors,consumer,hookid,hookprio,consumertype));
+
+  foreach(struct hook_entry_s surveyor : surveyors) {
+    if (closurep(surveyor->cl) && surveyor->endtime >= time())
+    {
+      // surveyor hook gueltig.
+      object sob = GET_OBJECT(surveyor->cl);
+      if (!sob->HookRegistrationCallback(consumer, hookid,
+                        this_object(), hookprio, consumertype))
+        return 0;
+    }
+  }
+  return 1;
+}
+
+int HRegisterToHook(int hookid, mixed consumer, int hookprio,
+                       int consumertype, int timeInSeconds) {
+  int ret, regtime;
+
+  if (!closurep(consumer) && !objectp(consumer))
+    raise_error(sprintf("Wrong argument %.50O to HRegisterToHook(): consumer "
+          "must be closure or object.\n",consumer));
+
+  if (!member(hookMapping, hookid))
+    return -1;
+
+  if (objectp(consumer)) {
+    consumer = symbol_function("HookCallback", consumer);
+    if (!closurep(consumer))
+      return -2;
+  }
+
+  if (timeInSeconds > 0) {
+      regtime=time() + timeInSeconds;
+  }
+  else {
+      regtime=__INT_MAX__;
+  }
+
+  H_DMSG(sprintf("HRegisterToHook hookid %d consumer %O\n hookprio %d "
+        "consumertype %d\n",hookid,consumer,hookprio,consumertype));
+
+  CleanHookMapping(({hookid})); // entfernt ungueltige/abgelaufene Eintraege
+
+  // nur einmal pro closure registrieren!
+  if (HIsHookConsumer(hookid, consumer))
+    return -3;
+
+  // Consumertyp erlaubt?
+  if (H_CONSUMERCHECK(consumertype) == -1
+      || !HConsumerTypeIsAllowed(consumertype,GET_OBJECT(consumer)))
+    return -4;
+
+  // Prioritaet erlaubt?
+  if (H_HOOK_VALIDPRIO(hookprio) == -1
+      || !HPriorityIsAllowed(hookprio, GET_OBJECT(consumer)))
+    return -5;
+
+  struct hook_s hook = hookMapping[hookid];
+
+  // Und surveyors erlauben die Registierung?
+  if (!askSurveyorsForRegistrationAllowance(hook->surveyors,
+                    GET_OBJECT(consumer),hookid,
+                    hookprio,consumertype))
+    return -6;
+
+  string ctypename = H_CONSUMERNAMES[consumertype];
+
+  // get the consumer array
+  struct hook_entry_s *consumers = hook->(ctypename);
+
+  // assemble new hook consumer struct
+  struct hook_entry_s newconsumer = (<hook_entry_s>
+                      cl : consumer,
+                      prio : hookprio,
+                      endtime : regtime,
+                      type : consumertype );
+
+  // consumers enthaelt die Hookeintraege
+  if (sizeof(consumers) < MAX_HOOK_COUNTS[consumertype]) {
+    // max. Anzahl an Eintraegen fuer diesen Typ noch nicht
+    // erreicht, direkt anhaengen.
+    consumers += ({ newconsumer });
+    hook->(ctypename) = consumers;
+    ret=1;
+  }
+  else {
+    // gibt es einen Eintrag mit hoeherem Priowert (niedrigere
+    // Prioritaet), den man ersetzen koennte?
+    // Das Array ist sortiert, mit hoechsten Priowerten am
+    // Ende. Ersetzt werden soll der Eintrag mit dem hoechsten
+    // Zahlenwert, falls der neue Eintrag einen niedrigeren Wert
+    // hat, d.h. es muss nur er letzte Consumer im Array geprueft werden.
+    // Pruefung auf Closureexistenz, falls der Surveyor Objekte
+    // zerstoert (hat)...
+    struct hook_entry_s oh = consumers[<1];
+    if (!oh->cl || oh->prio > newconsumer->prio) {
+      // Found superseedable entry - replace it, but inform the object.
+      H_DMSG("Found superseedable entry\n");
+      consumers[<1] = newconsumer;
+      GET_OBJECT(oh->cl)->superseededHook(hookid, this_object());
+      ret = 1;
+      // nicht noetig, consumers wieder in sein hook_s zu haenngen wegen Array
+      // -> Referenz
+    }
+  }
+
+  // wenn ein Eintrag hinzugefuegt wurde, muss neu sortiert werden
+  if (ret) {
+    hook->(ctypename) = sort_array(consumers,
+        function int (struct hook_entry_s a, struct hook_entry_s b) {
+            return a->prio > b->prio; } );
+  }
+
+  H_DMSG(sprintf("  result %O\n",hookMapping));
+
+  // -7, wenn kein Eintrag mehr frei / zuviele Hooks
+  return (ret > 0 ? 1 : -7);
+}
+
+// Conveniences wrapper for simple listener hooks
+int HRegisterListener(int hookid, mixed consumer)
+{
+  return HRegisterToHook(hookid, consumer, H_HOOK_OTHERPRIO(2), H_LISTENER, 0);
+}
+
+// Cnveniences wrapper for simple modificator hooks
+int HRegisterModifier(int hookid, mixed consumer)
+{
+  return HRegisterToHook(hookid, consumer, H_HOOK_OTHERPRIO(2),
+                         H_HOOK_MODIFICATOR, 0);
+}
+
+// surveyors are asked for cancellation permittance
+protected int askSurveyorsForCancelAllowance(mixed surveyors,
+  object modifiyingOb,mixed data,int hookid,int prio,object hookOb){
+
+  foreach(struct hook_entry_s surveyor : surveyors) {
+    if (closurep(surveyor->cl) && surveyor->endtime >= time())
+    {
+      // surveyor hook gueltig.
+      object sob = GET_OBJECT(surveyor->cl);
+      if (!sob->HookCancelAllowanceCallback(modifiyingOb, hookid,
+                        hookOb, prio, data))
+        return 0;
+    }
+  }
+  return 1;
+}
+
+// surveyors are asked for data change permittance
+protected int askSurveyorsForModificationAllowance(mixed surveyors,
+  object modifiyingOb,mixed data,int hookid,int prio,object hookOb){
+
+  foreach(struct hook_entry_s surveyor : surveyors) {
+    if (closurep(surveyor->cl) && surveyor->endtime >= time())
+    {
+      // surveyor hook gueltig.
+      object sob = GET_OBJECT(surveyor->cl);
+      if (!sob->HookModificationAllowanceCallback(modifiyingOb,
+                        hookid, hookOb, prio, data))
+        return 0;
+    }
+  }
+  return 1;
+}
+
+protected mixed HookFlow(int hookid, mixed hookdata){
+  mixed tmp, ret;
+
+  ret=({H_NO_MOD,hookdata});
+
+  H_DMSG(sprintf("HookFlow hookid %d hookdata %O\n",hookid,hookdata));
+
+  if (!member(hookMapping, hookid))
+    return ret;
+
+  struct hook_s hook = hookMapping[hookid];
+
+  // notify surveyors
+  foreach(struct hook_entry_s h : hook->surveyors) {
+    if (closurep(h->cl) && h->endtime >= time())
+    {
+      // Hook gueltig
+      tmp = funcall(h->cl, this_object(), hookid, ret[H_RETDATA]);
+      if(tmp[H_RETCODE]==H_CANCELLED) {
+        ret[H_RETCODE]=H_CANCELLED;
+        return ret;  // und weg...
+      }
+      else if(tmp[H_RETCODE]==H_ALTERED){
+        ret[H_RETCODE]=H_ALTERED;
+        ret[H_RETDATA]=tmp[H_RETDATA];
+      }
+    }
+    // ungueltige/abgelaufene Eintraege -> Aufraeumen, aber nicht jetzt.
+    else if (find_call_out(#'CleanHookMapping) == -1) {
+      call_out(#'CleanHookMapping, 0, ({hookid}));
+    }
+  } // surveyors fertig
+
+  // notify hmods
+  foreach(struct hook_entry_s h : hook->hmods) {
+    if (closurep(h->cl) && h->endtime >= time())
+    {
+      // Hook gueltig
+      tmp = funcall(h->cl, this_object(), hookid, ret[H_RETDATA]);
+      if(tmp[H_RETCODE]==H_CANCELLED) {
+        // ask allowance in surveyors
+        if(h->cl &&
+           askSurveyorsForCancelAllowance(hook->surveyors,
+              GET_OBJECT(h->cl), hookdata, hookid,
+              h->prio, this_object()))
+        {
+            ret[H_RETCODE] = H_CANCELLED;
+            return ret; // und raus...
+        }
+      }
+      else if(tmp[H_RETCODE]==H_ALTERED) {
+        // ask allowance in surveyors
+        if(h->cl &&
+           askSurveyorsForModificationAllowance(hook->surveyors,
+              GET_OBJECT(h->cl),hookdata, hookid,
+              h->prio,this_object()))
+        {
+            ret[H_RETCODE] = H_ALTERED;
+            ret[H_RETDATA] = tmp[H_RETDATA];
+        }
+      }
+    }
+    // ungueltige/abgelaufene Eintraege -> Aufraeumen, aber nicht jetzt.
+    else if (find_call_out(#'CleanHookMapping) == -1) {
+      call_out(#'CleanHookMapping, 0, ({hookid}));
+    }
+  } // hmods fertig
+
+  // notify dmods
+  foreach(struct hook_entry_s h : hook->dmods) {
+    if (closurep(h->cl) && h->endtime >= time())
+    {
+      // Hook gueltig
+      tmp = funcall(h->cl, this_object(), hookid, ret[H_RETDATA]);
+      if(tmp[H_RETCODE]==H_ALTERED) {
+        // ask allowance in surveyors
+        if (h->cl &&
+            askSurveyorsForModificationAllowance(hook->surveyors,
+              GET_OBJECT(h->cl),hookdata, hookid,
+              h->prio,this_object()))
+        {
+            ret[H_RETCODE] = H_ALTERED;
+            ret[H_RETDATA] = tmp[H_RETDATA];
+        }
+      }
+    }
+    // ungueltige/abgelaufene Eintraege -> Aufraeumen, aber nicht jetzt.
+    else if (find_call_out(#'CleanHookMapping) == -1) {
+      call_out(#'CleanHookMapping, 0, ({hookid}));
+    }
+  } // dmods fertig
+
+  // notify listener
+  foreach(struct hook_entry_s h : hook->listeners) {
+    if (closurep(h->cl) && h->endtime >= time())
+    {
+      // Hook gueltig
+      funcall(h->cl, this_object(), hookid, ret[H_RETDATA]);
+    }
+    // ungueltige/abgelaufene Eintraege -> Aufraeumen, aber nicht jetzt.
+    else if (find_call_out(#'CleanHookMapping) == -1) {
+      call_out(#'CleanHookMapping, 0, ({hookid}));
+    }
+  } // listener fertig
+
+  return ret;
+}
+
