diff --git a/d/seher/haeuser/modules/losa.c b/d/seher/haeuser/modules/losa.c
new file mode 100644
index 0000000..893ca51
--- /dev/null
+++ b/d/seher/haeuser/modules/losa.c
@@ -0,0 +1,378 @@
+//  losa.c -- Modul fuer Laden und Speichern der Hausdaten
+//
+//  (c) 1995 Wargon@MorgenGrauen
+//      2006 Vanion@MorgenGrauen, fuer die rebootfesten Moebel
+// $Id: losa.c,v 1.1.1.1 2000/08/20 20:22:42 mud Exp $
+//
+#pragma strong_types,rtt_checks
+
+#define NEED_PROTOTYPES
+#include "../haus.h"
+#include <container.h>
+#include <thing/properties.h>
+#include <room/exits.h>
+#include <thing/description.h>
+#undef NEED_PROTOTYPES
+#include <properties.h>
+#include <wizlevels.h>
+#include <moving.h>
+
+static void start_reload_furniture();
+
+private int csaved;
+
+// Variablen zur Verwaltung der Moebel im Raum.
+mapping furniture;
+mapping broken_furniture;
+
+protected void
+create()
+{
+  Set(H_CHEST, SAVE, F_MODE);
+  Set(H_CHEST, 0);
+
+  Set(H_FURNITURE, SAVE, F_MODE);
+  Set(H_FURNITURE, 0);
+
+//  Set(H_SPECIAL, SAVE|SECURED, F_MODE);
+//  Set(H_SPECIAL, ([:2]), F_VALUE);
+}
+
+/* Scheint nirgendwo benutzt zu werden...
+varargs int AddSpecial(int typ, string key, string extra)
+{
+  if (!this_interactive() || !IS_ARCH(this_interactive()) ||
+      !(PATH+"access_rights")->access_rights(geteuid(this_interactive()),""))
+    return -1;
+
+  if (typ != HS_EXIT && typ != HS_ITEM)
+    return 0;
+
+  Set(H_SPECIAL, Query(H_SPECIAL) + ([ key : typ; extra ]));
+  Save();
+  return 1;
+}
+
+void RemoveSpecial(string key)
+{
+  if (!this_interactive() || !IS_ARCH(this_interactive()) ||
+      !(PATH+"access_rights")->access_rights(geteuid(this_interactive()),""))
+    return;
+
+  Set(H_SPECIAL, m_delete(Query(H_SPECIAL), key));
+  Save();
+}
+*/
+
+void
+reset()
+{
+  if (QueryOwner() &&
+      !sizeof(filter(all_inventory(),#'interactive)) &&
+      !csaved)
+    Save(1);
+}
+
+// crunched komprimiert das Savefile
+varargs void
+Save(int crunched)
+{
+  mixed o1, o2, o3;
+  closure pc;
+  object *obs;
+  int i, found;
+
+  o3 = 0;
+
+  if (!(o1 = Query(P_DETAILS)))
+    Set(P_DETAILS, QueryProp(P_DETAILS), F_VALUE);
+
+  if (!(o2 = Query(P_READ_DETAILS)))
+    Set(P_READ_DETAILS, QueryProp(P_READ_DETAILS), F_VALUE);
+
+  if (csaved = crunched)
+  {
+    pc = symbol_function("PCrunch", VERWALTER);
+    Set(P_DETAILS, funcall(pc, Query(P_DETAILS)), F_VALUE);
+    Set(P_READ_DETAILS, funcall(pc, Query(P_READ_DETAILS)), F_VALUE);
+    o3 = Query(H_COMMANDS, F_VALUE);
+    Set(H_COMMANDS, funcall(pc, o3), F_VALUE);
+  }
+
+  // Autoload-Einrichtung identifizieren und speichern
+  // Code in Anlehnung an dem Autoload-Mechanismus fuer Spieler
+  furniture=([]);
+
+  // Alle Autoloader filtern
+  obs=filter_objects(all_inventory(this_object()), "QueryProp", H_FURNITURE);
+  found = 0;
+
+  // Ueber alle Moebel iteritieren
+  for( i=sizeof(obs)-1;i>=0;i--)
+  {
+    if( clonep(obs[i]))
+    {
+      if ( ++found <= MAX_FURNITURE_PER_ROOM )
+        furniture += ([ object_name(obs[i]):obs[i]->QueryProp(H_FURNITURE) ]);
+    }
+  }
+  if (found > MAX_FURNITURE_PER_ROOM)
+  {
+    tell_object(this_player(), 
+      break_string("Du hast "+found+" Moebelstuecke im Raum stehen. "
+                   "Gespeichert werden nur "+MAX_FURNITURE_PER_ROOM+". "
+                   "Du solltest Dich von einigen Einrichtungsgegenstaenden "
+                   "trennen.",78));
+
+  }
+  HDEBUG("Saving "+ sizeof (furniture) +" (plus "+sizeof(broken_furniture)+
+         " broken) objects in room "+
+         object_name(this_object()) + ".");
+
+  save_object( HAUSSAVEPATH+QueryOwner(1));
+
+  Set(P_DETAILS, o1, F_VALUE);
+  Set(P_READ_DETAILS, o2, F_VALUE);
+  if (o3)
+    Set(H_COMMANDS, o3, F_VALUE);
+}
+
+void
+Load()
+{
+  mixed prop;
+  int i;
+
+  restore_object( HAUSSAVEPATH+QueryOwner(1));
+
+  // Details und Kommandos werden beim Speichern de-dupliziert und in einem
+  // speziellen Format abgespeichert (s. PCrunch() im Hausverwalter). Sie
+  // muessen nach dem Laden durch die entsprechenden Add...()-Aufrufe
+  // wieder eingetragen werden.
+  prop=Query(P_DETAILS, F_VALUE);
+  RemoveDetail(0);
+  if (pointerp(prop))
+  {
+    foreach(<string*|string>* item : prop)
+      AddDetail(item[0], item[1]);
+  }
+  else if (mappingp(prop))
+  {
+    foreach(string key, mixed val : prop)
+      AddDetail(key, val);
+  }
+  else
+    SetProp(P_DETAILS, prop);
+
+  prop = Query(P_READ_DETAILS, F_VALUE);
+  RemoveReadDetail(0);
+  if (pointerp(prop))
+  {
+    foreach(<string*|string>* item : prop)
+      AddDetail(item[0], item[1]);
+  }
+  else if (mappingp(prop))
+  {
+    foreach(string key, mixed val : prop)
+      AddReadDetail(key, val);
+  }
+  else
+    SetProp(P_READ_DETAILS, prop);
+
+  prop = Query(P_EXITS, F_VALUE);
+  RemoveExitNoCheck(0);
+  if (mappingp(prop))
+  {
+    if (widthof(prop) <= 1)
+    {
+      foreach(string key, string dest : prop)
+        AddExitNoCheck(key, dest);
+    }
+    else
+    {
+      foreach(string key, string dest, string msg : prop)
+      {
+        if (stringp(msg))
+          _AddExit(key, dest, msg);
+        else if (stringp(dest) && strstr(dest,"#") != -1)
+          AddExitNoCheck(key, dest);
+        else
+          _AddExit(key, dest, 0);
+      }
+    }
+  }
+
+  prop=Query(H_COMMANDS, F_VALUE);
+  if (pointerp(prop))
+  {
+    Set(H_COMMANDS, ([]), F_VALUE);
+    for (i=sizeof(prop)-1; i>=0; i--)
+      this_object()->AddUserCmd(prop[i][0], 0, prop[i][1], prop[i][2]);
+  }
+
+  if (environment())
+    environment()->SetProp(P_NEVER_CLEAN, 1);
+
+  if (previous_object() && object_name(previous_object())==VERWALTER)
+  {
+    if (Query(H_CHEST))
+      this_object()->AddItem(PATH+"truhe",REFRESH_NONE,
+                             ([ "owner" : QueryOwner() ]));
+/* Das scheint nirgendwo benutzt zu werden und in allen Seherhaeusern leer zu
+ * sein.
+    mapping special = Query(H_SPECIAL, F_VALUE);
+    if (special)
+    {
+      foreach(string key, int type, string extra : special)
+      {
+        switch(type)
+        {
+          case HS_ITEM:
+            AddItem(SPECIALPATH + extra, REFRESH_DESTRUCT);
+            break;
+          case HS_EXIT:
+            AddExitNoCheck(key, extra);
+            break;
+        }
+      }
+    }
+*/
+  }
+
+  // Das Laden der Autoloader wird erst am Ende angestossen. 
+  // Dann ist es nicht schlimm, wenn alle Eval Ticks verbraucht werden.
+  start_reload_furniture();
+}
+
+// Mehrere Save-Anforderungen zusammenfassen.
+static void queued_save()
+{
+        HDEBUG("QS");
+        while (remove_call_out("Save")!=-1);
+        call_out("Save",3);
+}
+
+static int reload_error(string file, mixed data,  string message)
+{
+        HDEBUG(message);
+        broken_furniture+=([file:data]);
+        log_file("seher/haeuser/autoloader_error",
+                 dtime(time())+"\n"+
+                 break_string(object_name(this_object())+" ("+QueryOwner(1)+")",78, " FILE: ",1)+
+                 break_string(message, 78, " MSG:  ",1)+
+                 break_string(sprintf("%O", data),78, " DATA: ",1)+"\n");
+                 
+        return 0; // 0 fuer das filter, damit dieser Eintrag 
+                  // aus furniture geloescht wird.
+}
+
+// Laedt ein einzelnes Moebelstuecks
+static int load_furniture_object( string file, mixed data )
+{
+    object ob;
+    string error;
+    string blueprint;
+    closure pc;
+    // mixed data;
+    
+    // Wenn genug Ticks frei sind, wird versucht, das Objekt zu erzeugen.
+    // Ansonsten ist die Gefahr zu gross, dass ein Erzeugungs-Prozess abbricht.
+    if (get_eval_cost() < 500000) 
+    {
+      // HDEBUG("Suspending Object: "+file+". Only "+to_string(get_eval_cost())+" ticks left.");
+      return 1; // 1 bedeutet, dass dieser Eintrag es im Mapping bleibt.
+    }
+
+    // HDEBUG("Processing Object: "+file+" with Data: "+sprintf("%O",data)+".");
+    
+    // Nummern der Clones sind beim Speichern noetig, um die Identitaeten
+    // der Objekte zu bestimmen (mehrere Objekte vom gleichen Blueprint 
+    // speichern). Hier braucht man sie nicht mehr 
+            
+    blueprint = explode(file,"#")[0];
+    
+    // Data aus dem Mapping holen
+    // data=furniture[file];
+    
+    // Muss ich die Blueprint suchen?
+    ob = find_object(file);
+    
+    // Nein.
+    if (!ob)
+    {
+            // Existiert die BP oder ein VC fuers File?
+        if (file_size(blueprint+".c")<0&&
+           file_size(implode(explode(blueprint,"/")[0..<2],"/")+
+                     "/virtual_compiler.c")<0)
+        {
+           return reload_error(file, data, "Error in file: "+ file +
+                               ". File does not exist.");
+
+        }
+
+        // File gefunden. Versuch, es zu laden.
+        if (error = catch(call_other( blueprint,"???")))
+        {
+           return reload_error(file, data, "Error loading file: "+file+". "+error);
+        }
+    }
+    
+    // Clone erzeugen
+    if ( error = catch(ob = clone_object(blueprint)) )
+    {
+        return reload_error(file, data, "Error cloning object: "+file+". "+error);
+    }
+ 
+    HDEBUG(sprintf("%O",furniture));
+    // Autoload-Daten setzen
+    HDEBUG(object_name(ob)+"->SetProp("+sprintf("%O", data)+")");
+    if (ob)
+        catch(ob->SetProp( H_FURNITURE, data ));
+           
+    // Furniture in das Seherhaus moven
+    if ( error = catch(ob->move( this_object(), M_NOCHECK )) ) {
+        ob->remove();
+        if(ob) destruct(ob);
+        return reload_error(file, data, "Error moving object: "+file+". "+error);
+    }
+
+    // post_create anstossen
+    pc=symbol_function("post_create", ob);
+    if (closurep(pc))
+      call_out(pc, 1);
+    
+    return 0; // 0 bedeutet hier, dieses Objekt nicht noch einmal anstossen.
+}
+
+static void load_furniture()
+{
+        int i;
+        string rv;
+        string current_key;
+        
+        // Abbruchbedingung ist, dass nichts mehr zu laden ist.
+        if (sizeof(furniture)==0) return; 
+        
+        // Anstoßen des naechsten Durchlaufs, falls die Ticks nicht reichen.
+        while (remove_call_out(#'load_furniture) != -1);
+        call_out(#'load_furniture, 1);
+        
+        // Laden aller Moebel anstoßen
+    furniture=filter(furniture, #'load_furniture_object);
+}
+
+// Diese Funktion bereitet das Reloaden der Einrichtung vor
+static void start_reload_furniture()
+{  
+  // Wenn es keine Moebel gibt, ist das Laden beendet.
+  if (!mappingp(furniture)) return;
+  if (broken_furniture==0) broken_furniture=([]);
+  
+  // Falls ein Key von furniture 0 ist, wird dieser geloescht. 
+  m_delete(furniture,0);
+  
+  // Laden des Furniture anstossen
+  load_furniture();  
+}
+
+
