Index: branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/Index.cs
===================================================================
--- branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/Index.cs	(revision 14537)
+++ branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/Index.cs	(revision 14549)
@@ -20,7 +20,5 @@
 #endregion
 
-using System;
 using System.Collections.Generic;
-using System.Linq;
 using HeuristicLab.PluginInfrastructure;
 
@@ -35,5 +33,5 @@
       this.indexes = new Dictionary<T, uint>();
       this.values = new Dictionary<uint, T>();
-      nextIndex = 0;
+      nextIndex = 1;
     }
     public Index(IEnumerable<T> values)
@@ -47,6 +45,6 @@
 
     public uint GetIndex(T value) {
-      uint index;
-      if (!indexes.TryGetValue(value, out index)) {
+      uint index = 0;
+      if (value != null && !indexes.TryGetValue(value, out index)) {
         index = nextIndex;
         nextIndex++;
@@ -57,5 +55,5 @@
     }
     public T GetValue(uint index) {
-      return values[index];
+      return index == 0 ? null : values[index];
     }
     public IEnumerable<T> GetValues() {
Index: branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/Mapper.cs
===================================================================
--- branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/Mapper.cs	(revision 14537)
+++ branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/Mapper.cs	(revision 14549)
@@ -27,4 +27,20 @@
 namespace HeuristicLab.Persistence {
   public sealed class Mapper {
+    internal class MappingEqualityComparer : IEqualityComparer<object> {
+      bool IEqualityComparer<object>.Equals(object x, object y) {
+        if (x == null && y == null) return true;
+        if (x == null ^ y == null) return false;
+        if (x.GetType() != y.GetType()) return false;
+
+        var type = x.GetType();
+        if (type.IsValueType || type == typeof(string)) return x.Equals(y);
+        return object.ReferenceEquals(x, y);
+      }
+
+      int IEqualityComparer<object>.GetHashCode(object obj) {
+        return obj == null ? 0 : obj.GetHashCode();
+      }
+    }
+
     private static StaticCache staticCache = null;
     private static object locker = new object();
@@ -41,9 +57,9 @@
     private Index<Type> types;
     private Index<string> strings;
-    private Index<Box> boxes;
+    private Dictionary<uint, Box> boxId2Box;
     private Dictionary<object, uint> object2BoxId;
     private Dictionary<uint, object> boxId2object;
 
-    public long BoxCount { get; private set; }
+    public uint BoxCount { get; private set; }
 
     public Mapper() {
@@ -51,6 +67,6 @@
       types = new Index<Type>();
       strings = new Index<string>();
-      boxes = new Index<Box>();
-      object2BoxId = new Dictionary<object, uint>(new ReferenceEqualityComparer<object>());
+      boxId2Box = new Dictionary<uint, Box>();
+      object2BoxId = new Dictionary<object, uint>(new MappingEqualityComparer());
       boxId2object = new Dictionary<uint, object>();
 
@@ -81,17 +97,17 @@
     public uint GetBoxId(object o) {
       uint boxId;
-      if (object2BoxId.TryGetValue(o, out boxId)) return boxId;
 
       if (o == null)
-        boxId = boxes.GetIndex(null);
+        boxId = 0;
       else {
+        if (object2BoxId.TryGetValue(o, out boxId)) return boxId;
         var type = o.GetType();
         var typeInfo = StaticCache.GetTypeInfo(type);
         if (typeInfo.Transformer == null) throw new ArgumentException("Cannot serialize object of type " + o.GetType());
-        BoxCount++;
+        boxId = ++BoxCount;
         typeInfo.Used++;
-        boxId = boxes.GetIndex(typeInfo.Transformer.ToBox(o, this));
+        object2BoxId.Add(o, boxId);
+        boxId2Box.Add(boxId, typeInfo.Transformer.ToBox(o, this));
       }
-      object2BoxId.Add(o, boxId);
       return boxId;
     }
@@ -100,5 +116,7 @@
       if (boxId2object.TryGetValue(boxId, out o)) return o;
 
-      var box = this.boxes.GetValue(boxId);
+      Box box;
+      boxId2Box.TryGetValue(boxId, out box);
+
       if (box == null)
         o = null;
@@ -106,6 +124,7 @@
         var transformer = transformers.GetValue(box.TransformerId);
         o = transformer.ToObject(box, this);
+        boxId2object.Add(boxId, o);
+        transformer.FillFromBox(o, box, this);
       }
-      boxId2object.Add(boxId, o);
       return o;
     }
@@ -122,5 +141,5 @@
       bundle.AddRangeTypeGuids(mapper.types.GetValues().Select(x => StaticCache.GetGuid(x)).Select(x => ByteString.CopyFromUtf8(x)));
       bundle.AddRangeStrings(mapper.strings.GetValues());
-      bundle.AddRangeBoxes(mapper.boxes.GetValues());
+      bundle.AddRangeBoxes(mapper.boxId2Box.OrderBy(x => x.Key).Select(x => x.Value));
       return bundle.Build();
     }
@@ -129,5 +148,5 @@
       mapper.types = new Index<Type>(bundle.TypeGuidsList.Select(x => x.ToStringUtf8()).Select(x => StaticCache.GetType(x)));
       mapper.strings = new Index<string>(bundle.StringsList);
-      mapper.boxes = new Index<Box>(bundle.BoxesList);
+      mapper.boxId2Box = bundle.BoxesList.Select((b, i) => new { Box = b, Index = i }).ToDictionary(k => (uint)k.Index + 1, v => v.Box);
       mapper.transformers = new Index<ITransformer>(bundle.TransformerGuidsList.Select(x => new Guid(x.ToByteArray())).Select(x => StaticCache.GetTransformer(x)));
       return mapper.GetObject(bundle.RootBoxId);
Index: branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/StaticCache.cs
===================================================================
--- branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/StaticCache.cs	(revision 14537)
+++ branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/StaticCache.cs	(revision 14549)
@@ -21,4 +21,5 @@
 
 using System;
+using System.Collections;
 using System.Collections.Generic;
 using System.Drawing;
@@ -103,5 +104,5 @@
       //       RegisterType(new Guid("E92C35AD-32B1-4F37-B8D2-BE2F5FEB465B"), typeof(Dictionary<,>));
 
-
+      RegisterTypeAndFullName(typeof(object));
       RegisterTypeAndFullName(typeof(bool));
       RegisterTypeAndFullName(typeof(byte));
@@ -116,9 +117,21 @@
       RegisterTypeAndFullName(typeof(float));
       RegisterTypeAndFullName(typeof(double));
+      RegisterTypeAndFullName(typeof(decimal));
       RegisterTypeAndFullName(typeof(DateTime));
       RegisterTypeAndFullName(typeof(TimeSpan));
+      RegisterTypeAndFullName(typeof(Font));
       RegisterTypeAndFullName(typeof(Color));
+      RegisterTypeAndFullName(typeof(Bitmap));
       RegisterTypeAndFullName(typeof(Point));
       RegisterTypeAndFullName(typeof(KeyValuePair<,>));
+      RegisterTypeAndFullName(typeof(Tuple<>));
+      RegisterTypeAndFullName(typeof(Tuple<,>));
+      RegisterTypeAndFullName(typeof(Tuple<,,>));
+      RegisterTypeAndFullName(typeof(Tuple<,,,>));
+      RegisterTypeAndFullName(typeof(Tuple<,,,,>));
+      RegisterTypeAndFullName(typeof(Tuple<,,,,,>));
+      RegisterTypeAndFullName(typeof(Tuple<,,,,,,>));
+      RegisterTypeAndFullName(typeof(Tuple<,,,,,,,>));
+      RegisterTypeAndFullName(typeof(Nullable<>));
       RegisterTypeAndFullName(typeof(string));
 
@@ -138,12 +151,14 @@
       RegisterTypeAndFullName(typeof(string[]));
       RegisterTypeAndFullName(typeof(List<>));
+      RegisterTypeAndFullName(typeof(ArrayList));
+      RegisterTypeAndFullName(typeof(HashSet<>));
       RegisterTypeAndFullName(typeof(Stack<>));
-      RegisterTypeAndFullName(typeof(System.Collections.Stack));
-      RegisterTypeAndFullName(typeof(HashSet<>));
+      RegisterTypeAndFullName(typeof(Stack));
+      RegisterTypeAndFullName(typeof(Queue<>));
+      RegisterTypeAndFullName(typeof(Queue));
       RegisterTypeAndFullName(typeof(Dictionary<,>));
 
-
       foreach (var asm in AppDomain.CurrentDomain.GetAssemblies()) {
-        foreach (var t in asm.GetTypes().Where(x => StorableClassAttribute.IsStorableClass(x)))
+        foreach (var t in asm.GetTypes().Where(x => StorableClassAttribute.IsStorableClass(x) || x.IsValueType && !x.IsPrimitive && !x.IsEnum && x.IsSealed))
           RegisterTypeAndFullName(t);
       }
Index: branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/Transformer.cs
===================================================================
--- branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/Transformer.cs	(revision 14537)
+++ branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/Transformer.cs	(revision 14549)
@@ -35,4 +35,6 @@
     public abstract Box ToBox(object o, Mapper mapper);
     public abstract object ToObject(Box box, Mapper mapper);
+
+    public virtual void FillFromBox(object obj, Box box, Mapper mapper) { }
   }
 }
Index: branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/TypeInfo.cs
===================================================================
--- branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/TypeInfo.cs	(revision 14537)
+++ branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/TypeInfo.cs	(revision 14549)
@@ -72,19 +72,26 @@
         while (types.Count > 0) {
           type = types.Pop();
-          var fieldInfos = type.GetFields(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic).
-                           Where(x => StorableAttribute.IsStorable(x));
-          foreach (var field in fieldInfos) {
-            var attrib = StorableAttribute.GetStorableAttribute(field);
-            var name = string.IsNullOrEmpty(attrib.Name) ? field.Name : attrib.Name;
-            fields.Add(new ComponentInfo(name, field, attrib, true, true));
+          if (StorableClassAttribute.Type != StorableClassType.AllProperties) {
+            var fieldInfos = type.GetFields(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic)
+                                 .Where(x => !x.Name.StartsWith("<") && !x.Name.EndsWith("k__BackingField")); // exclude backing fields
+            if (StorableClassAttribute.Type == StorableClassType.MarkedOnly)
+              fieldInfos = fieldInfos.Where(x => StorableAttribute.IsStorable(x)).ToArray();
+            foreach (var field in fieldInfos) {
+              var attrib = StorableAttribute.GetStorableAttribute(field);
+              var name = attrib == null || string.IsNullOrEmpty(attrib.Name) ? field.Name : attrib.Name;
+              fields.Add(new ComponentInfo(type.Name + '.' + name, field, attrib, true, true));
+            }
           }
 
-          var propertyInfos = type.GetProperties(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic).
-                      Where(x => x.GetIndexParameters().Length == 0).  // exclude indexed properties
-                      Where(x => StorableAttribute.IsStorable(x));
-          foreach (var property in propertyInfos) {
-            var attrib = StorableAttribute.GetStorableAttribute(property);
-            var name = string.IsNullOrEmpty(attrib.Name) ? property.Name : attrib.Name;
-            properties.Add(new ComponentInfo(name, property, attrib, property.CanRead, property.CanWrite));
+          if (StorableClassAttribute.Type != StorableClassType.AllFields) {
+            var propertyInfos = type.GetProperties(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic).
+                        Where(x => x.GetIndexParameters().Length == 0);  // exclude indexed properties
+            if (StorableClassAttribute.Type == StorableClassType.MarkedOnly)
+              propertyInfos = propertyInfos.Where(x => StorableAttribute.IsStorable(x)).ToArray();
+            foreach (var property in propertyInfos) {
+              var attrib = StorableAttribute.GetStorableAttribute(property);
+              var name = attrib == null || string.IsNullOrEmpty(attrib.Name) ? property.Name : attrib.Name;
+              properties.Add(new ComponentInfo(type.Name + '.' + name, property, attrib, property.CanRead, property.CanWrite));
+            }
           }
 
Index: branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/ITransformer.cs
===================================================================
--- branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/ITransformer.cs	(revision 14537)
+++ branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/ITransformer.cs	(revision 14549)
@@ -30,4 +30,5 @@
     Box ToBox(object o, Mapper mapper);
     object ToObject(Box box, Mapper mapper);
+    void FillFromBox(object obj, Box box, Mapper mapper);
   }
 }
Index: branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Transformers/StorableClassTransformer.cs
===================================================================
--- branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Transformers/StorableClassTransformer.cs	(revision 14537)
+++ branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Transformers/StorableClassTransformer.cs	(revision 14549)
@@ -63,7 +63,10 @@
 
     protected override object Extract(Box box, Type type, Mapper mapper) {
+      return mapper.CreateInstance(type);
+    }
+    public override void FillFromBox(object obj, Box box, Mapper mapper) {
       var data = box.GetExtension(StorableClassBox.StorableClass);
+      var type = obj.GetType();
       var typeInfo = Mapper.StaticCache.GetTypeInfo(type);
-      var o = mapper.CreateInstance(type);
 
       var components = new Dictionary<uint, uint>();
@@ -76,5 +79,5 @@
         uint componentId;
         bool found = components.TryGetValue(mapper.GetStringId(componentInfo.Name), out componentId);
-        field.SetValue(o, found ? mapper.GetObject(componentId) : componentInfo.StorableAttribute.DefaultValue);
+        field.SetValue(obj, found ? mapper.GetObject(componentId) : componentInfo.StorableAttribute.DefaultValue);
       }
 
@@ -83,13 +86,11 @@
         uint componentId;
         bool found = components.TryGetValue(mapper.GetStringId(componentInfo.Name), out componentId);
-        property.SetValue(o, found ? mapper.GetObject(componentId) : componentInfo.StorableAttribute.DefaultValue, null);
+        property.SetValue(obj, found ? mapper.GetObject(componentId) : componentInfo.StorableAttribute.DefaultValue, null);
       }
 
       var emptyArgs = new object[0];
       foreach (var hook in typeInfo.AfterDeserializationHooks) {
-        hook.Invoke(o, emptyArgs);
+        hook.Invoke(obj, emptyArgs);
       }
-
-      return o;
     }
   }
