diff --git a/d/seher/haeuser/moebel/autoloadertruhe.c b/d/seher/haeuser/moebel/autoloadertruhe.c
new file mode 100644
index 0000000..e22ce17
--- /dev/null
+++ b/d/seher/haeuser/moebel/autoloadertruhe.c
@@ -0,0 +1,1015 @@
+//--------------------------------------------------------------------------------
+// Name des Objects:    Aufbewahrungtruhe fuer Autoload-Objekte
+//
+// Magier:              Zesstra
+//--------------------------------------------------------------------------------
+#pragma strong_types,rtt_checks
+
+#include "schrankladen.h"
+inherit LADEN("swift_std_container");
+
+//#include <ansi.h>
+#include <class.h>
+#include <wizlevels.h>
+#include "/d/seher/haeuser/haus.h"
+
+#define IDS     0
+#define NAME   1
+#define ALDATA  2
+
+#define LOG(x,y) log_file(x,sprintf("%s [%s, %O, %O]: %s\n",dtime(time()),\
+      (uuid?uuid:" "),PL,object_name(ME),y))
+#define STORELOG(x) LOG("zesstra/ALTRUHE_STORE.log",x)
+#define PICKLOG(x) LOG("zesstra/ALTRUHE_PICK.log",x)
+
+#define ITEMLOG(x) log_file("zesstra/ALTRUHE_ITEMS.log",\
+    sprintf("%s [%O]: %s\n",dtime(time()),\
+      this_interactive()||PL,x))
+
+#define ERRLOG(x) LOG("zesstra/ALTRUHE.ERR",x)
+
+#undef BS
+#define BS(x) break_string(x,78)
+
+#define VERSION_OBJ "5"
+
+#ifdef MAINTAINER
+#undef MAINTAINER
+#endif
+#define MAINTAINER ({"zesstra"})
+
+// Savefile der Blueprint
+#ifdef SAVEFILE
+#undef SAVEFILE
+#endif
+#define SAVEFILE __FILE__[..<3]
+
+#define DEBUG(x)    if (funcall(symbol_function('find_player),MAINTAINER[0]))\
+          tell_object(funcall(symbol_function('find_player),MAINTAINER[0]),\
+                      "ALTruhe: "+x+"\n")
+
+#define ACCESS (my_secure_level() >= ARCH_LVL)
+
+// Diese 4 sind fuer die Blueprint (Master aller Truhen)
+mapping whitelist=([]); // erlaubte Autoloader, alle anderen nicht erlaubt.
+mapping blacklist=([]); // bereits explizit durch EM+ abgelehnte Autoloader
+mapping vorschlaege=m_allocate(1,2); // vorschlaege der Spieler
+mapping data=([]);  // hier speichert die BP alle Daten der Truhen
+                    // WICHTIG: dieses Mapping wird in /secure/memory
+                    // abgelegt und muss auch beim Neuladen ggf. von dort
+                    // wieder abgeholt werden. Ausserdem teilen sich alle
+                    // Truhen eines Spielers und diese Blueprint die Mappings
+                    // darin, damit Aenderungen sofort in allen Truhen und dem
+                    // Master bekannt sind.
+
+/* die einzelnen Truhen speichern in autoloader. Format: 
+   3 Werte pro Key, Keys sind die Namen der Blueprints der Objekte:
+   ([<blueprint>: <P_IDS>; <ob->name()>; <P_AUTOLOADOBJ> ])
+   */
+nosave mapping autoloader=m_allocate(1,3);
+nosave string uuid; // UUID des Eigentuemers
+nosave object ob_in_bewegung; // uebler Hack eigentlich. :-(
+
+void NotifyInsert(object ob, object oldenv);
+static mapping QueryData();
+static mapping SetData(mixed data);
+protected void save_me();
+protected void check_content();
+
+nomask private int my_secure_level(); //Args.
+
+protected void create() {
+
+  // Ja, es is Absicht, dass das create der BP erst spaeter abgebrochen wird!
+  swift_std_container::create();
+
+  seteuid(getuid(ME));
+
+  // falls dies die BP ist:
+  // 1. das Savefile zu laden.
+  // 2. versuchen, die truhendaten von /secure/memory zu holen, damit nach dem
+  //    Neuladen der Master und die Client immer nach _dieselben_ Mappings
+  //    haben.
+  if (!clonep(ME))
+  {
+    // Savefile restaurieren (auch wenn data im Memory ist, muss das sein,
+    // damit die anderen Variablen wieder eingelesen sind).
+    restore_object(SAVEFILE);
+    // jetzt Daten aus Memory holen, sofern verfuegbar
+    mapping tmp = "/secure/memory"->Load("truhendaten");
+    if (mappingp(tmp))
+    {
+      // Daten aus Savefile durch die vom Memory ersetzen
+      data = tmp;
+    }
+    else
+    {
+      // Keine Daten in Memory. Jetzt in jedem Fall den Pointer auf das Mapping data in
+      // /secure/memory ablegen
+      if ("/secure/memory"->Save("truhendaten",data) != 1)
+      {
+        raise_error("Could not save memory to /secure/memory.");
+      }
+    }
+  }
+  else
+  {
+    // brauchen Clones nicht.
+    set_next_reset(-1);
+    data=0; // brauchen Clones nicht.
+  }
+
+  SetProp(P_SHORT, "Eine kleine, magische Holztruhe");
+  SetProp("cnt_version_obj", VERSION_OBJ);
+  SetProp(P_NAME, "Holztruhe");
+  SetProp(P_GENDER, FEMALE);
+  SetProp(P_NAME_ADJ,({"klein", "magisch"}));
+  SetProp(P_LONG, BS(
+     "Die kleine Holztruhe ist aus stabilem Eichenholz gefertigt. Eigentlich "
+     "saehe sie recht unscheinbar aus, waeren da nicht die vielen kunstvollen "
+     "Runen an den Seiten und auf dem Deckel.")
+    +"@@cnt_status@@");
+
+  AddId(({"autoloadertruhe", "holztruhe", "truhe"}));
+
+  // den Rest vom Create braucht die BP nicht.
+  if (!clonep(ME)) return;
+
+  SetProp(P_LOG_FILE,"zesstra/ALTRUHE.rep");
+
+  SetProp(P_WEIGHT, 3000);         // Gewicht 5 Kg
+  // die drei hier sind in diesme Fall eigentlich voellig ohne Bedeutung
+  SetProp(P_MAX_WEIGHT, 1000000);  // Es passen fuer 1000 kg Sachen rein.
+  SetProp(P_WEIGHT_PERCENT, 100);
+  SetProp(P_MAX_OBJECTS, 100);     // sind eh immer 0 echte Objekte drin.
+
+  SetProp(P_VALUE, 0);             // Kein materieller Wert. Ist eh nicht verkaufbar.
+  SetProp(P_NOBUY, 1);             // Wird im Laden zerstoert, falls er verkauft wird.
+  SetProp(P_NOGET, "Das geht nicht. "+Name(WER,1)+" haftet wie magisch am Boden.\n");
+  SetProp(P_MATERIAL, ([MAT_OAK:49, MAT_MISC_MAGIC:50, MAT_JOFIUM: 1]) );
+  SetProp(P_INFO, BS("In diese stabile Truhe kannst Du bestimmte "
+        "Autoload-Objekte hineinlegen und sie lagern, wenn Du sie gerade "
+        "nicht brauchst. (Mit 'deponiere <was>' kannst Du etwas in der "
+        "Truhe zur Aufbewahrung deponieren, mit 'entnehme <was> oder "
+        "'nimm <was> aus truhe' kannst Du einen Gegenstand wieder "
+        "herausnehmen.)"));
+
+  // Prop fuer rebootfeste Moebel
+  // Der endgueltige Wert (UUID des Spielers) wird per SetBesitzer() gesetzt,
+  // sobald die Truhe das erste Mal in ein Seherhaus bewegt wurde.
+  SetProp(H_FURNITURE, 1);
+
+  AD(({"platz","groesse"}), 
+      BS("Die Truhe ist recht klein, aber merkwuerdigerweise "
+        "scheint sie viel mehr an Gegenstaenden aufnehmen zu koennen, als "
+        "es von ihrer Groesse her scheint."));
+  AD(({"gegenstand","gegenstaende"}),
+      BS("Die Truhe scheint zwar vielen Gegenstaenden Platz zu bieten, aber "
+        "dafuer nimmt sie nicht jeden Gegenstand auf."));
+  AD(({"holz","eichenholz"}),
+      BS("Das Eichenholz ist sehr stabil. Es ist ganz glatt geschliffen und "
+        "traegt viele kunstvolle Runen in sich."));
+  AD(({"seiten","seite"}),
+      BS("Die Truhe hat 4 Seiten, die allesamt mit Runen verziert sind."));
+  AD(({"boden"}),
+      BS("Der Boden der Truhe traegt keinerlei Runen."));
+  AD(({"deckel"}),
+      BS("Auch der Deckel der Truhe ist mit Runen verziert."));
+  AD(({"runen","rune"}),
+      BS("Die Runen bedecken alle 4 Seiten und den Deckel der Truhe. Man "
+        "hat sie zweifellos in muehsamer Arbeit aus dem harten Holz "
+        "geschnitzt. Anschliessend wurden sie offenbar mit einem "
+        "Metall gefuellt. Du verstehst zwar ueberhaupt nicht, was "
+        "die Runen bedeuten, aber sie sind bestimmt magisch, denn wann immer "
+        "Du den Deckel oeffnest oder schliesst oder Gegenstaende hineinlegst "
+        "oder herausnimmst, leuchten die Runen hell auf."));
+  AD(({"metall"}),
+      BS("Was das wohl fuer ein Metall sein mag? Zweifellos hat es auch was "
+        "mit Magie zu tun."));
+  AD(({"magie"}),
+      BS("In dieser Truhe scheint viel Magie zu stecken, wenn selbst ein "
+        "Weltuntergang ihr nichts anhaben kann."));
+  AD(({"arbeit","fertigung"}),
+      BS("Die Fertigung dieser Truhe muss sehr aufwendig gewesen sein. "
+        "Kein Wunder, dass die Truhe so teuer ist."));
+  AD(({"wunder"}),
+      BS("Ein Wunder scheint es zu sein."));
+  AD(({"weltuntergang","armageddon"}),
+      BS("Dir schaudert beim Gedanken an den Weltuntergang."));
+  AD(({"gedanken"}),
+      BS("Denk doch lieber an was anderes..."));
+
+  AddCmd("deponier|deponiere&@PRESENT","cmd_deponiere",
+      "Was moechtest Du in der Eichenholztruhe deponieren?");
+  AddCmd("entnimm|entnehme|entnehm","cmd_entnehmen");
+
+  // bei dieser Truhe waere das Erlauben voellig sinnlos. ;-)
+  RemoveCmd(({"serlaube"}));
+
+}
+
+// keine Truhen zerstoeren, die irgendeinen INhalt haben.
+int zertruemmern(string str) {
+  // aus swift_std_container
+  string nf_str;
+  nf_str="Syntax: zertruemmer [Objekt-Id]\n"
+        +"Bsp.:   zertruemmer "+QueryProp(P_IDS)[1]+"\n";
+  notify_fail("Fehler: Ohne Parameter klappt das nicht.\n"+nf_str);
+  if(!str) return 0;
+  notify_fail("Fehler: Du musst eine gueltige Objekt-Id angeben!\n"+nf_str);
+  if(present(str)!=TO)   // Ueberpruefe, ob auch dieses Objekt gemeint ist!
+    return 0;
+  if( QueryHausbesitzer() != QueryTP() && !QueryProp("test") )
+  {
+    write( BS("Nur "+QueryHausbesitzer()+" darf "+name(WEN,1)+" zertruemmern!"));
+    return 1;
+  }
+  // Objekte enthalten? Wenn ja, abbruch.
+  if (sizeof(autoloader)) {
+    tell_object(PL,BS("Du willst gerade zum Schlag ausholen, um "
+          +name(WEN,1)+ " zu zertruemmern, als Dir einfaellt, dass "
+          +QueryPronoun(WER)+ " ja gar nicht leer ist! Nene, wer weiss, ob "
+          "Du das nicht noch brauchen koenntest."));
+    return 1;
+  }
+  // sonst geerbten Kram ausfuehren.
+  return ::zertruemmern(str);
+}
+
+// Zesstra, 1.7.07, fuers Hoerrohr
+string GetOwner() {return "zesstra";}
+
+// Prueft das Objekt auf Eignung fuer die Truhe, speichert seine Daten und
+// zerstoert es anschliessend. NODROP-Objekte koennen nur so in die Truhe
+// gelegt werden, alle anderen koennen auch mit "stecke ... in truhe"
+// deponiert werden, woraufhin ebenfalls PreventInsert() und NotifyInsert()
+// durchlaufen werden.
+protected int cmd_deponiere(string cmd, mixed args) {
+  if (!objectp(PL)) return 0;
+
+  notify_fail(Name(WER,1)+" ist doch geschlossen!\n");
+  if(QueryProp(P_CNT_STATUS)!=CNT_STATUS_OPEN) return 0;
+  
+  notify_fail("Was moechtest Du in der Eichenholztruhe deponieren?\n");
+  if (!stringp(cmd) || !sizeof(cmd) 
+      || !pointerp(args) || !sizeof(args)) return 0;
+  object ob=args[0];
+  if (!objectp(ob)) return 0;
+  // wuerde die Truhe das Objekt ueberhaupt aufnehmen? Fehlerausgabe durch
+  // PrevenInsert()
+  if (PreventInsert(ob)) return 1;
+  // Ausziehen... Schade, dass DoUnwear nix vernuenftiges an Rueckgabewert
+  // hat. :-(
+  if (objectp(ob->QueryProp(P_WORN))) {
+    ob->DoUnwear();
+    if (objectp(ob->QueryProp(P_WORN))) {
+      tell_object(PL, BS("Du musst "+ ob->name(WEN,1)+ "zunaechst einmal "
+            "ausziehen!"));
+      return 1;
+    }
+  }
+  // wegstecken
+  if (objectp(ob->QueryProp(P_WIELDED))) {
+    ob->DoUnwield();
+    if (objectp(ob->QueryProp(P_WIELDED))) {
+      tell_object(PL, BS("Du musst "+ ob->name(WEN,1)+ "zunaechst einmal "
+            "wegstecken!"));
+      return 1;
+    }
+  }
+  // NO_CHECK und Silent-Bewegung, Meldungen an den Spieler selber machen.
+  tell_object(PL, BS("Du steckst "+ ob->name(WEN,1) + " in " + name(WEN,1) +
+      "."));
+    
+  tell_room(environment(),BS(PL->Name(WER) + " legt " + ob->name(WEN,0) +
+      " in " + name(WEN,1) + " hinein."),({PL}));
+  ob->move(ME, M_NOCHECK|M_SILENT);
+  return 1;
+}
+
+// alternative zum "nimm bla aus truhe". Spieler wollten was kurzes dafuer
+// haben.
+protected int cmd_entnehmen(string cmd) {
+  int res;
+  mixed noget;
+
+  if (!objectp(PL)) return 0;
+
+  notify_fail(Name(WER,1)+" ist doch geschlossen!\n");
+  if(QueryProp(P_CNT_STATUS)!=CNT_STATUS_OPEN) return 0;
+
+  notify_fail(BS("Was moechtest Du aus "+name(WEM,1)+ " entnehmen?\n"));
+  if (!stringp(cmd) || !sizeof(cmd)) return 0;
+
+  object *obs=present_objects(cmd);
+
+  if (!sizeof(obs) || !objectp(obs[0]))
+    return 0;
+
+  // NOGET ist hier bloed. So ist es zwar auch nicht richtig doll... *seufz*
+  // Die hier ist/waere aber nen uebler Hack, erstmal auskommentiert lassen.
+  // also, P_NOGET sichern.
+  /*if (!closurep(noget=ob->Query(P_NOGET,F_QUERY_METHOD))) {
+    noget=ob->Query(P_NOGET,F_VALUE);
+    ob->Set(P_NOGET,0,F_VALUE);
+  }
+  else {
+    ob->Set(P_NOGET,0,F_QUERY_METHOD);
+  }*/
+  // nehmen.
+  res=PL->pick_obj(obs[0]);
+  // P_NOGET zurueckschreiben. (Ja, wenn eine Closure als F_VALUE drinsteht,
+  // landet die jetzt als F_QUERY_METHOD im Objekt.
+  /*if (closurep(noget)) {
+    ob->Set(P_NOGET,noget,F_QUERY_METHOD);
+  }
+  else
+    ob->Set(P_NOGET,noget,F_VALUE);
+*/
+  return(res);
+}
+
+// Hier wird auch das PreventInsert() von der Blueprint gerufen. Das
+// erleichtert es, die Liste an erlaubten Objekten zu aendern, ohne dass man
+// alle Clones ersetzen muss.
+varargs int PreventInsert(object ob) {
+  string oname;
+  // Das Objekt, was die Truhe gerade selber bewegt, wird ignoriert.
+  if (!objectp(ob) || ob_in_bewegung==ob) return 0;
+  
+  oname=BLUE_NAME(ob);
+  
+  // Pruefung in Clonen:
+  if (clonep(ME))
+  {
+    // nur Eigentuemer
+    if (!stringp(uuid) || !sizeof(uuid)) {
+      if (objectp(PL))
+        tell_object(PL,BS(sprintf("%s gehoert Dir nicht, daher kannst Du "
+            "auch keine Gegenstaende in %s legen.",
+            Name(WER,1),QueryPronoun(WEN))));
+      return 1;
+    }
+    if (!objectp(PL) || getuuid(PL)!=uuid) {
+      if (objectp(PL))
+        tell_object(PL,BS(sprintf("Nur %s darf Gegenstaende in %s "
+          "hineinlegen.",capitalize(explode(uuid,"_")[0]),name(WEN,1))));
+      return 1;
+    }
+    // jedes Objekt nur einmal.
+    if (member(autoloader,oname)) {
+      if (objectp(PL))
+        tell_object(PL,BS(Name(WER,1)+ " kann von einem Gegenstand jeweils "
+          "nur ein Exemplar aufnehmen, es ist aber bereits "
+          +ob->name(WER,0) + " in " + QueryPronoun(WEM) + "."));
+      return 1;
+    }
+    // jetzt Erlaubnisliste der BP fragen.
+    if (objectp(blueprint(ME)))
+      return blueprint(ME)->PreventInsert(ob);
+    else
+      return load_object(load_name(ME))->PreventInsert(ob);
+  }
+  // Ende fuer Pruefung fuer Clone.
+
+  // ab hier jetzt die Pruefung durch die BP.
+  // Keine (freigegebener) Autoloader? Hat in diesem Container nix verloren!
+  if( !ob->QueryProp(P_AUTOLOADOBJ) ) {
+    if (objectp(PL))
+      tell_object(PL,BS("In "+name(WEN,1)
+            +" kannst Du nur Autoload-Objekte hineinlegen. "));
+    return 1;
+  }
+  else if (member(blacklist,oname)) {
+    if (objectp(PL))
+      tell_object(PL,BS("In "+name(WEN,1)
+            +" kannst Du nur dafuer erlaubte Autoload-Objekte hineinlegen. "
+            +ob->Name(WER,1) + " wurde explizit als nicht erwuenscht "
+            "befunden."));
+    return 1;
+  }
+  else if (!member(whitelist,oname)) {
+    if (!member(vorschlaege,oname)) {
+      vorschlaege[oname,0]=ob->name(WER,0) || "";
+      vorschlaege[oname,1]=ob->short() || "";
+    }
+    if (objectp(PL))
+      tell_object(PL,BS("In "+name(WEN,1)
+            +" kannst Du nur dafuer erlaubte Autoload-Objekte hineinlegen. "
+            +ob->Name(WER,1) + " ist momentan nicht auf der Liste. Der "
+            "Gegenstand wurde jetzt als Vorschlag gespeichert. Bitte hab "
+            "etwas Geduld, bis sich jemand den Gegenstand angeschaut hat."));
+    // ggf. reset reaktivieren und Maintainer informieren.
+    if (!query_next_reset())
+      set_next_reset(1);
+    return 1;
+  }
+  // getragenes?
+  if (ob->QueryProp(P_WORN)) {
+      ob->DoUnwear(0);
+      if (ob->QueryProp(P_WORN)) { //ARGL. GRUMMEL.
+        if (objectp(PL))
+          tell_object(PL,BS("Willst Du "+ob->name(WEN,1) + " nicht erstmal "
+                "ausziehen?"));
+        return 1;
+      }
+  }
+  // enthaelt es irgendwelche anderen Objekte?
+  if (sizeof(all_inventory(ob))) {
+      if (objectp(PL))
+        tell_object(PL,BS(ob->Name(WER,1) + " ist nicht leer."));
+      return 1;
+  }
+
+  // andere Einschraenkungen, als hier geprueft werden, gibt es nicht.
+  return 0;
+}
+
+// hier ist das Objekt jetzt in der Truhe, d.h. Daten speichern und Objekt
+// destructen. ;)
+void NotifyInsert(object ob, object oldenv) {
+
+  // Das Objekt, was die Truhe gerade selber bewegt, wird ignoriert.
+  if (!objectp(ob) || ob==ob_in_bewegung)
+    return;
+  STORELOG(sprintf("%s deponiert %s [%O], Daten: %O",getuid(PL),ob->name(WEN,0),
+        ob,ob->QueryProp(P_AUTOLOADOBJ)));
+  // noetig sind die IDs, den Namen und die AUTOLOADOBJ-Daten des Objekts.
+  // ;-)
+  autoloader[BLUE_NAME(ob),ALDATA]=ob->QueryProp(P_AUTOLOADOBJ);
+  autoloader[BLUE_NAME(ob),IDS]=ob->QueryProp(P_IDS);
+  // Objekte, die 0 als short liefern, kriegen eine Standard-Short und werden
+  // sichtbar gemacht, da sie sonst nicht wiederzufinden sind. Objekte, die
+  // unsichtbar sein sollen, duerfen nicht erlaubt werden.
+  // TODO eine ID als Short nehmen?
+  autoloader[BLUE_NAME(ob),NAME]=capitalize((ob->short()||"<Unbekannt>.\n")[..<3]);
+  // nach dem Move die realen Objekte destructen.
+  call_out(#'check_content, 0);
+  save_me();
+}
+
+// Objekt wurde entnommen, also aus der Liste der enthaltenen Autoloader
+// loeschen. Ausserdem Objekt konfigurieren. Dies wird erst hier gemacht und
+// nicht in create_object(), damit es so aehnlich wie moeglich zum clonen der
+// Autoloader beim erstellen des Spielerobjektes wird (dort wird erst bewegt,
+// dann konfiguriert).
+void NotifyLeave(object ob, object dest) {
+  string error, oname;
+ 
+  if (!objectp(ob))
+    return;
+  
+  oname=BLUE_NAME(ob);
+  if (!member(autoloader,oname)) {
+    // Das sollte definitiv nicht passieren.
+    ERRLOG(sprintf("Gegenstand (%O) wurde entnommen, der nicht "
+      "gespeichert war!",ob));
+    return;
+  }
+
+  // wenn kein Fehler: Objekt aus Liste loeschen. Sonst wird das Objekt
+  // zerstoert. Damit bleiben die Autoloader-Daten hier erhalten und der
+  // Spieler hat kein disfunktionales Objekt im Inventar.
+  if (error) {
+    ERRLOG(sprintf("Fehler beim Konfigurieren von %O. Fehlermeldung: %O."
+        "Daten: %O",ob,error,autoloader[oname,ALDATA]));
+    ob->remove(1);
+    if (objectp(ob))
+      destruct(ob);
+  }
+  else {
+    PICKLOG(sprintf("Objekt (%O) wurde entnommen.",ob));
+    m_delete(autoloader,oname);
+    // speichern
+    save_me();
+  }
+}
+
+protected void check_content() {
+  // wenn Objekte noch in der Truhe sind, also nicht erfolgreich in
+  // einen Spieler bewegt wurden, werden zerstoert. Datenverlust gibt es
+  // hierbei nicht, weil die Daten der Autoloader nur durch NotifyLeave()
+  // geloescht werden.
+  foreach(object ob: all_inventory()) {
+    ob->remove(1);
+    if (objectp(ob)) destruct(ob);
+  }
+}
+
+// hier nochmal schauen, ob das Objekt auch in den richtigen Spieler bewegt
+// wird... Falls das move dann hier abgebrochen wird, wird das Objekt im
+// naechsten HB von der Truhe zerstoert. (chk_contents())
+varargs int PreventLeave(object ob, mixed dest) {
+  object ob2;
+  
+  //DEBUG(sprintf("PreventLeave(): Ob: %O, Dest: %O (%O)",
+  //        ob,dest,(objectp(dest)?"Objekt":"Non-Object")));
+
+  if (!objectp(ob)) return 0; 
+  // falls string uebergeben, erstmal zug. Spieler finden.
+  if (stringp(dest) && sizeof(dest))
+    dest=find_player(dest);
+
+  // richtiges INteractive? Dann darf das Objekt raus. Sonst nicht. ;-)
+  if (!objectp(dest) || !interactive(dest) || getuuid(dest)!=uuid)
+      return 1;
+
+  // pruefen, ob der Spieler schon ein Objekt dieser Blueprint dabei hat. Wenn
+  // ja, Abbruch, das koennte sonst zuviele Probleme geben.
+  if (objectp(ob2=present_clone(ob,dest))) {
+    tell_object(dest,BS("Du hast bereits "+ob2->name(WEN,0) +
+        " dabei. Zwei Gegenstaende dieser Art kannst du nicht gleichzeitig "
+        "mit Dir herumtragen."));
+    return 1; //nicht rausnehmen.
+  }
+  return 0;
+}
+
+// Objekte ausgeben, die hier angeblich drin sind. ;-) Gibt aber nur die
+// Autoloader aus, keine echten Objekt, die Container sind. Allerdings sollte
+// sowas eh nicht vorkommen. ;-)
+// flags: 1 - return array, 2 - don't collect equal objects '
+// flags: 4 - don't append infos for wizards
+varargs mixed make_invlist(object viewer, mixed inv, int flags) {
+  int iswiz;
+  mixed objs;
+
+  iswiz = IS_LEARNER( viewer ) && viewer->QueryProp(P_WANTS_TO_LEARN);
+  // Mapping benutzen, um multiplen Overhead fuer allokation im foreach() zu
+  // vermeiden.
+  objs=m_allocate(sizeof(autoloader),1);
+  foreach(string oname, string *ids, string sh: autoloader) {
+    if (iswiz && !(flags & 4))
+      objs[oname]=sh + ". ["+oname+"]";
+    else
+      objs[oname]=sh + ".";
+  }
+  if(flags & 1) return(m_values(objs)-({""}));
+  if(!sizeof(autoloader)) return "";
+  return sprintf("%"+(sizeof(objs) > 6 ? "#" : "=")+"-78s",
+                 implode(m_values(objs)-({""}), "\n")) + "\n";
+}
+
+// erzeugt das benannte Objekt und liefert es zurueck. Liefert 0 im Fehlerfall.
+// ausserdem bewegt es das Objekt in die Truhe, damit es ein Env hat und die
+// Truhe via NotifyLeave() mitkriegt, dass es tatsaechlich entnommen wurde.
+private object create_object(string oname) {
+  string error;
+  object ob;
+  mixed noget;
+  if (!member(autoloader,oname)) return 0;
+
+  //Blueprint finden (ja, das ist nicht unbedingt noetig, man koennte auch
+  //direkt clonen)
+  if (error=catch(ob=load_object(oname);publish) ||
+      !objectp(ob)) {
+    ERRLOG(sprintf("Konnte %s nicht laden/finden. Fehler: %O",
+          oname,error));
+    return 0;
+  }
+  // clonen
+  if (error=catch(ob=clone_object(oname);publish) ||
+      !objectp(ob)) {
+    ERRLOG(sprintf("Konnte %s nicht clonen. Fehler: %O",
+        oname,error));
+    return 0;
+  }
+  // konfigurieren
+  error=catch(ob->SetProp(P_AUTOLOADOBJ,autoloader[oname,ALDATA]);publish);
+
+  //Objekt bewegen, dabei Objekt in glob. Var. merken, damit PreventInsert()
+  //und NotifyInsert() es ignorieren. *seufz*
+  ob_in_bewegung=ob;
+  ob->move(ME,M_NOCHECK);
+  ob_in_bewegung=0;
+
+  // jetzt noch nen Callout starten, damit das Objekt zerstoert wird, wenn es
+  // nicht wirklich in einen Spieler bewegt wird.
+  call_out(#'check_content,1);
+
+  return(ob);
+}
+
+// Schauen, ob die truhe ein Objekt mit passender ID enthaelt. Wenn
+// ja, das Objekt erzeugen und zurueckliefern. 
+// Diese Funktion hat eine Reihe von Nachteilen bzw. Defiziten ggue. der
+// normalerweise in Containern definierten Funktion:
+// - Nur das erste Objekt, auf das id passt. Ich hab erstmal keine Lust,
+//   hier mehrere Objekte zu erzeugen. Mal schauen, ob es so geht. Auch waere
+//   es ein Problem, wenn viele Objekt die Evalgrenze bzw. nicht alle in den
+//   Spieler bewegt werden, nachdem sie erzeugt wurden.
+// - keine komplexen Ausdruecke, nur reine IDs.
+// Ich halte den Aufwand fuer nicht gerechtfertigt.
+object *present_objects( string complex_desc ) {
+  object ob;
+  if (!stringp(complex_desc) || !sizeof(complex_desc))
+      return ({});
+  // diese Funktion liefert nur Objete zurueck, wenn der richtige Interactive
+  // versucht, sie zu entnehmen. ;-)
+  if (!objectp(this_interactive()) ||
+      getuuid(this_interactive())!=uuid)
+      return ({});
+
+  // "alles" liefert das erstbeste Objekt.
+  if (complex_desc=="alles" && sizeof(autoloader))
+  {
+    string oname=m_indices(autoloader)[0];
+    ob=create_object(oname);
+    if (objectp(ob)) return ({ob});
+  }
+
+  // ueber alle Eintraege gehen, bis eine ID stimmt, erstes passendes Objekt
+  // erzeugen und in einem Array zurueckliefern.
+  foreach(string oname, string *ids: autoloader) {
+    if (member(ids,complex_desc)==-1) continue;
+    ob=create_object(oname);
+    break; //objekt gefunden, fertig hier
+  }
+  if (objectp(ob)) return ({ob});
+  return ({}); // nix gefunden
+}
+
+
+
+// ******************* Verwaltung *********************************
+
+// registriert die Truhe auf den jeweiligen Eigentuemer.
+protected void SetBesitzer(string unused, string newuuid) {
+  if (!stringp(newuuid) || !sizeof(newuuid)) return;
+  // wenn schon registriert, abbrechen
+  if (stringp(uuid) && sizeof(uuid)) return;
+
+  uuid=newuuid;
+  Set(H_FURNITURE,uuid,F_VALUE); //Setmethode umgehen, sonst Rekursion 
+  // ab jetzt nur noch von der Truhe selber.
+  Set(H_FURNITURE,SECURED,F_MODE_AS);
+  
+  // Daten fuer den Benutzer aus der Blueprint holen (BP liefert KEINE Kopie
+  // und es darf KEINE gemacht werden!):
+  autoloader=(mapping)load_name()->GetData(uuid);
+  
+  // keine Daten gekriegt? -> Fehler loggen
+  if (!mappingp(autoloader))
+  {
+    ERRLOG(sprintf("Keine gueltigen Daten vom Truhenmaster (BP) erhalten. "
+        "initialisiere mit leerem Mapping. :-("));
+    raise_error(sprintf(
+          "Keine gueltigen Daten vom Truhenmaster (BP) fuer UUID %s "
+          "erhalten.\n",uuid));
+  }
+}
+
+// Set-Funktion
+string _set_h_furniture(mixed arg) {
+  if (stringp(arg))
+  {
+    SetBesitzer(0,arg); // bricht ab, wenn bereits registriert.
+  }
+  return(uuid);
+}
+
+// Falls das Speichern in der BP nicht klappte, rufen die Clones diese
+// Funktion. Schreiben der Daten in in Logfile zur Restaurieren per Hand.
+private void EmergencyStore(int res) {
+    ERRLOG(sprintf("EmergencyStore() called. Rueckgabewert des "
+        "Truhenmaster (BP) war: %O. Speichere Daten in Logfile. ",res));
+    write_file(__DIR__+"ALTRUHE.NOTFALLDATEN",
+        sprintf("Daten fuer %O:\n%O\n",uuid,autoloader));
+}
+
+protected void save_me() {
+  int res;
+  // nur BP speichern
+  if (!clonep(ME))
+    save_object(SAVEFILE);
+  else
+  {
+    if (objectp(blueprint(ME)))
+      res=(int)blueprint(ME)->StoreData(uuid,autoloader);
+    else
+      res=(int)load_object(load_name(ME))->StoreData(uuid,autoloader);
+
+    if (res!=1)
+      EmergencyStore(res); // Daten in einem Notfall-Logfile ablegen.
+  }
+}
+
+
+// diese Funktion wird vom Seherhausraum gerufen, sobald ein rebootfestes
+// Moebelstueck erzeugt und konfiguriert wurde.
+void post_create() {
+    if (!clonep()) return;
+
+    // wenn jetzt kein Env: destructen
+    if (!objectp(environment())) {
+        remove(1);
+        return;
+    }
+    //beim Schrankmaster registrieren
+    SCHRANKMASTER->RegisterCnt(ME, QueryProp("cnt_version_std")
+      +":"+QueryProp("cnt_version_obj"), environment()->QueryOwner(),
+       environment());
+}
+
+// diese Funktion wird vom Schrankmaster gerufen, wenn dieser meint, dass
+// dieses Objekt neu erstellt werden sollte.
+int UpdateMe()
+{
+  if (!clonep())
+    return 0;
+  if (!objectp(environment()))
+    return 1;
+  object ob=clone_object(load_name(ME));
+  if (objectp(ob)) {
+    object oldenv=environment();
+    // UUID uebertragen
+    ob->SetProp(H_FURNITURE, uuid);
+    // hierhier bewegen, dabei werden UUID und Daten von der neuen Truhe meist
+    // automatisch geholt.
+    ob->move(oldenv,M_NOCHECK);
+    // jetzt erst post_create() rufen!
+    ob->post_create();
+    // dieses Objekt rausbewegen (damit das Seherhaus es austraegt).
+    move("/room/void",M_NOCHECK);
+    // Seherhausraum speichern (koennte teuer sein!)
+    oldenv->Save(1);
+    // selbstzerstoeren
+    // __INT_MAX__ bedeutet: nicht speichern, die neue Truhe hat die daten
+    // schon aus der BP abgefragt.
+    remove(__INT_MAX__);
+  }
+  return(1);
+}
+
+// bei Selbstzerstoerung speichern bzw. Daten an die Blueprint uebermitteln
+// und beim Schrankmaster abmelden.
+varargs int remove(int silent) {
+  string uid="";
+
+  // Blueprint speichern im Savefile, Clones uebertragen die Daten hier an die
+  // Blueprint. Clones nur, wenn nicht __INT_MAX__ uebergeben wurde.
+  if (silent!=__INT_MAX__ || !clonep())
+    save_me();
+
+  if (clonep()) {
+    // Clone melden sich beim Schrankmaster ab.
+    if (objectp(environment())) {
+        uid=environment()->QueryOwner();
+    }
+    //beim Schrankmaster deregistrieren
+    SCHRANKMASTER->RemoveCnt(ME,uid);
+  }
+  return(::remove(silent));
+}
+
+// ***************** NUR BLUEPRINTS *********************************
+
+// neuen Autoloader zulassen (nur EM+!)
+varargs int AddAutoloader(string path,string nam) {
+  object ob;
+  if (clonep(ME)) return 0;
+  if (!stringp(path) || !sizeof(path)) return -1;
+  if (!ACCESS) return -2;
+  //if (!ARCH_SECURITY) return -2;
+  if (member(whitelist,path)) return -3;
+  if (catch(ob=load_object(path);publish)
+      || !objectp(ob))
+      return -4;
+  // wenn Name nicht angegeben und auch nicht aus BP ermittelbar: Abbruch.
+  if (!stringp(nam) || !sizeof(nam)) {
+      nam=ob->name(WER,0);
+      if (!stringp(nam) || !sizeof(nam)) return -5;
+  }
+  ITEMLOG(sprintf("%s erlaubt: %s (%s)\n",getuid(this_interactive()),
+          path,nam));
+  whitelist+=([path:capitalize(nam)]);
+  if (member(vorschlaege,path))
+    m_delete(vorschlaege,path);
+  save_me();
+  return(1);
+}
+
+// Autoloader aus Erlaubnisliste entfernen (nur EM+!)
+int RemoveAutoloader(string path) {
+  if (clonep(ME)) return 0;
+  if (!stringp(path) || !sizeof(path)) return -1;
+  if (!ACCESS) return -2;
+  //if (!ARCH_SECURITY) return -2;
+  if (!member(whitelist,path)) return -3;
+  ITEMLOG(sprintf("%s widerruft Erlaubnis: %s (%s)\n",getuid(this_interactive()),
+          path,whitelist[path]));
+  whitelist-=([path]);
+  save_me();
+  return(1);
+}
+
+// erlaubte Autoloader abfragen
+mapping QueryAutoloader() {
+  return(copy(whitelist));
+}
+
+// neuen Autoloader in Blacklist eintragen (nur EM+!)
+varargs int AddBlacklist(string path, string nam) {
+  object ob;
+  if (clonep(ME)) return 0;
+  if (!stringp(path) || !sizeof(path)) return -1;
+  if (!ACCESS) return -2;
+  //if (!ARCH_SECURITY) return -2;
+  
+  if (member(blacklist,path)) return -3;
+
+  if (catch(ob=load_object(path);publish)
+      || !objectp(ob))
+      return -4;
+  // wenn Name nicht angegeben und auch nicht aus BP ermittelbar: Abbruch.
+  if (!stringp(nam) || !sizeof(nam)) {
+      nam=ob->name(WER,0);
+      if (!stringp(nam) || !sizeof(nam)) return -5;
+  }
+  // ggf. erlaubten entfernen.
+  if (member(whitelist,path))
+    RemoveAutoloader(path);
+  ITEMLOG(sprintf("%s verbietet: %s (%s)\n",getuid(this_interactive()),
+          path,nam));
+
+  blacklist+=([path:capitalize(nam)]);
+
+  if (member(vorschlaege,path))
+    m_delete(vorschlaege,path);
+
+  save_me();
+  return(1);
+}
+
+// Autoloader aus Blacklist entfernen (nur EM+!)
+int RemoveBlacklist(string path) {
+  if (clonep(ME)) return 0;
+  if (!stringp(path) || !sizeof(path)) return -1;
+  if (!ACCESS) return -2;
+  //if (!ARCH_SECURITY) return -2;
+  if (member(blacklist,path)==-1) return -3;
+  ITEMLOG(sprintf("%s loescht: %s (%s) von Blacklist\n",getuid(this_interactive()),
+          path,blacklist[path]));
+  blacklist-=([path]);
+  save_me();
+  return(1);
+}
+
+// gesperrte Autoloader abfragen
+mapping QueryBlacklist() {
+  return(copy(blacklist));
+}
+
+// vorschlaege abfragen
+varargs mixed QueryVorschlaege(int format) {
+  string res="\n";
+  if (!format) return(copy(vorschlaege));
+
+  foreach(string oname, string nam, string sh: vorschlaege) {
+    res+=sprintf("%.78s:\n   %.37s,%.37s\n",oname,nam,sh); 
+  }
+
+  if (format==2 && objectp(PL))
+    tell_object(PL,res);
+  else
+    return res;
+  return 0;
+}
+
+// Wird diese funktion in der Blueprint gerufen, liefert sie die Daten fuer
+// eine Truhe mit dieser UUID zurueck. Aber nur dann, wenn die auch von einer
+// truhe abgerufen wird und keinem beliebigen anderen Objekt oder wenn ein EM
+// abfragt.
+mapping GetData(string uid) {
+  if (clonep(ME)) return 0;
+  if (extern_call())
+  {
+    if (!objectp(previous_object())) return 0;
+    if (blueprint(previous_object()) != ME
+        && load_name(previous_object()) != __FILE__[..<3]
+        && !ACCESS)
+        return(0);
+  }
+  if (!stringp(uid)) return ([]);
+
+  if (!member(data, uid))
+    data[uid] = m_allocate(1,3);
+
+  // Absichtlich keine Kopie, damit die Truhen (falls jemand mehrere kauft)
+  // sich alle eine Kopie des Mappings teilen.
+  return data[uid];
+}
+
+// Loest die Speicherung der Daten im Savefile aus, denn irgendwelche Daten
+// haben sich in einem Clone geaendert, welche noch auf die Platte muessen.
+// Diese Funktion speicherte frueher Daten aus den Clones wieder im Mapping
+// des Masters (der Blueprint). Dies ist heute nicht mehr so, weil alle Truhen
+// (eines Benutzers) sich data[uid] teilen. Daher wird hier ein Fehler
+// ausgeloest, wenn es von einer Truhe ein Mapping kriegt, welches nicht
+// identisch (!) mit dem data[uid] ist.
+// liefert 0 im Fehlerfall!
+int StoreData(string uid, mapping tmp) {
+
+  if (clonep(ME)) return 0;
+
+  // Aber nur dann, wenn die auch von einer truhe abgerufen wird und keinem
+  // beliebigen anderen Objekt oder wenn ein EM setzt.
+  if (extern_call())
+  {
+    if (!objectp(previous_object()))
+      return 0;
+    if (blueprint(previous_object()) != ME 
+        && load_name(previous_object()) != __FILE__[..<3]
+        && !ACCESS)
+      return 0;
+  }
+  if (!stringp(uid) || !mappingp(tmp))
+    return(0);
+
+  // tmp muss auf _dasselbe_ Mapping zeigen wie data[uid]. Wenn das nicht der
+  // Fall ist, ist was schiefgelaufen. Jedenfalls wird dann hier nen Fehler
+  // ausgeloest.
+  if (tmp != data[uid])
+  {
+//    if(program_time(previous_object()) < 1400525694)
+//      data[uid]=tmp;
+//    else
+      raise_error("StoreData() gerufen und Daten sind nicht identisch "
+          "mit den bereits bekannten.\n");
+  }
+
+  // Absichtlich keine Kopie, damit sich alle Truhen das Mapping teilen.
+  //data[uid]=tmp;
+
+  // Savefile muss natuerlich geschrieben werden, fuer den naechsten Reboot.
+  if (find_call_out(#'save_me)==-1)
+      call_out(#'save_me,10); // Speichervorgaenge ggf. sammeln (upd -ar ...)
+  return(1);
+}
+
+// Maintainer ueber Truhenvorschlaege informieren
+void reset() {
+
+  if (clonep() || !sizeof(vorschlaege)) {
+    // ohne Vorschlaege ist auch kein reset noetig.
+    set_next_reset(-1);
+    return;
+  }
+  set_next_reset(12000); // alle 3-4h reicht.
+  foreach(string uid: MAINTAINER) {
+    object pl=find_player(uid);
+    if (objectp(pl) && query_idle(pl) < 1800)
+      tell_object(pl,BS("Es gibt neue Objektvorschlaege fuer die "
+        "Autoloadertruhe. Bitt schau da doch bei Gelegenheit mal drueber."));
+  }
+}
+
+
+// *************************************************************************
+
+// **************** SONSTIGES **********************************************
+
+// *seufz*
+// secure_level() aus der simul_efun ist hier momentan nicht brauchbar, weil
+// dort auch p/seher/moebel/autoloadertruhe in der Callerkette steht und das
+// ein levle von 0 hat. *seufz*
+nomask private int my_secure_level() {
+  int *level;
+  //kette der Caller durchlaufen, den niedrigsten Level in der Kette
+  //zurueckgeben. Zerstoerte Objekte (Selbstzerstoerer) fuehren zur Rueckgabe
+  //von 0.
+  //caller_stack(1) fuegt dem Rueckgabearray this_interactive() hinzu bzw. 0,
+  //wenn es keinen Interactive gibt. Die 0 fuehrt dann wie bei zerstoerten
+  //Objekten zur Rueckgabe von 0, was gewuenscht ist, da es hier einen
+  //INteractive geben muss.
+  level=map(caller_stack(1),function int (object caller)
+      {if (objectp(caller))
+        return(query_wiz_level(geteuid(caller)));
+       return(0); // kein Objekt da, 0.
+      } );
+  return(min(level)); //den kleinsten Wert im Array zurueckgeben (ggf. 0)
+}
+
+
+// debugkram
+mixed _query_content() {
+  //deep_copy, damit nicht jemand einfach so an den Daten rumbasteln kann.
+  return(deep_copy(autoloader));
+}
+
+mixed _query_owner() {
+  return(uuid);
+}
+
+int DeleteData(string uid) {
+  if (clonep(ME)) return 0;
+  if (!stringp(uid) || !sizeof(uid)) return -1;
+  if (!ACCESS) return -2;
+  //if (!ARCH_SECURITY) return -2;
+  m_delete(data,uid);
+  save_me();
+  return(1);
+}
+
+mixed testfun() {return "bin da\n";}
+
