diff --git a/obj/vitem_shadow.c b/obj/vitem_shadow.c
new file mode 100644
index 0000000..6599288
--- /dev/null
+++ b/obj/vitem_shadow.c
@@ -0,0 +1,344 @@
+#pragma strong_types,rtt_checks
+
+#include <moving.h>
+#include <properties.h>
+#include <container/vitems.h>
+
+// Einschraenkungen: Alle _query_* Querymethoden und _set_* Setmethoden im
+// Ziel werden nicht beschattet.
+
+
+// Alle nicht explizit zum oeffentlichen Interface von /std/container
+// gehoerenden (d.h. alle nicht explizit "public" definierten) Funktionen
+// werden protected geerbt. Damit koennen sie von aussen nicht gerufen werden
+// und der Effekt ist, dass sie nicht im Shadow gerufen werden, sondern im
+// beschatteten Objekt.
+protected functions nosave private variables inherit "/std/container";
+
+// Mapping ohne Values. Keys zeigen an, welche Props dieses Objekt im
+// Zielobjekt beschattet.
+mapping props;
+
+
+protected void create()
+{
+  set_next_reset(7200);
+}
+
+// Einige spezielle Props (wie Details etc. und Props mit Arrays oder
+// Mappings) werden gemerged mit dem Ziel, alle anderen ueberschrieben.
+private void configure_object(object ziel, mapping newprops)
+{
+  props = ([:0]);
+  foreach (string k, mixed v : newprops)
+  {
+    printf("VSH: Prop %s, %O\n", k, v);
+    int reset_prop;
+    if (k[0] == VI_RESET_PREFIX)
+    {
+      reset_prop=1;
+      k=k[1..];
+    }
+    switch(k)
+    {
+      case P_READ_DETAILS:
+        if (reset_prop)
+          RemoveReadDetail(0);
+        else
+          SetProp(P_READ_DETAILS, ziel->QueryProp(P_READ_DETAILS));
+        walk_mapping(v, #'AddReadDetail);
+        break;
+      case P_DETAILS:
+        if (reset_prop)
+          RemoveDetail(0);
+        else
+          SetProp(P_DETAILS, ziel->QueryProp(P_DETAILS));
+        walk_mapping(v, #'AddDetail);
+        break;
+      case P_SMELLS:
+        if (reset_prop)
+          RemoveSmells(0);
+        else
+          SetProp(P_SMELLS, ziel->QueryProp(P_SMELLS));
+        walk_mapping(v, #'AddSmells);
+        break;
+      case P_SOUNDS:
+        if (reset_prop)
+          RemoveSounds(0);
+        else
+          SetProp(P_SOUNDS, ziel->QueryProp(P_SOUNDS));
+        walk_mapping(v, #'AddSounds);
+        break;
+      case P_TOUCH_DETAILS:
+        if (reset_prop)
+          RemoveTouchDetail(0);
+        else
+          SetProp(P_TOUCH_DETAILS, ziel->QueryProp(P_TOUCH_DETAILS));
+        walk_mapping(v, #'AddTouchDetail);
+        break;
+      case P_IDS:
+        if (reset_prop)
+          SetProp(P_IDS, v);
+        else
+        {
+          SetProp(P_IDS, ziel->QueryProp(P_IDS));
+          AddId(v);
+        }
+      case P_CLASS:
+        if (reset_prop)
+          SetProp(P_CLASS, v);
+        else
+        {
+          SetProp(P_CLASS, ziel->QueryProp(P_CLASS));
+          AddClass(v);
+        }
+      case P_ADJECTIVES:
+        if (reset_prop)
+          SetProp(P_ADJECTIVES, v);
+        else
+        {
+          SetProp(P_ADJECTIVES, ziel->QueryProp(P_ADJECTIVES));
+          AddAdjective(v);
+        }
+        break;
+
+      // Alle anderen Properties stumpf setzen.
+      default:
+        if (reset_prop)
+          SetProp(k, v);
+        else
+        {
+          mixed val = ziel->QueryProp(k);
+          // Arrays und Mapping koennen addiert werden, alles andere wird
+          // ueberschrieben.
+          if (pointerp(val) || mappingp(val))
+            SetProp(k, val + v);
+          else
+            SetProp(k, v);
+        }
+     } // switch
+  } // foreach
+}
+
+/*
+xcall 
+/players/zesstra/vitem_shadow->set_shadow(find_object("/players/zesstra/seil#55513
+2"),([P_MATERIAL:([MAT_ICE:100]),P_SHORT:"Eis-Seil"]))
+*/
+public void set_shadow(object target, mapping p)
+{
+  // wenn schon beschattend, ists nen Fehler
+  if (query_shadowing(this_object()))
+      raise_error(sprintf("set_shadow(): Ein Objekt wird schon beschattet: "
+            "%O (Ziel jetzt: %O)\n",query_shadowing(this_object()), target));
+
+  // der Aufrufer muss eine eUID gleich meiner UID haben, damit er das
+  // Beschatten aktivieren kann. (Dieses Objekt hat immer die UID+eUID == eUID
+  // vom Cloner des Shadows, d.h. vom Erzeuger des vItems.) D.h. das
+  // Beschatten kann vom Erzeuger des vItems aktiviert werden.
+  if (getuid(this_object()) == geteuid(previous_object()))
+  {
+    configure_object(target, p);
+    if (shadow(target, 1) != target)
+      raise_error(sprintf("Kann %O nicht beschatten.\n",target));
+  }
+  else
+    raise_error(sprintf("Kann %O nicht beschatten, falsche eUID. "
+                        "Meine: %s, Aufrufer: %s\n",
+                        target, getuid(this_object()),
+                        geteuid(previous_object()) ));
+}
+
+
+varargs int remove(int silent)
+{
+  // Sollten wir gerade etwas beschatten, ist der Aufruf von diesem remove()
+  // evtl. auch der vom Ziel. Wir machen das ganz einfach: Aufruf von remove()
+  // fuehrt zum Entsorgen von Ziel und diesem Objekt.
+  object ziel=query_shadowing(this_object());
+  // und ganz wichtig: nur wenn das Ziel noch ein virtuell anwesendes Items
+  // (vitem) ist, d.h. *kein* Environment hat.
+  if (ziel && !environment(ziel))
+    ziel->remove(1);
+
+  return ::remove(1);
+}
+
+// Dieses Objekt raeumt sich immer im ersten reset auf - es ist kurzlebig und
+// transient und Aenderungen an seinen Daten bleiben nicht erhalten.
+void reset()
+{
+  // BTW: Sollten wir gerade etwas beschatten, ist der Aufruf von diesem
+  // reset() evtl. auch der vom Ziel. (remove kuemmer sich drum)
+  remove(1);
+}
+
+// private ueberschreiben, damit es in diesem Objekt nicht gerufen werden kann
+// und im Beschatteten gerufen wird.
+private varargs void init(object origin)
+{
+}
+
+public varargs int move( object|string dest, int method )
+{
+  object ziel=query_shadowing(this_object());
+  int res;
+  if (ziel)
+  {
+    res=ziel->move(dest, method);
+    if (res == MOVE_OK)
+    {
+      // TODO: environment bescheidsagen, dass das Objekt bewegt wurde.
+      // und nach Bewegung des vitems ist das kein vitem mehr und der Schatten
+      // muss weg.
+      remove(1);
+    }
+  }
+  // Bewegen vom Schatten ist nicht. Und ohne Ziel braucht es den Schatten eh
+  // nicht.
+  else
+  {
+    remove(1);
+    res = ME_WAS_DESTRUCTED;
+  }
+  return res;
+}
+
+// Query und QueryProp liefern die abweichend hier definierten Properties,
+// oder ansonsten die aus dem beschatteten Objekt.
+public mixed QueryProp( string name )
+{
+  object ziel=query_shadowing(this_object());
+  if (ziel && !member(props,name))
+  {
+    return ziel->QueryProp(name);
+  }
+  return ::QueryProp(name);
+}
+
+public varargs mixed Query( string name, int Type )
+{
+  object ziel=query_shadowing(this_object());
+  if (ziel && !member(props,name))
+  {
+    return ziel->Query(name, Type);
+  }
+  return ::Query(name, Type);
+}
+
+public varargs mixed Set( string name, mixed Value, int Type, int extern )
+{
+  // Ab jetzt ist das unsere Prop, die aus dem Beschatteten ist egal.
+  m_add(props,name);
+  return ::Set(name, Value, Type, extern_call());
+}
+
+public mixed SetProp( string name, mixed Value )
+{
+  // Ab jetzt ist das unsere Prop, die aus dem Beschatteten ist egal.
+  m_add(props,name);
+  return ::SetProp(name, Value);
+}
+
+// Details hinzufuegen muss die passende Prop so markieren, dass sie aus
+// diesem Objekt geliefert wird.
+public void AddDetail(string|string* keys, string|string*|mapping|closure descr)
+{
+  // Ab jetzt ist das unsere Prop, die aus dem Beschatteten ist egal.
+  m_add(props,P_DETAILS);
+  m_add(props,P_SPECIAL_DETAILS);
+  return ::AddDetail(keys, descr);
+}
+
+public void AddReadDetail(string|string* keys,
+                   string|string*|mapping|closure descr )
+{
+  // Ab jetzt ist das unsere Prop, die aus dem Beschatteten ist egal.
+  m_add(props,P_READ_DETAILS);
+  return ::AddDetail(keys, descr);
+}
+
+public void AddSounds(string|string* keys,
+               string|string*|mapping|closure descr )
+{
+  // Ab jetzt ist das unsere Prop, die aus dem Beschatteten ist egal.
+  m_add(props,P_SOUNDS);
+  return ::AddDetail(keys, descr);
+}
+
+public void AddSmells(string|string* keys,
+               string|string*|mapping|closure descr )
+{
+  // Ab jetzt ist das unsere Prop, die aus dem Beschatteten ist egal.
+  m_add(props,P_SMELLS);
+  return ::AddDetail(keys, descr);
+}
+
+public void AddTouchDetail(string|string* keys,
+                    string|string*|mapping|closure descr )
+{
+  // Ab jetzt ist das unsere Prop, die aus dem Beschatteten ist egal.
+  m_add(props,P_TOUCH_DETAILS);
+  return ::AddDetail(keys, descr);
+}
+
+// Beides nicht unterstuetzt fuer vitems.
+visible void AddSpecialDetail(string|string* keys, string functionname )
+{
+  raise_error("Nicht unterstuetzt fuer vitem-shadows.\n");
+}
+visible void RemoveSpecialDetail(string|string* keys )
+{
+  raise_error("Nicht unterstuetzt fuer vitem-shadows.\n");
+}
+
+// Wird ggf. auf GetDetail im echten Item umgeleitet, damit jenes FP an
+// Details haben kann und man diese auch findet.
+public varargs string GetDetail(string key, string race, int sense)
+{
+  object ziel=query_shadowing(this_object());
+  if (!ziel)
+    return ::GetDetail(key, race, sense);
+
+  switch(sense)
+  {
+    case SENSE_SMELL: if (member(props, P_SMELLS))
+                          return ::GetDetail(key, race, sense);
+                      break;
+    case SENSE_SOUND: if (member(props, P_SOUNDS))
+                          return ::GetDetail(key, race, sense);
+                      break;
+    case SENSE_TOUCH: if (member(props, P_TOUCH_DETAILS))
+                          return ::GetDetail(key, race, sense);
+                      break;
+    case SENSE_READ:  if (member(props, P_READ_DETAILS))
+                          return ::GetDetail(key, race, sense);
+                      break;
+
+    default:          if (member(props, P_DETAILS))
+                          return ::GetDetail(key, race, sense);
+                      break;
+  }
+  // nix in diesem Objekt, GetDetail vom ziel darfs machen.
+  return ziel->GetDetail(key, race, sense);
+}
+
+// Sollen aus dem Beschatteten kommen
+public object *present_objects( string complex_desc )
+{
+  object ziel=query_shadowing(this_object());
+  if (ziel)
+    return ziel->present_objects(complex_desc);
+  return ::present_objects(complex_desc);
+}
+
+// Sollen aus dem Beschatteten kommen
+public object *locate_objects( string complex_desc, int info )
+{
+  object ziel=query_shadowing(this_object());
+  if (ziel)
+    return ziel->locate_objects(complex_desc, info);
+  return ::locate_objects(complex_desc, info);
+}
+
+