Index: branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Transformers/Transformers.cs
===================================================================
--- branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Transformers/Transformers.cs	(revision 14537)
+++ branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Transformers/Transformers.cs	(revision 14549)
@@ -23,7 +23,13 @@
 using System.Collections;
 using System.Collections.Generic;
+using System.ComponentModel;
 using System.Drawing;
+using System.Drawing.Imaging;
+using System.Globalization;
+using System.IO;
 using System.Linq;
+using System.Reflection;
 using Google.ProtocolBuffers;
+using HeuristicLab.Persistence.Core;
 
 namespace HeuristicLab.Persistence {
@@ -36,10 +42,10 @@
       var box = Box.CreateBuilder();
       box.TransformerId = mapper.GetTransformerId(this);
-      box.TypeId = mapper.GetTypeId(o.GetType());
+      box.TypeId = mapper.GetBoxId(o.GetType());
       Populate(box, (T)o, mapper);
       return box.Build();
     }
     public override object ToObject(Box box, Mapper mapper) {
-      return Extract(box, mapper.GetType(box.TypeId), mapper);
+      return Extract(box, (Type)mapper.GetObject(box.TypeId), mapper);
     }
     protected abstract void Populate(Box.Builder box, T value, Mapper mapper);
@@ -269,5 +275,51 @@
   #endregion
 
