diff --git a/obj/tools/merkzettel/merkzettel.c b/obj/tools/merkzettel/merkzettel.c
new file mode 100644
index 0000000..70447ab
--- /dev/null
+++ b/obj/tools/merkzettel/merkzettel.c
@@ -0,0 +1,1130 @@
+/*  /obj/tools/merkzettel.c
+    Merkzettel fuer Magier
+    Autor: Zesstra
+    ggf. Changelog:
+*/
+#pragma strict_types
+#pragma no_shadow
+#pragma range_check
+#pragma pedantic
+
+inherit "/std/secure_thing";
+
+#include <properties.h>
+#include <language.h>
+#include <wizlevels.h>
+#include <moving.h>
+#include <defines.h>
+
+#define NEED_PROTOTYPES
+#include "merkzettel.h"
+#undef NEED_PROTOTYPES
+
+//Variablen
+mapping notizen;
+//mapping notizen_inaktiv;
+int maxusedID;
+static string owner; //UID des Besitzers, wird in P_AUTOLOAD gespeichert
+//static int *cache; //nach Prioritaet sortiertes Array der IDs
+
+void create() {
+  ::create();
+  SetProp(P_NAME, "Merkzettel");
+  SetProp(P_SHORT, "Ein Merkzettel");
+  AddId(({"merkzettel","zettel"}));
+  //Absicht, damit die Blueprint eine ID, P_NAME und P_SHORT hat.
+  if(!clonep(this_object())) return;
+  
+  SetProp(P_LONG,
+  "Was wolltest Du gleich nochmal schoenes proggen? ;-)\n"
+  "Befehlsliste:\n"
+  "zmerke/znotiz <string>  : Etwas auf den Merkzettel schreiben\n"
+  "zliste                  : 20 wichtigsten Notizen anzeigen\n"
+  "zliste <int>            : <int> wichtigste Notizen anzeigen\n"
+  "                          (unwichtigste, wenn <int> negativ)\n"
+  "                          Angabe von 0 oder 'alle' gibt alle aus\n"
+  "zliste <int> <filter>   : <int> wichtigste Notizen anzeigen\n"
+  "                          (Filter: 'aktiv', 'wartend'\n"
+  "                           'inaktiv', 'abgehakt', 'alle'|'0')\n"
+  "                          Ohne Angabe eines Filter gilt 'aktiv'\n"
+  "zstatus <int>           : Status von Notiz mit ID umschalten\n"
+  "zstatus <int> <int2>    : Status von Notiz mit ID auf <int> setzen \n"
+  "zloesche/zrm <int>      : Notiz mit ID <int> loeschen\n"
+  "zlies/zlese <int>       : Notiz mit ID <int> anzeigen\n"
+  "zdeplies <int> <int2>   : Abhaengigkeiten von <int> lesen, \n"
+  "                        : rekursiv, wenn <int2> != 0\n"
+  "zfertig/zhake <int>     : Notiz mit ID <int> abhaken (fertig)\n"
+  "zprio <int1> <int2>     : Notiz mit ID <int> mit Prioritaet <int2>\n"
+  "                          versehen.\n"
+  "zdep <int1> <int2>      : Notiz mit ID <int> soll von Notiz mit ID\n"
+  "                          <int2> abhaengen.\n"
+  "zhelfer <int1> <namen>  : Notiz mit ID <int> wird (mit)bearbeitet\n"
+  "                          von den angegebenen Personen\n"
+  "zergaenze <int> <text>  : haengt <text> an Notiz <int> an\n"
+  "zersetze <int> <text>   : ersetzt Text von Notiz <int> durch <text>\n"
+  "zexpire <int>           : alle abgehakten Notizen archivieren und loeschen,\n"
+  "                        : die aelter als <int> Tage sind.\n"
+  "zzeige <name>           ; zeige <name>, wie furchtbar viel Du zu tun hast\n"
+  "zwedel <name>	   : <name> aus der Ferne vor der Nase rumwedeln.\n"
+  );
+  SetProp(P_INFO,break_string("Ein Merkzettel fuer Magier. ;-)."));
+  SetProp(P_GENDER, MALE);
+  SetProp(P_ARTICLE, 1);
+  SetProp(P_WEIGHT, 0);
+  SetProp(P_VALUE, 0);
+  Set(P_AUTOLOADOBJ,#'query_autoloadobj,F_QUERY_METHOD);
+  Set(P_AUTOLOADOBJ,#'set_autoloadobj,F_SET_METHOD);
+  Set(P_AUTOLOADOBJ,PROTECTED,F_MODE_AS);
+  SetProp(P_NEVERDROP,1);
+  SetProp(P_NODROP,1);
+  AddCmd(({"zmerke","znotiz"}),"AddNotiz");
+  AddCmd(({"zliste","ztodo"}),"ListNotizen");
+  AddCmd(({"zloesche","zrm"}),"RemoveNotiz");
+  AddCmd(({"zfertig","zhake"}),"FinishNotiz");
+  AddCmd(({"zlies","zlese"}),"LiesNotiz");
+  AddCmd(({"zprio"}),"ChangePrio");
+  AddCmd(({"zdep"}),"ChangeDep");
+  AddCmd(({"zstatus"}),"ChangeStatus");
+  AddCmd(({"zersetze"}),"ErsetzeText");
+  AddCmd(({"zergaenze"}),"ErgaenzeText");
+  AddCmd(({"zhelfer","zdelegiere"}),"ChangeHelper");
+  AddCmd(({"zzeige"}),"ZeigeZettel");
+  AddCmd(({"zwedel"}),"WedelZettel");
+  AddCmd(({"zdeplies"}),"LiesDeps");
+  AddCmd(({"zexpire"}),"Expire");
+  //cache=({});
+  
+}
+
+//****************** AddCmd *****************************
+int AddNotiz(string str) {
+  
+  if(!objectp(TI)) return(0);
+  if(!check_allowed()) {
+    if(objectp(this_interactive()))
+      tell_object(this_interactive(),
+        BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
+    return(0);
+  }
+  //ggf. nur Einlesen, Cache muss hier nicht aktualisiert werden ;-)
+  checkStatus(1);
+  str=(string)PL->_unparsed_args(0);  //kein parsing
+  if (!stringp(str) || !sizeof(str)) {
+    tell_object(PL,
+      "Was moechtest Du Dir denn notieren?\n");
+    return(1);
+  }
+  if (sizeof(str)>MAX_NOTE_LENGTH) {
+    tell_object(PL,BS(
+      sprintf("Deine Notiz ist mit %d Zeichen zu lang! Leider passen auf "
+             "Deinen Merkzettel nur % Zeichen drauf.",
+        sizeof(str),MAX_NOTE_LENGTH)));
+    return(1);
+  }
+  
+  //m_allocate gilt nur bis Funktionsende, daher hilft das in
+  //checkStatus leider nicht.
+  if (!mappingp(notizen) || !sizeof(notizen))
+    notizen=m_allocate(0,7);
+  
+  //freie ID finden (maxusedID+1 sollte die naechste frei sein, aber falls
+  //da mal was kaputtgegangen ist: Pruefen ;-) )
+  while(member(notizen,maxusedID)) {maxusedID++;}
+  //Reihenfolge: s. merkzettel.h
+  notizen+=([maxusedID:str;0;time();({});({});NOTE_ACTIVE;0]);
+/*  notizen+=([maxusedID]);
+  notizen[maxusedID,NOTE_TEXT]=str;
+  notizen[maxusedID,NOTE_PRIO]=0;
+  notizen[maxusedID,NOTE_STARTTIME]=time();
+  notizen[maxusedID,NOTE_DEPS]=({});
+*/
+  
+  //cache=({}); //cache invalidieren
+  //in Kuerze speichern, aber nicht fuer jede Aenderung speichern
+  save_me(60);
+  tell_object(PL,BS(
+      sprintf("Du schreibst sorgfaeltig Deine Notiz auf Deinen Merkzettel. "
+          "Es ist nun die %d. Notiz.",maxusedID)));
+  tell_room(environment(TI),
+    BS(sprintf("%s notiert sich etwas auf %s Merkzettel.\n",
+        capitalize((string)TI->name(WER)),
+        (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem") 
+              )),({TI}));
+  return(1);
+}
+
+int LiesNotiz(string str) {
+  int id;
+  
+  if(!objectp(TI)) return(0);
+  if(!check_allowed()) {
+    if(objectp(this_interactive()))
+      tell_object(this_interactive(),
+        BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
+    return(0);
+  }
+  if (!stringp(str) || !sizeof(str) || !id=to_int(str)) {
+    tell_object(PL,
+      "Welche Notiz moechtest Du lesen? Bitte eine ID angeben!\n");
+    return(1);
+  }
+  if (!checkStatus()) {
+    tell_object(PL,
+      "Es gibt keine Notiz, die Du lesen koenntest!\n");
+    return(1);
+  }
+  if (!member(notizen,id)) {
+    tell_object(PL,
+      sprintf("Es gibt keine Notiz mit der ID: %d\n",id));
+    return(1);
+  }
+  //Ausgabetext holen und ausgeben
+  tell_object(PL,sprintf("\nDu vertiefst Dich in Deinen Merkzettel und liest:\n%s\n",_LiesNotiz(id)));
+  tell_room(environment(TI),
+    BS(sprintf("%s liest etwas auf %s Merkzettel.\n",
+        capitalize((string)TI->name(WER)),
+        (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem") 
+              )),({TI}));
+  return(1);
+}
+
+int RemoveNotiz(string str) {
+  int id;
+  
+  if(!objectp(TI)) return(0);
+  if(!check_allowed()) {
+    if(objectp(this_interactive()))
+      tell_object(this_interactive(),
+        BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
+    return(0);
+  }
+  if (!stringp(str) || !sizeof(str) || !id=to_int(str)) {
+    tell_object(PL,
+      "Welche Notiz moechtest Du ausradieren? Bitte eine ID angeben!\n");
+    return(1);
+  }
+  if (!checkStatus()) {
+    tell_object(PL,
+      "Es gibt keine Notiz, die Du ausradieren koenntest!\n");
+    return(1);
+  }
+  if (!member(notizen,id)) {
+    tell_object(PL,
+      sprintf("Es gibt keine Notiz mit der ID: %d\n",id));
+    return(1);
+  }
+  //direkt Loeschen, keine Kopie, daher m_delete()
+  m_delete(notizen,id);
+  //in Kuerze speichern, aber nicht fuer jede Aenderung speichern
+  save_me(60);
+  //cache invalidieren
+  //cache=({});
+  tell_object(PL,
+    sprintf("Sorgfaeltig radierst Du Notiz %d von Deinem Merkzettel.\n",
+           id));
+  tell_room(environment(TI),
+    BS(sprintf("%s radiert sorgfaeltig etwas von %s Merkzettel.\n",
+        capitalize((string)TI->name(WER)),
+        (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem") 
+              )),({TI}));
+  return(1);
+}
+
+int FinishNotiz(string str) {
+  int id;
+  mixed liste;
+  if(!objectp(TI)) return(0);
+  if(!check_allowed()) {
+    if(objectp(this_interactive()))
+      tell_object(this_interactive(),
+        BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
+    return(0);
+  }
+  if (!stringp(str) || !sizeof(str) || !id=to_int(str)) {
+    tell_object(PL,
+      "Welche Notiz moechtest Du abhaken? Bitte eine ID angeben!\n");
+    return(1);
+  }
+  if (!checkStatus()) {
+    tell_object(PL,
+      "Es gibt keine Notiz, die Du abhaken koenntest!\n");
+    return(1);
+  }
+  if (!member(notizen,id)) {
+    tell_object(PL,
+      sprintf("Es gibt keine Notiz mit der ID: %d\n",id));
+    return(1);
+  }
+  if(notizen[id,NOTE_STATUS]==NOTE_FINISHED) {
+    tell_object(PL,
+      sprintf("Notiz %d ist schon abgehakt!\n",id));
+    return(1);
+  }
+  liste=getUnresolvedDeps(id);  //liste ist Array von ints
+  if (sizeof(liste)) {
+    liste=map(liste,#'to_string);  //liste ist Array von strings
+    tell_object(PL,BS(sprintf("Du kannst Notiz %d nicht abhaken, da noch "
+        "nicht erledigte Abhaengigkeiten existieren. IDs: %s.",
+        id,CountUp(liste))));
+    return(1); 
+  }
+  notizen[id,NOTE_STATUS]=NOTE_FINISHED;
+  notizen[id,NOTE_CLOSETIME]=time();
+  tell_object(PL,BS(
+    sprintf("Du malst zufrieden einen schoenen grossen Haken hinter "
+        "die Notiz Nr. %d. Hach - was bist Du nun zufrieden! :-)\n",id)));
+  tell_room(environment(TI),
+    BS(sprintf("%s hakt erfreut etwas auf %s Merkzettel ab.\n",
+        capitalize((string)TI->name(WER)),
+        (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem") 
+              )),({TI}));
+  return(1);
+}
+
+int ListNotizen(string str) {
+  int zahl,notizzahl,i,id,filterstate;
+  string txt;
+  string *arr;
+  status invers;
+  
+  if(!objectp(TI)) return(0);
+  str=(string)PL->_unparsed_args(0);
+  if(!check_allowed()) {
+    if(objectp(this_interactive()))
+      tell_object(this_interactive(),
+        BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
+    return(0);
+  }
+  if (!notizzahl=checkStatus()) {
+    tell_object(PL,BS(
+      "Dein Merkzettel ist bluetenweiss und leer! Wie kommt das denn?? "
+      "Hast Du nix zu tun?"));
+    return(1);
+  }
+  //Argumente parsen
+  if(stringp(str) && sizeof(str))
+    arr=explode(str," ");
+  if (pointerp(arr)) arr-=({""}); //doppelte leerzeichen im String
+  if (pointerp(arr) && sizeof(arr)>=2) {
+    zahl=to_int(arr[0]);
+    switch(arr[1]) {
+      case "aktiv":
+        filterstate=NOTE_ACTIVE; break;
+      case "inaktiv":
+        filterstate=NOTE_INACTIVE; break;
+      case "wartend":
+      case "pending":
+        filterstate=NOTE_PENDING; break;
+      case "abgehakt":
+      case "fertig":
+      case "abgeschlossen":
+        filterstate=NOTE_FINISHED; break;
+      case "alle":
+        filterstate=0; break;
+      default: 
+        filterstate=to_int(arr[1]);
+        break;
+    }
+  }
+  else if (pointerp(arr) && sizeof(arr)==1) {
+    zahl=to_int(arr[0]);
+    filterstate=NOTE_ACTIVE;
+  }
+  else {
+    //Voreinstellungen
+    zahl=20;
+    filterstate=NOTE_ACTIVE;
+  }
+  //1. Argument "all" oder "alle" ist: alle anzeigen
+  if (pointerp(arr) && sizeof(arr) && stringp(arr[0]) &&
+      sizeof(arr[0]) && arr[0]=="alle")
+    zahl=notizzahl;  //alle anzeigen
+  
+  //wenn die gewuenschte Zahl die Anzahl gespeicherter
+  //Notizen ueberschreitet (oder 0 ist)
+  if(!zahl || zahl>notizzahl) zahl=notizzahl;
+  
+  //wenn 1. Argument negativ: Liste in umgekehrter Reihenfolge
+  if (zahl<0) {
+    invers=1;
+    zahl=zahl*-1;
+  }
+  txt=sprintf("\n|%:9|s|%:56|s|%:7|s|\n","ID","Notiztext","Prio.");
+  txt+=sprintf("%:78'-'s\n","-");
+  //alle passenden Notizen ermitteln
+  arr=filter(m_indices(notizen),#'note_filter,filterstate);
+  //sortieren
+  arr=sort_array(arr,#'sort_prio);
+  if (zahl>sizeof(arr)) zahl=sizeof(arr);
+  //ausgeben
+  for(i=0;i<zahl;i++) {
+    if (!invers)
+      id=to_int(arr[i]);
+    else
+      //von hinten
+      id=to_int(arr[<i+1]); // i+1 ist wirklich Absicht. ;-)
+    txt+=sprintf("| %:7|d | %:54-s | %:5|d |\n",
+            id,
+	    //nur bis zum ersten \n anzeigen
+	    explode(notizen[id,NOTE_TEXT],"\n")[0],
+            notizen[id,NOTE_PRIO]);
+  }
+  txt+=sprintf("%:78'-'s\n\n","-");
+  tell_object(PL,txt);
+  tell_room(environment(TI),
+    BS(sprintf("%s wirft einen Blick auf %s Merkzettel.\n",
+        capitalize((string)TI->name(WER)),
+        (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihren" : "seinen") 
+              )),({TI}));
+  return(1);
+}
+
+int ChangeDep(string str) {
+  int id;
+  string *arr;
+  int *deps;
+  
+  notify_fail("Bitte eine ID und eine min. eine Abhaengigkeit angeben!\n");
+  if(!objectp(TI)) return(0);
+  if(!check_allowed()) {
+    if(objectp(this_interactive()))
+      tell_object(this_interactive(),
+        BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
+    return(0);
+  }
+  str=(string)PL->_unparsed_args(0);
+  if (!stringp(str) || !sizeof(str))
+    return(0);
+  
+  if (!checkStatus()) {
+    tell_object(PL,BS(
+      "Dein Merkzettel ist bluetenweiss und leer! Wie kommt das denn?? "
+      "Hast Du nix zu tun?"));
+    return(1);
+  }
+  arr=explode(str," ");
+  arr-=({""});  // "" entfernen, wichtig. ;-)
+  if (sizeof(arr)<2)
+    return(0);
+  id=to_int(arr[0]);
+  arr-=({arr[0]});  //eigene ID loeschen
+  if (sizeof(arr)<1)
+    return(0);  //mehrfach die eigene ID gilt nicht.;-)
+  if (!member(notizen,id)) {
+    tell_object(PL,
+      sprintf("Es gibt keine Notiz mit der ID: %d\n",id));
+    return(1);
+  }
+  //dies updated direkt die Abhaengigkeiten in 'notizen'!
+  map(arr,#'update_deps,id);
+  save_me(60);
+  tell_object(PL,BS(
+      sprintf("Du aenderst die Abhaengigkeiten von Notiz %d.\n",
+              id)));
+  tell_room(environment(TI),
+    BS(sprintf("%s kritzelt auf %s Merkzettel herum.\n",
+        capitalize((string)TI->name(WER)),
+        (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem") 
+              )),({TI}));
+  return(1);
+}
+
+int ChangePrio(string str) {
+  int id, prio;
+  string* arr;
+  
+  notify_fail("Bitte eine ID und eine neue Prioritaet angeben!\n");
+  if(!objectp(TI)) return(0);
+  if(!check_allowed()) {
+    if(objectp(this_interactive()))
+      tell_object(this_interactive(),
+        BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
+    return(0);
+  }
+  str=(string)PL->_unparsed_args(0);
+  if (!stringp(str) || !sizeof(str))
+    return(0);
+  
+  if (!checkStatus()) {
+    tell_object(PL,BS(
+      "Dein Merkzettel ist bluetenweiss und leer! Wie kommt das denn?? "
+      "Hast Du nix zu tun?"));
+    return(1);
+  }
+  arr=explode(str," ");
+  if (sizeof(arr)>2) {
+    notify_fail("Bitte nur eine ID und eine neue Prioritaet angeben!");
+    return(0);
+  }
+  else if(sizeof(arr)==2) {
+    id=to_int(arr[0]);
+    prio=to_int(arr[1]);
+  }
+  else
+    return(0);
+
+  if (!member(notizen,id)) {
+    tell_object(PL,
+      sprintf("Es gibt keine Notiz mit der ID: %d\n",id));
+    return(1);
+  }
+  notizen[id,NOTE_PRIO]=prio;
+  //cache=({}); //cache invalidieren
+  save_me(60);
+  tell_object(PL,BS(
+      sprintf("Du aenderst die Prioritaet von Notiz %d auf %d.",
+              id,notizen[id,NOTE_PRIO])));
+  tell_room(environment(TI),
+    BS(sprintf("%s kritzelt auf %s Merkzettel herum.\n",
+        capitalize((string)TI->name(WER)),
+        (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem") 
+              )),({TI}));
+  return(1);
+}
+
+int ChangeHelper(string str) {
+  int id;
+  string *arr;
+  
+  notify_fail("Bitte eine ID und eine min. einen Namen angeben!\n");
+  if(!objectp(TI)) return(0);
+  if(!check_allowed()) {
+    if(objectp(this_interactive()))
+      tell_object(this_interactive(),
+        BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
+    return(0);
+  }
+  str=(string)PL->_unparsed_args(0);
+  if (!stringp(str) || !sizeof(str))
+    return(0);
+  
+  if (!checkStatus()) {
+    tell_object(PL,BS(
+      "Dein Merkzettel ist bluetenweiss und leer! Wie kommt das denn?? "
+      "Hast Du nix zu tun?"));
+    return(1);
+  }
+  arr=explode(str," ");
+  arr-=({""});  // "" entfernen, wichtig. ;-)
+  if (sizeof(arr)<2)
+    return(0);
+  id=to_int(arr[0]);
+  arr-=({arr[0]});  //eigene ID loeschen
+  if (sizeof(arr)<1)
+    return(0);  //mehrfach die eigene ID gilt nicht.;-)
+  if (!member(notizen,id)) {
+    tell_object(PL,
+      sprintf("Es gibt keine Notiz mit der ID: %d\n",id));
+    return(1);
+  }
+  notizen[id,NOTE_HELPER]=arr;
+  save_me(60);
+  tell_object(PL,BS(
+      sprintf("Mitarbeiter von Notiz %d geaendert.",id)));
+  tell_room(environment(TI),
+    BS(sprintf("%s kritzelt auf %s Merkzettel herum.\n",
+        capitalize((string)TI->name(WER)),
+        (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem") 
+              )),({TI}));
+  return(1);
+}
+
+int ChangeStatus(string str) {
+  int id, state;
+  string *arr;
+  
+  notify_fail(BS(
+      "Bitte min. eine ID angeben, um den Status umzuschalten oder "
+      "eine ID und den neuen Status (1==Aktiv, 2==Wartend, "
+      "-1==Inaktiv/Pause)"));
+  if(!objectp(TI)) return(0);
+  if(!check_allowed()) {
+    if(objectp(this_interactive()))
+      tell_object(this_interactive(),
+        BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
+    return(0);
+  }
+  str=(string)PL->_unparsed_args(0);
+  if (!stringp(str) || !sizeof(str))
+    return(0);
+  if (!checkStatus()) {
+    tell_object(PL,BS(
+      "Dein Merkzettel ist bluetenweiss und leer! Wie kommt das denn?? "
+      "Hast Du nix zu tun?"));
+    return(1);
+  }
+  arr=explode(str," ");
+  if (sizeof(arr)>2) {
+    notify_fail("Bitte nur eine ID und einen neuen Status angeben!");
+    return(0);
+  }
+  else if(sizeof(arr)==2) {
+    id=to_int(arr[0]);
+    state=to_int(arr[1]);
+  }
+  else if(sizeof(arr)==1) {
+    id=to_int(arr[0]);
+  }
+  else
+    return(0);
+  
+  if (!member(notizen,id)) {
+    tell_object(PL,
+      sprintf("Es gibt keine Notiz mit der ID: %d\n",id));
+    return(1);
+  }
+  if(member(NOTE_STATES,state)==-1) {
+    if (notizen[id,NOTE_STATUS]==NOTE_ACTIVE) {
+      tell_object(PL,BS(
+          sprintf("%d ist ein unbekannter Status, setzt Notiz %d auf "
+              "'Inaktiv'.",state,id)));
+      state=NOTE_INACTIVE;
+    }
+    else {
+      tell_object(PL,BS(
+          sprintf("%d ist ein unbekannter Status, setzt Notiz %d auf "
+              "'Aktiv'.",state,id)));
+      state=NOTE_ACTIVE;
+    }
+  }
+  notizen[id,NOTE_STATUS]=state;
+  save_me(60);
+  tell_object(PL,BS(
+      sprintf("Status von Notiz %d geaendert.",id)));
+  tell_room(environment(TI),
+    BS(sprintf("%s kritzelt auf %s Notizzettel herum.\n",
+        capitalize((string)TI->name(WER)),
+        (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem") 
+              )),({TI}));
+  return(1);
+}
+
+int ErsetzeText(string str) {
+  string *arr;
+  int id;
+  
+  notify_fail("Bitte eine ID und einen neuen Text angeben!\n");
+  if(!objectp(TI)) return(0);
+  
+  if(!check_allowed()) {
+    if(objectp(this_interactive()))
+      tell_object(this_interactive(),
+        BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
+    return(0);
+  }
+  str=(string)PL->_unparsed_args(0);
+  if (!stringp(str) || !sizeof(str))
+    return(0);
+  
+  if (!checkStatus()) {
+    tell_object(PL,BS(
+      "Dein Merkzettel ist bluetenweiss und leer! Wie kommt das denn?? "
+      "Hast Du nix zu tun?"));
+    return(1);
+  }
+  arr=explode(str," ");
+  arr-=({""});  // "" entfernen
+  if (sizeof(arr)<2)
+    return(0);
+  id=to_int(arr[0]);
+  str=implode(arr[1..]," ");  //text wiederherstellen, ohne erstes Element
+  if (!sizeof(str)) return(0);
+  if (!member(notizen,id)) {
+    tell_object(PL,
+      sprintf("Es gibt keine Notiz mit der ID: %d\n",id));
+    return(1);
+  }
+  notizen[id,NOTE_TEXT]=str;
+  save_me(60);
+  tell_object(PL,BS(
+      sprintf("Text von Notiz %d ersetzt.",id)));
+  tell_room(environment(TI),
+    BS(sprintf("%s radiert zuerst etwas auf %s Notizzettel herum und "
+        "schreibt anschliessend sorgfaeltig etwas neues auf.\n",
+        capitalize((string)TI->name(WER)),
+        (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem") 
+              )),({TI}));
+  return(1);
+}
+
+int ErgaenzeText(string str) {
+  string *arr;
+  int id;
+  
+  notify_fail("Bitte eine ID und einen Text angeben!\n");
+  if(!objectp(TI)) return(0);
+  if(!check_allowed()) {
+    if(objectp(this_interactive()))
+      tell_object(this_interactive(),
+        BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
+    return(0);
+  }
+  str=(string)PL->_unparsed_args(0);
+  if (!stringp(str) || !sizeof(str))
+    return(0);
+  
+  if (!checkStatus()) {
+    tell_object(PL,BS(
+      "Dein Merkzettel ist bluetenweiss und leer! Wie kommt das denn?? "
+      "Hast Du nix zu tun?"));
+    return(1);
+  }
+  arr=explode(str," ");
+  arr-=({""});  // "" entfernen
+  if (sizeof(arr)<2)
+    return(0);
+  id=to_int(arr[0]);
+  str="\n";
+  str+=implode(arr[1..]," ");  //text wiederherstellen
+  if (!member(notizen,id)) {
+    tell_object(PL,
+      sprintf("Es gibt keine Notiz mit der ID: %d\n",id));
+    return(1);
+  }
+  notizen[id,NOTE_TEXT]+=str;
+  save_me(60);
+  tell_object(PL,BS(
+      sprintf("Text von Notiz %d ergaenzt.",id)));
+  tell_room(environment(TI),
+    BS(sprintf("%s ergaenzt etwas auf %s Notizzettel.\n",
+        capitalize((string)TI->name(WER)),
+        (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem") 
+              )),({TI}));
+  return(1);
+}
+
+int ZeigeZettel(string str) {
+    //anderen zeigen, wie furchtbar viel man zu tun hat.
+  object pl;
+  int count;
+  int *ids;
+  
+  notify_fail("Wem willst Du Deinen Merkzettel zeigen?\n");
+  if (!objectp(TI)) return(0);
+  if (!environment() || !environment(environment()))
+     return(0);
+  if (!stringp(str) || !sizeof(str)) return(0);
+  if(!check_allowed()) {
+    if(objectp(this_interactive()))
+      tell_object(this_interactive(),
+        BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
+    return(0);
+  }
+ if (!checkStatus()) {
+    tell_object(PL,BS(
+      "Dein Merkzettel ist bluetenweiss und leer! Wie kommt das denn?? "
+      "Hast Du nix zu tun? Du willst anderen Leuten doch bestimmt nicht "
+      "zeigen, dass Du nix zu tun hast, oder?"));
+    return(1);
+  }
+ if(!objectp(pl=present(str,environment(environment()))))
+     return(0);
+ if (!living(pl))
+     return(0);
+
+ ids=filter(m_indices(notizen),#'note_filter,NOTE_ACTIVE);
+ tell_object(TI,BS("Du zeigst "+pl->Name(WEM)+" voller Stolz deinen vollen "
+       "Merkzettel."));
+ tell_room(environment(environment()),BS(sprintf(
+	 "%s zeigt %s %s Merkzettel.",
+       TI->Name(WER),pl->Name(WEM),TI->QueryPossPronoun(MALE,WEN,SINGULAR))),
+     ({TI,pl}));
+ switch(sizeof(ids)) {
+     case 0..10:
+       tell_object(pl,BS(sprintf("%s zeigt Dir voller Stolz %s Merkzettel. Du "
+	       "wirfst einen schnellen Blick darueber und zaehlst %d "
+	       "Notizen. Na, soviel ist das ja zum Glueck noch nicht.",
+	       TI->Name(WER),TI->QueryPossPronoun(MALE,WEN,SINGULAR),
+	       sizeof(ids))));
+       break;
+    case 11..20:
+        tell_object(pl,BS(sprintf("%s zeigt Dir voller Stolz %s Merkzettel. Du "
+	       "wirfst einen schnellen Blick darueber und zaehlst %d "
+	       "Notizen. Oh, das ist ja schon so einiges!",
+	       TI->Name(WER),TI->QueryPossPronoun(MALE,WEN,SINGULAR),
+	       sizeof(ids))));
+       break;
+    default:
+        tell_object(pl,BS(sprintf("%s zeigt Dir voller Stolz %s Merkzettel. Du "
+	       "wirfst einen schnellen Blick darueber und zaehlst %d "
+	       "Notizen. Puuuh. %s hat ganz schoen viel zu tun! In "
+	       "Dir regt sich leises Mitleid.",
+	       TI->Name(WER),TI->QueryPossPronoun(MALE,WEN,SINGULAR),
+	       sizeof(ids),TI->Name(WER) )));
+       break;
+ }
+ return(1);
+ }
+
+int WedelZettel(string str) {
+    object pl;
+    string rwedel;
+  //wedelt anderen mit dem Zettel vor der Nase herum.
+  notify_fail("Wem willst Du Deinen Merkzettel zeigen?\n");
+  if (!objectp(TI)) return(0);
+  if (!environment() || !environment(environment()))
+     return(0);
+  if (!stringp(str) || !sizeof(str)) return(0);
+  if(!check_allowed()) {
+    if(objectp(this_interactive()))
+      tell_object(this_interactive(),
+        BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
+    return(0);
+  }
+  if (!objectp(pl=find_player(str))) return(0);
+  if (!present(pl,environment(environment())))
+    rwedel="aus der Ferne";
+      
+  tell_object(PL,BS("Du wedelst "+pl->Name(WEM) 
+	+ (rwedel?" "+rwedel:"") 
+	+" heftig mit Deinem Merkzettel vor der Nase herum."));
+  tell_object(pl,BS(PL->Name(WER)+ " wedelt Dir " 
+	+ (rwedel?rwedel+" ":"") +"heftig mit "
+	+PL->QueryPossPronoun(MALE,WEM,SINGULAR)
+	+" Merkzettel vor der Nase herum."));
+  tell_room(environment(pl),BS(PL->Name(WER) + " wedelt "
+	+pl->Name(WEM) + (rwedel?" "+rwedel:"") + " heftig mit "
+       +PL->QueryPossPronoun(MALE,WEM,SINGULAR)
+       +" Merkzettel vor der Nase herum."),({PL,pl}));
+  return(1);
+}
+
+int LiesDeps(string str) {
+  //erstmal (rekursiv) alle Abhaengigkeiten einer Notiz ermitteln
+  string *arr;
+  int id, rec, i;
+  int *liste;
+  
+  notify_fail("Bitte eine ID und ggf. '1' fuer rekursive Suche angeben!\n");
+  if(!objectp(TI)) return(0);
+  if(!check_allowed()) {
+    if(objectp(this_interactive()))
+      tell_object(this_interactive(),
+        BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
+    return(0);
+  }
+  str=(string)PL->_unparsed_args(0);
+  if (!stringp(str) || !sizeof(str))
+    return(0);
+  
+  if (!checkStatus()) {
+    tell_object(PL,BS(
+      "Dein Merkzettel ist bluetenweiss und leer! Wie kommt das denn?? "
+      "Hast Du nix zu tun?"));
+    return(1);
+  }
+  arr=explode(str," ");
+  arr-=({""});  // "" entfernen
+  if (sizeof(arr)==1) {
+    id=to_int(arr[0]);
+    rec=0;  //Standard: keine Rekursion
+  }
+  else if (sizeof(arr)>=2) {
+    id=to_int(arr[0]);
+    rec=to_int(arr[1]);
+  }
+  else {
+    return(0);
+  }
+  if (!member(notizen,id)) {
+    tell_object(PL,
+      sprintf("Es gibt keine Notiz mit der ID: %d\n",id));
+    return(1);
+  }
+  //Notizen, von denen id abhaengt, holen
+  //und nur aktive Notizen behalten
+  liste=filter(getDeps(id,rec),#'note_filter,NOTE_ACTIVE);
+  //nach Prioritaet sortieren
+  liste=sort_array(liste,#'sort_prio);
+  //dann mal ausgeben.
+  i=sizeof(liste);
+  tell_object(PL,BS(sprintf("Du vertiefst Dich in die Abhaenhigkeiten von Notiz: %d\n",id)));
+  while(i--) {
+    tell_object(PL,_LiesNotiz(liste[i])+"\n");
+  }
+  tell_room(environment(TI),
+    BS(sprintf("%s liest etwas auf %s Merkzettel.\n",
+        capitalize((string)TI->name(WER)),
+        (((int)TI->QueryProp(P_GENDER))==FEMALE ? "ihrem" : "seinem") 
+              )),({TI}));
+  return(1);    
+}
+
+int Expire(string str) {
+  float age;
+  int sekunden, i;
+  int *liste;
+  string res;
+  
+  notify_fail("Bitte angeben, wie alt zu loeschende Notizen sein sollen (in Tagen)!\n");
+  if(!objectp(TI)) return(0);
+  if(!check_allowed()) {
+    if(objectp(this_interactive()))
+      tell_object(this_interactive(),
+        BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
+    return(0);
+  }
+  str=(string)PL->_unparsed_args(0);
+  if (!stringp(str) || !sizeof(str))
+    return(0);
+  age=to_float(str);
+  if (age<=0) return(0);
+  sekunden=time() - (int)(age*86400);
+  if (!checkStatus()) {
+    tell_object(PL,BS(
+      "Dein Merkzettel ist bluetenweiss und leer! Wie kommt das denn?? "
+      "Hast Du nix zu tun?"));
+    return(1);
+  }
+  //abgehakte Notizen ermitteln
+  liste=filter(m_indices(notizen),#'note_filter,NOTE_FINISHED);
+  //Notizen ermitteln, die lang genug abgehakt sind.
+  liste=filter(liste,#'aelter_als,sekunden);
+  if (!sizeof(liste)) {
+    tell_object(PL,BS("Keine Notizen gefunden, die lang genug abgehakt sind."));
+    return(1);
+  }
+  res=sprintf("Archivierte Notizen vom %s\n\n",dtime(time()));
+  for (i=sizeof(liste);i--;) {
+    //Infos noch einmal ausgeben und loeschen
+    res+=_LiesNotiz(liste[i])+"\n";
+    m_delete(notizen,liste[i]);
+  }
+  res+="\n";
+  write_file(ARCHIVE(owner),res);
+  tell_object(PL,BS(sprintf(
+    "%d alte Notizen wurden nach %s archiviert und geloescht.",
+       sizeof(liste),ARCHIVE(owner))));
+  return(1);
+}
+
+//
+static string _LiesNotiz(int id) {
+  //Funktion verlaesst sich drauf, dass id existiert. ;-)
+  string res,txt;
+  res=BSL(sprintf("%-11s: %d","Notiz-Nr.",id));
+  res+=break_string(notizen[id,NOTE_TEXT],78,"Notiztext  : ",
+                             BS_INDENT_ONCE|BS_LEAVE_MY_LFS);
+  res+=sprintf("%-11s: %d\n","Prioritaet",notizen[id,NOTE_PRIO]);
+  //wenn nicht aktiv: Status anzeigen
+  if (notizen[id,NOTE_STATUS]!=NOTE_ACTIVE) {
+    switch(notizen[id,NOTE_STATUS]) {
+      case NOTE_INACTIVE:
+          txt="Inaktiv/Pause";
+          break;
+      case NOTE_FINISHED:
+          txt="Abgeschlossen"; 
+          break;
+      case NOTE_PENDING:
+          txt="Warte auf Rueckmeldung"; 
+          break;
+      default: txt=sprintf("%d",notizen[id,NOTE_STATUS]); break;
+    }
+    res+=sprintf("%-11s: %s\n","Status",txt);
+    //wenn abgeschlossen: Endezeit anzeigen
+    if (notizen[id,NOTE_STATUS]==NOTE_FINISHED)
+      res+=sprintf("%-11s: %s\n","Endezeit",
+                  dtime(notizen[id,NOTE_CLOSETIME]));
+  }
+  res+=sprintf("%-11s: %s\n","Merkzeit",dtime(notizen[id,NOTE_STARTTIME]));
+  //nur wenn Abhaengigkeiten: anezeigen
+  if (pointerp(notizen[id,NOTE_DEPS]) && sizeof(notizen[id,NOTE_DEPS])) {
+    txt=implode(map(notizen[id,NOTE_DEPS],#'to_string)," ");
+    res+=sprintf("%-11s: %s\n","abh. von",txt);
+  }
+  //nur wenn Helfer: anezeigen
+  if (pointerp(notizen[id,NOTE_HELPER]) && sizeof(notizen[id,NOTE_HELPER]))
+    res+=sprintf("%-11s: %s\n","Helfer",
+                implode(notizen[id,NOTE_HELPER]," "));
+  return(res);
+}
+
+//int. Helfer
+static int note_filter(int id,int filterstate) {
+    //kein filter -> passt immer
+    if (!filterstate) return(1);
+    if (member(notizen,id) &&
+    notizen[id,NOTE_STATUS]==filterstate)
+    return(1);
+    return(0);
+}
+
+static int aelter_als(int id,int zeit) {
+  //liefert 1 zurueck, wenn Schliesszeit der Notiz laenger als 'sekunden' her ist, sonst 0.
+  if (notizen[id,NOTE_CLOSETIME]<zeit) return(1);
+  return(0);
+}
+
+static string update_deps(string str,int id) {
+  //wandelt str nach int um
+  //schaut, ob dep positiv und noch nicht bekannt ist, wenn ja: 
+  //zu deps hinzufuegen
+  //wenn dep < 0 und bekannt ist: aus deps entfernen
+  //Rueckgabewert ist egal. ;-)
+  int dep;
+  dep=to_int(str);
+  if (dep>0 && member(notizen[id,NOTE_DEPS],dep)==-1)
+    notizen[id,NOTE_DEPS]+=({dep});
+  else if (dep<0 && member(notizen[id,NOTE_DEPS],dep*-1)!=-1)
+    notizen[id,NOTE_DEPS]-=({dep*-1});
+  return("");
+}
+
+static int *getDeps(int id, int rec) {
+  //ermittelt (ggf. rekursiv bei rec!=0) die Abhaengigkeiten einer Notiz
+  int i, *liste;
+  liste=notizen[id,NOTE_DEPS];
+  //jetzt ggf. noch rekursiv weiterholen
+  if (rec)  {
+    i=0;
+    while(i<sizeof(liste)) {
+        //nicht schreien. ;-)
+        if (get_eval_cost()<100000) {
+            tell_object(PL,"Fehler: Zu lange Rekursion bei "
+		"Ermitteln der Abhaengigkeiten, Abbruch\n");
+            return(liste);
+        }
+        //Abhaengigkeiten der anderen Abhaengigkeiten hinten anhaengen.
+        liste+=notizen[liste[i],NOTE_DEPS];
+        i++;
+    }
+  }
+  return(liste);
+}
+
+static int *getUnresolvedDeps(int id) {
+  //liefert die Anzahl der nicht abgehakten Notizen, von denen eine 
+  //Notiz abhaengig ist (rekursiv)
+  int *liste;
+  //Abhaengigkeiten rekursiv holen
+  liste=getDeps(id,1);
+  //nicht abgehakte zurueckgeben
+  return(liste-filter(liste,#'note_filter,NOTE_FINISHED));
+}
+
+void init() {
+  ::init();
+  //wenn kein Env, Env kein magier oder nicht der Eigentuemer ist: weg
+  if (!objectp(environment()) || !IS_LEARNER(environment())
+     || (stringp(owner) && getuid(environment())!=owner) ) {
+    if (find_call_out("remove") == -1)
+      call_out("remove",1,1);
+    return;
+  }
+  //beim erstmaligen Bewegen in einen Magier wird der als Eigentuemer
+  //registriert. Danach kommt diese Info aus P_AUTOLOAD
+  if (!stringp(owner))
+    owner=getuid(environment());
+}
+
+static nomask status check_allowed() {
+  //Zugriff auf die Daten fuer den Eigentuemer
+  if(objectp(this_interactive()) &&
+     getuid(this_interactive())==owner
+     && !process_call())
+    return(1);
+  return(0);
+}
+
+protected int restore_me() {
+  //laedt Savefile im Home vom Magier
+  if(!stringp(owner)) return(0);
+  if(!restore_object(SAVEFILE(owner))) {
+    maxusedID=1;
+    notizen=0;
+    //cache=({});
+    return(0);
+  }
+  return(1);
+}
+
+varargs protected void save_me(int delay) {
+  //speichert Savefile im Home vom Magier
+  if(!stringp(owner)) return;
+  //wenn maxusedID==0 wurde der zettel noch nicht ordentlich initialisiert
+  //bzw. restauriert. In diesem Fall wuerde ein leeres Savefile geschrieben
+  if (maxusedID==0)
+    restore_me();
+  if(!delay)
+    //direkt speichen. ;-)
+    save_object(SAVEFILE(owner));
+  else {
+    //verzoegert speichern, wenn schon ein call_out laeuft, nehm ich den
+    if(find_call_out(#'save_me)==-1)
+      call_out(#'save_me,delay);
+  }
+}
+
+varargs int remove(int silent) {
+  //erstmal speichern. ;-)
+  save_me();
+  return ::remove(silent);
+}
+
+static string query_autoloadobj() {
+  //in P_AUTOLOAD wird nur der Eigentuemer gespeichert
+  return owner;
+}
+
+static string set_autoloadobj(mixed arg)  {
+  //Eigentuemer aus P_AUTOLOAD restaurieren
+  if (stringp(arg))
+    owner=arg;
+  return(owner);
+}
+
+//Shadow unerwuenscht
+int query_prevent_shadow() {return(1);}
+
+varargs static int checkStatus(int nocache) {
+  //schaut, ob Notizen da, ob der Cache Ok ist, etc.
+  //liefert Anzahl der Notizen auf dem Merkzettel
+  
+  //wenn keine Notizen da sind, schauen, ob das Savefile eingelesen werden
+  //kann
+  if (!mappingp(notizen) || !sizeof(notizen))
+    restore_me();
+  if (!mappingp(notizen)) return(0);
+/* Cache ist eigentlich nicht noetig und mir gerade zu unpraktisch, raus damit.  
+  //wenn keine Aktualisierung des Cache erwuenscht ist
+  if(nocache) return(0);
+  
+  if (sizeof(notizen)) {
+    if(!pointerp(cache) || !sizeof(cache)) {
+      //cache erneuern
+      cache=sort_array(m_indices(notizen),"sort_prio");
+    }
+  }
+  return(sizeof(cache)); //aequivalent zu sizeof(notizen)
+  */
+  return(sizeof(notizen));
+}
+
+static status sort_prio(int key1, int key2) {
+  // 1, falls falsche Reihenfolge,
+  // 0, wenn richtige
+  // und zwar _absteigend_, also hoechste Prio in liste[0] !
+  return(notizen[key1,NOTE_PRIO]<=notizen[key2,NOTE_PRIO]);
+}
+
+
+//*******************************************************
+
+// Debugging
+mapping QueryNotizen() {
+  
+  if(!check_allowed()) {
+    if(objectp(this_interactive()))
+      tell_object(this_interactive(),
+        BS("Dieser Zugriff auf den Merkzettel wurde nicht erlaubt."));
+    return(0);
+  }
+  checkStatus();
+  return(notizen);
+}
+
+//int *QueryCache() {return(cache);}
+
+int QuerySize() {return(sizeof(notizen));}
+
+string QueryOwner() {return(owner);}