+  [Transformer("11B822C9-46A0-4B65-AE4A-D12F63DDE9F6", 50)]
+  internal sealed class TypeTransformer : Transformer {
+    public override bool CanTransformType(Type type) {
+      return typeof(Type).IsAssignableFrom(type);
+    }
+    public override Box ToBox(object o, Mapper mapper) {
+      var box = Box.CreateBuilder();
+      box.TransformerId = mapper.GetTransformerId(this);
+      Populate(box, o, mapper);
+      return box.Build();
+    }
+    private void Populate(Box.Builder box, object value, Mapper mapper) {
+      var type = (Type)value;
+      var typeBox = TypeBox.CreateBuilder();
+      if (type.IsGenericType) {
+        box.TypeId = mapper.GetTypeId(type.GetGenericTypeDefinition());
+        typeBox.AddRangeGenericTypeIds(type.GetGenericArguments().Select(t => mapper.GetBoxId(t)));
+      } else if (type.IsArray) {
+        box.TypeId = mapper.GetTypeId(typeof(Array));
+        typeBox.AddGenericTypeIds(mapper.GetBoxId(type.GetElementType()));
+      } else {
+        box.TypeId = mapper.GetTypeId(type);
+      }
+      box.SetExtension(TypeBox.Type, typeBox.Build());
+    }
+    public override object ToObject(Box box, Mapper mapper) {
+      return Extract(box, mapper.GetType(box.TypeId), mapper);
+    }
+    private object Extract(Box box, Type type, Mapper mapper) {
+      var b = box.GetExtension(TypeBox.Type);
+      if (type.IsGenericType) {
+        return type.MakeGenericType(b.GenericTypeIdsList.Select(id => (Type)mapper.GetObject(id)).ToArray());
+      } else if (type == typeof(Array)) {
+        return ((Type)mapper.GetObject(b.GetGenericTypeIds(0))).MakeArrayType();
+      } else {
+        return type;
+      }
+    }
+  }
+
   #region Primitive Value Types
+  [Transformer("268617FE-3F0F-4029-8248-EDA420901FB6", 10000)]
+  internal sealed class ObjectTransformer : BoxTransformer<object> {
+    protected override void Populate(Box.Builder box, object value, Mapper mapper) { }
+    protected override object Extract(Box box, Type type, Mapper mapper) { return new object(); }
+  }
+
   [Transformer("9FA1C6A8-517E-4623-AC1B-7E9AEF6ED13D", 200)]
   internal sealed class BoolTransformer : BoolBoxTransformer<bool> {
@@ -367,19 +419,53 @@
 
   [Transformer("97B5CFC8-CDFA-4EB5-B4CD-5B3CFA5CD844", 216)]
-  internal sealed class KeyValuePairTransformer : UnsignedIntArrayBoxTransformer<object> {
+  internal sealed class KeyValuePairTransformer : BoxTransformer<object> {
     public override bool CanTransformType(Type type) {
       return type.IsGenericType && (type.GetGenericTypeDefinition() == typeof(KeyValuePair<,>));
     }
-    protected override IEnumerable<uint> ToBoxType(object value, Mapper mapper) {
+    protected override void Populate(Box.Builder box, object value, Mapper mapper) {
+      var b = UnsignedIntArrayBox.CreateBuilder();
       var type = value.GetType();
       var pair = new uint[2];
       pair[0] = mapper.GetBoxId(type.GetProperty("Key").GetValue(value));
       pair[1] = mapper.GetBoxId(type.GetProperty("Value").GetValue(value));
-      return pair;
-    }
-    protected override object ToValueType(IEnumerable<uint> value, Type type, Mapper mapper) {
-      var key = mapper.GetObject(value.ElementAt(0));
-      var val = mapper.GetObject(value.ElementAt(1));
-      return Activator.CreateInstance(type, key, val);
+      b.AddRangeValues(pair);
+      box.SetExtension(UnsignedIntArrayBox.UnsignedIntArray, b.Build());
+    }
+    public override void FillFromBox(object obj, Box box, Mapper mapper) {
+      var b = box.GetExtension(UnsignedIntArrayBox.UnsignedIntArray);
+      var key = mapper.GetObject(b.GetValues(0));
+      var val = mapper.GetObject(b.GetValues(1));
+      var type = obj.GetType();
+      //DataMemberAccessor.GenerateFieldSetter(type.GetField("key", BindingFlags.NonPublic | BindingFlags.Instance))(obj, key);
+      //DataMemberAccessor.GenerateFieldSetter(type.GetField("value", BindingFlags.NonPublic | BindingFlags.Instance))(obj, val);
+      type.GetField("key", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(obj, key);
+      type.GetField("value", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(obj, val);
+    }
+    protected override object Extract(Box box, Type type, Mapper mapper) {
+      return Activator.CreateInstance(type);
+    }
+  }
+
+  [Transformer("EBD8BF65-D97D-4FD4-BF4F-9D58A72B6249", 217)]
+  internal sealed class DecimalTransformer : UnsignedIntBoxTransformer<decimal> {
+    protected override uint ToBoxType(decimal value, Mapper mapper) {
+      return mapper.GetStringId(FormatG30(value));
+    }
+    protected override decimal ToValueType(uint value, Type type, Mapper mapper) {
+      var converter = TypeDescriptor.GetConverter(typeof(Font));
+      return ParseG30(mapper.GetString(value));
+    }
+    private static decimal ParseG30(string s) {
+      decimal d;
+      if (decimal.TryParse(s,
+        NumberStyles.AllowDecimalPoint |
+        NumberStyles.AllowExponent |
+        NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture, out d))
+        return d;
+      throw new FormatException(
+        string.Format("Invalid decimal G30 number format \"{0}\" could not be parsed", s));
+    }
+    private static string FormatG30(decimal d) {
+      return d.ToString("g30", CultureInfo.InvariantCulture);
     }
   }
@@ -387,5 +473,5 @@
 
   #region String
-  [Transformer("E75A594C-0034-4DAB-B28E-8F84F9F6DE8D", 217)]
+  [Transformer("E75A594C-0034-4DAB-B28E-8F84F9F6DE8D", 218)]
   internal sealed class StringTransformer : UnsignedIntBoxTransformer<string> {
     protected override uint ToBoxType(string value, Mapper mapper) { return mapper.GetStringId(value); }
@@ -395,5 +481,5 @@
 
   #region Enum
-  [Transformer("93FF076B-BC4B-4C39-8C40-15E004468C98", 218)]
+  [Transformer("93FF076B-BC4B-4C39-8C40-15E004468C98", 219)]
   internal sealed class EnumTransformer : Transformer {
     public override bool CanTransformType(Type type) {
@@ -420,24 +506,169 @@
   #endregion
 
-  //   #region Type
-  //   [Transformer("8D17FD28-383B-44E9-9BBF-B19D351C5E38", 219)]
-  //   internal sealed class TypeTransformer : Transformer {
-  //     public override bool CanTransformType(Type type) {
-  //       return typeof(Type).IsAssignableFrom(type);
-  //     }
-  //     public override Box ToBox(object o, Mapper mapper) {
-  //       var boxBuilder = Box.CreateBuilder();
-  // 
-  //       boxBuilder.TransformerId = mapper.GetTransformerId(this);
-  //       boxBuilder.TypeId = mapper.GetStringId(((Type)o).AssemblyQualifiedName);
-  // 
-  //       return boxBuilder.Build();
-  //     }
-  // 
-  //     public override object ToObject(Box box, Mapper mapper) {
-  //       return Type.GetType(mapper.GetString(box.TypeId));
-  //     }
-  //   }
-  //   #endregion
+  #region Struct
+  [Transformer("89DAAFC5-726C-48D4-A4E0-2B0D27329642", 220)]
+  internal sealed class StructTransformer : Transformer {
+    public override bool CanTransformType(Type type) {
+      return type.IsValueType && !type.IsPrimitive && !type.IsEnum && type.IsSealed;
+    }
+    public override Box ToBox(object o, Mapper mapper) {
+      var box = Box.CreateBuilder();
+      box.TransformerId = mapper.GetTransformerId(this);
+      Populate(box, o, mapper);
+      return box.Build();
+    }
+    public override object ToObject(Box box, Mapper mapper) {
+      return Extract(box, (Type)mapper.GetObject(box.TypeId), mapper);
+    }
+    private void Populate(Box.Builder box, object value, Mapper mapper) {
+      var b = StorableClassBox.CreateBuilder();
+      var type = value.GetType();
+
+      var components = new Dictionary<uint, uint>();
+      foreach (var fieldInfo in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) {
+        var component = mapper.GetBoxId(fieldInfo.GetValue(value));
+        components.Add(mapper.GetStringId(fieldInfo.Name), component);
+      }
+
+      b.AddRangeKeyIds(components.Keys);
+      b.AddRangeValueIds(components.Values);
+
+      box.TypeId = mapper.GetBoxId(type);
+      box.SetExtension(StorableClassBox.StorableClass, b.Build());
+    }
+    private object Extract(Box box, Type type, Mapper mapper) {
+      var data = box.GetExtension(StorableClassBox.StorableClass);
+      var obj = Activator.CreateInstance(type);
+
+      var components = new Dictionary<uint, uint>();
+      for (int i = 0; i < data.KeyIdsList.Count; i++) {
+        components.Add(data.KeyIdsList[i], data.ValueIdsList[i]);
+      }
+
+      foreach (var t in components) {
+        string name = mapper.GetString(t.Key);
+        MemberInfo[] mis = type.GetMember(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
+        if (mis.Length != 1)
+          throw new Exception("ambiguous struct member name " + name);
+        MemberInfo mi = mis[0];
+        if (mi.MemberType == MemberTypes.Field)
+          ((FieldInfo)mi).SetValue(obj, mapper.GetObject(t.Value));
+        else
+          throw new Exception("invalid struct member type " + mi.MemberType.ToString());
+      }
+
+      return obj;
+    }
+  }
+  #endregion
+
+  #region Tuple
+  [Transformer("63A19D57-EEEF-4346-9F06-B35B15EBFFA3", 221)]
+  internal sealed class TupleTransformer : Transformer {
+    private static readonly HashSet<Type> supportedTypes = new HashSet<Type> {
+      typeof(Tuple<>), typeof(Tuple<,>), typeof(Tuple<,,>), typeof(Tuple<,,,>),
+      typeof(Tuple<,,,,>), typeof(Tuple<,,,,,>), typeof(Tuple<,,,,,,>), typeof(Tuple<,,,,,,,>)
+    };
+    public override bool CanTransformType(Type type) {
+      return type.IsGenericType && supportedTypes.Contains(type.GetGenericTypeDefinition());
+    }
+    public override Box ToBox(object o, Mapper mapper) {
+      var box = Box.CreateBuilder();
+      box.TransformerId = mapper.GetTransformerId(this);
+      Populate(box, o, mapper);
+      return box.Build();
+    }
+    private void Populate(Box.Builder box, object value, Mapper mapper) {
+      var type = value.GetType();
+      var uIntArrayBox = UnsignedIntArrayBox.CreateBuilder();
+      for (int i = 1; i <= type.GetGenericArguments().Length; i++) {
+        string name = string.Format("Item{0}", i);
+        uIntArrayBox.AddValues(mapper.GetBoxId(type.GetProperty(name).GetValue(value)));
+      }
+      box.TypeId = mapper.GetBoxId(type);
+      box.SetExtension(UnsignedIntArrayBox.UnsignedIntArray, uIntArrayBox.Build());
+    }
+    public override object ToObject(Box box, Mapper mapper) {
+      var type = (Type)mapper.GetObject(box.TypeId);
+      var defaultValues = type.GetGenericArguments().Select(x =>
+        x.IsValueType ? Activator.CreateInstance(x) : null
+      ).ToArray();
+      return Activator.CreateInstance(type, defaultValues);
+    }
+    public override void FillFromBox(object obj, Box box, Mapper mapper) {
+      var uIntArrayBox = box.GetExtension(UnsignedIntArrayBox.UnsignedIntArray);
+      var elements = uIntArrayBox.ValuesList.Select(mapper.GetObject).ToArray();
+      var type = obj.GetType();
+      for (int i = 1; i <= elements.Length; i++) {
+        string name = string.Format("m_Item{0}", i);
+        DataMemberAccessor.GenerateFieldSetter(type.GetField(name, BindingFlags.NonPublic | BindingFlags.Instance))(obj, elements[i - 1]);
+      }
+    }
+  }
+  #endregion
+
+  #region Bitmap
+  [Transformer("D0ADB806-2DFD-459D-B5DA-14B5F1152534", 222)]
+  internal sealed class BitmapTransformer : ByteArrayBoxTransformer<Bitmap> {
+    protected override ByteString ToByteString(Bitmap value) {
+      lock (value)
+        using (var ms = new MemoryStream()) {
+          value.Save(ms, ImageFormat.Png);
+          return ByteString.CopyFrom(ms.ToArray());
+        }
+    }
+    protected override Bitmap FromByteString(ByteString byteString) {
+      using (var ms = new MemoryStream()) {
+        ms.Write(byteString.ToArray(), 0, byteString.Length);
+        ms.Seek(0, SeekOrigin.Begin);
+        return new Bitmap(ms);
+      }
+    }
+  }
+  #endregion
+
+  #region Font
+  [Transformer("AFF27987-3301-4D70-9601-EFCA31BDA0DB", 223)]
+  internal sealed class FontTransformer : UnsignedIntArrayBoxTransformer<Font> {
+
+    protected override IEnumerable<uint> ToBoxType(Font value, Mapper mapper) {
+      yield return mapper.GetStringId(GetFontFamilyName(value.FontFamily));
+      yield return mapper.GetBoxId(value.Size);
+      yield return mapper.GetBoxId(value.Style);
+      yield return mapper.GetBoxId(value.Unit);
+      yield return mapper.GetBoxId(value.GdiCharSet);
+      yield return mapper.GetBoxId(value.GdiVerticalFont);
+    }
+    protected override Font ToValueType(IEnumerable<uint> value, Type type, Mapper mapper) {
+      var fontData = value.ToArray();
+      return new Font(
+        GetFontFamily(mapper.GetString(fontData[0])),
+        (float)mapper.GetObject(fontData[1]),
+        (FontStyle)mapper.GetObject(fontData[2]),
+        (GraphicsUnit)mapper.GetObject(fontData[3]),
+        (byte)mapper.GetObject(fontData[4]),
+        (bool)mapper.GetObject(fontData[5])
+      );
+    }
+
+    public const string GENERIC_MONOSPACE_NAME = "_GenericMonospace";
+    public const string GENERIC_SANS_SERIF_NAME = "_GenericSansSerif";
+    public const string GENERIC_SERIF_NAME = "_GenericSerif";
+
+    public static FontFamily GetFontFamily(string name) {
+      if (name == GENERIC_MONOSPACE_NAME) return FontFamily.GenericMonospace;
+      if (name == GENERIC_SANS_SERIF_NAME) return FontFamily.GenericSansSerif;
+      if (name == GENERIC_SERIF_NAME) return FontFamily.GenericSerif;
+      return new FontFamily(name);
+    }
+
+    public static string GetFontFamilyName(FontFamily ff) {
+      if (ff.Equals(FontFamily.GenericMonospace)) return GENERIC_MONOSPACE_NAME;
+      if (ff.Equals(FontFamily.GenericSansSerif)) return GENERIC_SANS_SERIF_NAME;
+      if (ff.Equals(FontFamily.GenericSerif)) return GENERIC_SERIF_NAME;
+      return ff.Name;
+    }
+  }
+  #endregion
 
   #region Array Types
@@ -570,53 +801,51 @@
   }
 
-  //[Transformer("C83F0B5A-68D8-4271-81F9-FF259FC6F126", 400)]
-  //internal sealed class GenericArrayTransformer : UnsignedIntArrayBoxTransformer<object> {
-  //  public override bool CanTransformType(Type type) {
-  //    return type.IsArray;
-  //  }
-  //  protected override IEnumerable<uint> ToBoxType(object value, Mapper mapper) {
-  //    var arr = (object[])value;
-  //    return arr.Select(x => mapper.GetBoxId(x));
-  //  }
-  //  protected override object ToValueType(IEnumerable<uint> value, Type type, Mapper mapper) {
-  //    return value.Select(x => mapper.GetObject(x)).ToArray();
-  //  }
-  //}
-
-  //   internal sealed class QueueTransformer : Transformer {
-  //     public override bool CanTransformType(Type type) {
-  //       return type == typeof(System.Collections.Queue) || type == typeof(Queue<>);
-  //     }
-  //     public override Box ToBox(object o, Mapper mapper) {
-  //       var box = Box.CreateBuilder();
-  //       box.TransformerId = mapper.GetTransformerId(this);
-  //       Populate(box, o, mapper);
-  //       return box.Build();
-  //     }
-  //     public override object ToObject(Box box, Mapper mapper) {
-  //       return Extract(box, mapper.GetType(box.TypeId), mapper);
-  //     }
-  //     private void Populate(Box.Builder box, object value, Mapper mapper) {
-  //       var elements = (System.Collections.IEnumerable)value;
-  //       if (value.GetType().IsGenericType) {
-  //         var elementType = value.GetType().GetGenericTypeDefinition().GetGenericArguments().First();
-  //         box.TypeId = mapper.GetTypeId(elementType);
-  //       }
-  // 
-  //       var b = UnsignedIntArrayBox.CreateBuilder();
-  //       foreach (var elem in elements) {
-  //         b.AddValues(mapper.GetBoxId(elem));
-  //       }
-  // 
-  //       box.SetExtension(UnsignedIntArrayBox.UnsignedIntArray, b.Build());
-  //     }
-  //     private object Extract(Box box, Type type, Mapper mapper) {
-  //     }
-  //   }
-
-  [Transformer("B01ADF0A-ACAA-444E-9F82-0C7C2AF1F490", 2000)]
+  [Transformer("B01ADF0A-ACAA-444E-9F82-0C7C2AF1F490", 400)]
   internal sealed class ArrayTransformer : Transformer {
     public override bool CanTransformType(Type type) {
       return type.IsArray;
+    }
+    public override Box ToBox(object o, Mapper mapper) {
+      Array arr = (Array)o;
+      if (arr.GetLowerBound(0) != 0 || arr.Rank > 1) throw new NotSupportedException();
+
+      var box = Box.CreateBuilder();
+      box.TransformerId = mapper.GetTransformerId(this);
+      Populate(box, o, mapper);
+      return box.Build();
+    }
+    private void Populate(Box.Builder box, object value, Mapper mapper) {
+      var array = (Array)value;
+      var elementType = value.GetType().GetElementType();
+
+      var uIntArrayBox = UnsignedIntArrayBox.CreateBuilder();
+      foreach (var item in (IEnumerable)array)
+        uIntArrayBox.AddValues(mapper.GetBoxId(item));
+
+      box.TypeId = mapper.GetBoxId(elementType);
+      box.SetExtension(UnsignedIntArrayBox.UnsignedIntArray, uIntArrayBox.Build());
+    }
+    public override object ToObject(Box box, Mapper mapper) {
+      var uIntArrayBox = box.GetExtension(UnsignedIntArrayBox.UnsignedIntArray);
+      var type = (Type)mapper.GetObject(box.TypeId);
+      return Array.CreateInstance(type, uIntArrayBox.ValuesCount);
+    }
+    public override void FillFromBox(object obj, Box box, Mapper mapper) {
+      var uIntArrayBox = box.GetExtension(UnsignedIntArrayBox.UnsignedIntArray);
+      Array.Copy(uIntArrayBox.ValuesList.Select(x => mapper.GetObject(x)).ToArray(), (Array)obj, uIntArrayBox.ValuesCount);
+    }
+  }
+  #endregion
+
+  [Transformer("4FA5EAAF-ECC7-4A9C-84E7-6583DA96F3B9", 500)]
+  internal sealed class EnumerableTransformer : Transformer {
+    private static readonly HashSet<Type> supportedTypes = new HashSet<Type> {
+      typeof(Stack<>), typeof(Stack),
+      typeof(Queue<>), typeof(Queue),
+      typeof(HashSet<>),
+      typeof(List<>), typeof(ArrayList)
+    };
+    public override bool CanTransformType(Type type) {
+      return type.IsGenericType && supportedTypes.Contains(type.GetGenericTypeDefinition()) || supportedTypes.Contains(type);
     }
     public override Box ToBox(object o, Mapper mapper) {
@@ -626,36 +855,41 @@
       return box.Build();
     }
+    private void Populate(Box.Builder box, object value, Mapper mapper) {
+      var uIntArrayBox = UnsignedIntArrayBox.CreateBuilder();
+      foreach (var item in (IEnumerable)value)
+        uIntArrayBox.AddValues(mapper.GetBoxId(item));
+      box.TypeId = mapper.GetBoxId(value.GetType());
+      box.SetExtension(UnsignedIntArrayBox.UnsignedIntArray, uIntArrayBox.Build());
+    }
     public override object ToObject(Box box, Mapper mapper) {
-      return Extract(box, (Type)mapper.GetObject(box.TypeId), mapper);
-    }
-    private void Populate(Box.Builder box, object value, Mapper mapper) {
-      var array = (object[])value;
-      var elementType = value.GetType().GetElementType();
-
-      var b = UnsignedIntArrayBox.CreateBuilder();
-      b.AddRangeValues(array.Select(x => mapper.GetBoxId(x)));
-
-      box.TypeId = mapper.GetBoxId(elementType);
-      box.SetExtension(UnsignedIntArrayBox.UnsignedIntArray, b.Build());
-    }
-    private object Extract(Box box, Type type, Mapper mapper) {
-      var b = box.GetExtension(UnsignedIntArrayBox.UnsignedIntArray);
-
-      var array = (object[])Array.CreateInstance((Type)mapper.GetObject(box.TypeId), b.ValuesCount);
-
-      for (int i = 0; i < array.Length; i++) {
-        array[i] = mapper.GetObject(b.GetValues(i));
-      }
-
-      return array;
-    }
-  }
-
-  [Transformer("11B822C9-46A0-4B65-AE4A-D12F63DDE9F6", 1)]
-  internal sealed class TypeTransformer : Transformer {
+      var uIntArrayBox = box.GetExtension(UnsignedIntArrayBox.UnsignedIntArray);
+      var type = (Type)mapper.GetObject(box.TypeId);
+      return Activator.CreateInstance(type, uIntArrayBox.ValuesCount);
+    }
+    public override void FillFromBox(object obj, Box box, Mapper mapper) {
+      var uIntArrayBox = box.GetExtension(UnsignedIntArrayBox.UnsignedIntArray);
+      var elements = uIntArrayBox.ValuesList.Select(mapper.GetObject);
+      var type = obj.GetType();
+      string methodName = string.Empty;
+      if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Stack<>) || type == typeof(Stack)) {
+        elements = elements.Reverse();
+        methodName = "Push";
+      } else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Queue<>) || type == typeof(Queue)) {
+        methodName = "Enqueue";
+      } else {
+        methodName = "Add";
+      }
+
+      MethodInfo addMethod = type.GetMethod(methodName);
+      foreach (var e in elements)
+        addMethod.Invoke(obj, new[] { e });
+    }
+  }
+
+  [Transformer("C47A62F5-F113-4A43-A8EE-CF817EC799A2", 501)]
+  internal sealed class DictionaryTransformer : Transformer {
     public override bool CanTransformType(Type type) {
-      return typeof(Type).IsAssignableFrom(type);
-    }
-
+      return type.IsGenericType && typeof(Dictionary<,>) == type.GetGenericTypeDefinition();
+    }
     public override Box ToBox(object o, Mapper mapper) {
       var box = Box.CreateBuilder();
@@ -664,97 +898,4 @@
       return box.Build();
     }
-
-    private void Populate(Box.Builder box, object o, Mapper mapper) {
-      var type = (Type)o;
-
-      var b = TypeBox.CreateBuilder();
-      if (type.IsGenericType) {
-        box.TypeId = mapper.GetTypeId(type.GetGenericTypeDefinition());
-        b.AddRangeGenericTypeIds(type.GetGenericArguments().Select(t => mapper.GetBoxId(t)));
-      } else if (type.IsArray) {
-        box.TypeId = mapper.GetTypeId(typeof(Array));
-        b.AddGenericTypeIds(mapper.GetBoxId(type.GetElementType()));
-      } else {
-        box.TypeId = mapper.GetTypeId(type);
-      }
-      box.SetExtension(TypeBox.Type, b.Build());
-    }
-
-    public override object ToObject(Box box, Mapper mapper) {
-      return Extract(box, mapper.GetType(box.TypeId), mapper);
-    }
-
-    private object Extract(Box box, Type type, Mapper mapper) {
-      var b = box.GetExtension(TypeBox.Type);
-      if (b.GenericTypeIdsCount > 0) {
-        if (typeof(Array).IsAssignableFrom(type)) {
-          return ((Type)mapper.GetObject(b.GetGenericTypeIds(0))).MakeArrayType();
-        } else {
-          return type.MakeGenericType(b.GenericTypeIdsList.Select(id => (Type)mapper.GetObject(id)).ToArray());
-        }
-      } else {
-        return mapper.GetType(box.TypeId);
-      }
-    }
-  }
-
-  [Transformer("4FA5EAAF-ECC7-4A9C-84E7-6583DA96F3B9", 1000)]
-  internal sealed class EnumerableTransformer : Transformer {
-    public override bool CanTransformType(Type type) {
-      return (type.IsGenericType && typeof(Stack<>) == type.GetGenericTypeDefinition()) ||
-             type == typeof(System.Collections.Stack);
-    }
-    public override Box ToBox(object o, Mapper mapper) {
-      var box = Box.CreateBuilder();
-      box.TransformerId = mapper.GetTransformerId(this);
-      Populate(box, o, mapper);
-      return box.Build();
-    }
-    public override object ToObject(Box box, Mapper mapper) {
-      return Extract(box, (Type)mapper.GetObject(box.TypeId), mapper);
-    }
-    private void Populate(Box.Builder box, object value, Mapper mapper) {
-      var enumerableBox = UnsignedIntArrayBox.CreateBuilder();
-      box.TypeId = mapper.GetBoxId(value.GetType());
-      enumerableBox.AddRangeValues(((IEnumerable)value).OfType<object>().Select(mapper.GetBoxId));
-
-      box.SetExtension(UnsignedIntArrayBox.UnsignedIntArray, enumerableBox.Build());
-    }
-    private object Extract(Box box, Type type, Mapper mapper) {
-      var enumerableBox = box.GetExtension(UnsignedIntArrayBox.UnsignedIntArray);
-      if ((type.IsGenericType && typeof(Stack<>) == type.GetGenericTypeDefinition())) {
-        var elemType = type.GenericTypeArguments[0];
-        var stack = Activator.CreateInstance(type);
-        var addMeth = type.GetMethod("Push");
-        foreach (var e in enumerableBox.ValuesList.Select(mapper.GetObject).Reverse())
-          addMeth.Invoke(stack, new[] { e });
-        return stack;
-      } else if (typeof(Stack).IsAssignableFrom(type)) {
-        var l = new System.Collections.ArrayList();
-        foreach (var e in enumerableBox.ValuesList.Select(mapper.GetObject)) {
-          l.Add(e);
-        }
-        l.Reverse();
-        return Activator.CreateInstance(type, l);
-      } else {
-        throw new NotSupportedException();
-      }
-    }
-  }
-
-  [Transformer("C47A62F5-F113-4A43-A8EE-CF817EC799A2", 500)]
-  internal sealed class DictionaryTransformer : Transformer {
-    public override bool CanTransformType(Type type) {
-      return type.IsGenericType && typeof(IDictionary<,>).IsAssignableFrom(type);
-    }
-    public override Box ToBox(object o, Mapper mapper) {
-      var box = Box.CreateBuilder();
-      box.TransformerId = mapper.GetTransformerId(this);
-      Populate(box, o, mapper);
-      return box.Build();
-    }
-    public override object ToObject(Box box, Mapper mapper) {
-      return Extract(box, mapper.GetType(box.TypeId), mapper);
-    }
     private void Populate(Box.Builder box, object value, Mapper mapper) {
       var dictionaryBox = DictionaryBox.CreateBuilder();
@@ -763,10 +904,28 @@
         dictionaryBox.AddValueIds(mapper.GetBoxId(item.Value));
       }
-      // TODO: comparer
-    }
-    private object Extract(Box box, Type type, Mapper mapper) {
-      throw new NotImplementedException();
-    }
-  }
-  #endregion
+
+      var type = value.GetType();
+      var propertyInfo = type.GetProperty("Comparer");
+      var comparer = propertyInfo.GetValue(value);
+
+      dictionaryBox.SetComparerId(mapper.GetBoxId(comparer));
+      box.TypeId = mapper.GetBoxId(value.GetType());
+      box.SetExtension(DictionaryBox.Dictionary, dictionaryBox.Build());
+    }
+    public override object ToObject(Box box, Mapper mapper) {
+      var dictionaryBox = box.GetExtension(DictionaryBox.Dictionary);
+      return Activator.CreateInstance((Type)mapper.GetObject(box.TypeId), dictionaryBox.ValueIdsCount);
+    }
+    public override void FillFromBox(object obj, Box box, Mapper mapper) {
+      var type = obj.GetType();
+      var dictionaryBox = box.GetExtension(DictionaryBox.Dictionary);
+      var comparer = mapper.GetObject(dictionaryBox.ComparerId);
+      var addMethod = type.GetMethod("Add");
+      for (int i = 0; i < dictionaryBox.KeyIdsCount; i++) {
+        var key = mapper.GetObject(dictionaryBox.GetKeyIds(i));
+        var value = mapper.GetObject(dictionaryBox.GetValueIds(i));
+        addMethod.Invoke(obj, new[] { key, value });
+      }
+    }
+  }
 }
Index: branches/PersistenceOverhaul/HeuristicLab.Tests/HeuristicLab.Persistence-3.3/UseCasesPersistenceNew.cs
===================================================================
--- branches/PersistenceOverhaul/HeuristicLab.Tests/HeuristicLab.Persistence-3.3/UseCasesPersistenceNew.cs	(revision 14537)
+++ branches/PersistenceOverhaul/HeuristicLab.Tests/HeuristicLab.Persistence-3.3/UseCasesPersistenceNew.cs	(revision 14549)
@@ -33,5 +33,4 @@
 using HeuristicLab.Algorithms.GeneticAlgorithm;
 using HeuristicLab.Data;
-using HeuristicLab.Persistence;
 using HeuristicLab.Persistence.Auxiliary;
 using HeuristicLab.Persistence.Core;
@@ -945,5 +944,5 @@
     #region Old persistence test methods
     [TestMethod]
-    [TestCategory("Persistence4")]
+    [TestCategory("Persistence4-EXEPTION")]
     [TestProperty("Time", "short")]
     public void ComplexStorable() {
@@ -1035,5 +1034,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence4")]
+    [TestCategory("Persistence4-EXEPTION")]
     [TestProperty("Time", "short")]
     public void SelfReferences() {
@@ -1063,5 +1062,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence4")]
+    [TestCategory("Persistence4-EXEPTION")]
     [TestProperty("Time", "short")]
     public void ArrayCreation() {
@@ -1076,8 +1075,8 @@
       arrayListArray[2].Add(arrayListArray);
       arrayListArray[2].Add(arrayListArray);
-      Array a = Array.CreateInstance(
-                              typeof(object),
-                              new[] { 1, 2 }, new[] { 3, 4 });
-      arrayListArray[2].Add(a);
+      //Array a = Array.CreateInstance(
+      //                        typeof(object),
+      //                        new[] { 1, 2 }, new[] { 3, 4 });
+      //arrayListArray[2].Add(a);
       serializer.Serialize(arrayListArray, tempFile);
       object o = serializer.Deserialize(tempFile);
@@ -1353,5 +1352,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence4")]
+    [TestCategory("Persistence4-EXEPTION")]
     [TestProperty("Time", "short")]
     public void InstantiateParentChainReference() {
@@ -1517,5 +1516,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence4")]
+    [TestCategory("Persistence4-EXEPTION")]
     [TestProperty("Time", "short")]
     public void TestStreaming() {
@@ -2057,4 +2056,37 @@
     }
     #endregion
+
+    [StorableClass("6075F1E8-948A-4AD8-8F5A-942B777852EC")]
+    public class A {
+      [Storable]
+      public Tuple<B> B { get; set; }
+    }
+    [StorableClass("6075F1E8-948A-4AD8-8F5A-942B777852EC")]
+    public class B {
+      [Storable]
+      public A A { get; set; }
+    }
+
+    [TestMethod]
+    [TestCategory("Persistence4")]
+    [TestProperty("Time", "short")]
+    public void TestCyclicReferencesWithTuple() {
+      var test = new Func<A>(() => {
+        var a = new A { };
+        var b = new B { A = a };
+        a.B = Tuple.Create(b);
+        return a;
+      });
+      ProtoBufSerializer serializer = new ProtoBufSerializer();
+      serializer.Serialize(test(), tempFile);
+      object o = serializer.Deserialize(tempFile);
+      A result = (A)o;
+
+      Assert.AreEqual(result, result.B.Item1.A);
+      Assert.AreSame(result, result.B.Item1.A);
+
+      string msg = Profile(test);
+      Console.WriteLine(msg);
+    }
   }
 }
