Index: /branches/PersistenceOverhaul/HeuristicLab.Core/3.3/HeuristicLab.Core-3.3.csproj
===================================================================
--- /branches/PersistenceOverhaul/HeuristicLab.Core/3.3/HeuristicLab.Core-3.3.csproj	(revision 14593)
+++ /branches/PersistenceOverhaul/HeuristicLab.Core/3.3/HeuristicLab.Core-3.3.csproj	(revision 14594)
@@ -239,4 +239,8 @@
       <Private>False</Private>
     </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Persistence\4.0\HeuristicLab.Persistence-4.0.csproj">
+      <Project>{B1663091-8156-4DEB-9E37-5B19810A4644}</Project>
+      <Name>HeuristicLab.Persistence-4.0</Name>
+    </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.PluginInfrastructure\3.3\HeuristicLab.PluginInfrastructure-3.3.csproj">
       <Project>{94186A6A-5176-4402-AE83-886557B53CCA}</Project>
Index: /branches/PersistenceOverhaul/HeuristicLab.Core/3.3/PersistenceContentManager.cs
===================================================================
--- /branches/PersistenceOverhaul/HeuristicLab.Core/3.3/PersistenceContentManager.cs	(revision 14593)
+++ /branches/PersistenceOverhaul/HeuristicLab.Core/3.3/PersistenceContentManager.cs	(revision 14594)
@@ -20,6 +20,8 @@
 #endregion
 
+using System;
 using System.IO.Compression;
 using HeuristicLab.Common;
+using HeuristicLab.Persistence;
 using HeuristicLab.Persistence.Default.Xml;
 
@@ -29,9 +31,15 @@
 
     protected override IStorableContent LoadContent(string filename) {
-      return XmlParser.Deserialize<IStorableContent>(filename);
+      try {
+        return XmlParser.Deserialize<IStorableContent>(filename);
+      } catch (Exception) {
+        var serializer = new ProtoBufSerializer();
+        return (IStorableContent)serializer.Deserialize(filename);
+      }
     }
 
     protected override void SaveContent(IStorableContent content, string filename, bool compressed) {
-      XmlGenerator.Serialize(content, filename, compressed ? CompressionLevel.Optimal : CompressionLevel.NoCompression);
+      //XmlGenerator.Serialize(content, filename, compressed ? CompressionLevel.Optimal : CompressionLevel.NoCompression);
+      new ProtoBufSerializer().Serialize(content, filename);
     }
   }
Index: /branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/Mapper.cs
===================================================================
--- /branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/Mapper.cs	(revision 14593)
+++ /branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/Mapper.cs	(revision 14594)
@@ -139,5 +139,5 @@
       bundle.RootBoxId = mapper.GetBoxId(o);
       bundle.AddRangeTransformerGuids(mapper.transformers.GetValues().Select(x => x.Guid).Select(x => ByteString.CopyFrom(x.ToByteArray())));
-      bundle.AddRangeTypeGuids(mapper.types.GetValues().Select(x => StaticCache.GetGuid(x)).Select(x => ByteString.CopyFromUtf8(x)));
+      bundle.AddRangeTypeGuids(mapper.types.GetValues().Select(x => x.AssemblyQualifiedName ?? x.Name).Select(x => ByteString.CopyFromUtf8(x)));
       bundle.AddRangeStrings(mapper.strings.GetValues());
       bundle.AddRangeBoxes(mapper.boxId2Box.OrderBy(x => x.Key).Select(x => x.Value));
@@ -146,5 +146,5 @@
     public static object ToObject(Bundle bundle) {
       var mapper = new Mapper();
-      mapper.types = new Index<Type>(bundle.TypeGuidsList.Select(x => x.ToStringUtf8()).Select(x => StaticCache.GetType(x)));
+      mapper.types = new Index<Type>(bundle.TypeGuidsList.Select(x => x.ToStringUtf8()).Select(x => Type.GetType(x)));
       mapper.strings = new Index<string>(bundle.StringsList);
       mapper.boxId2Box = bundle.BoxesList.Select((b, i) => new { Box = b, Index = i }).ToDictionary(k => (uint)k.Index + 1, v => v.Box);
Index: /branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/StaticCache.cs
===================================================================
--- /branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/StaticCache.cs	(revision 14593)
+++ /branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/StaticCache.cs	(revision 14594)
@@ -35,6 +35,6 @@
     private Dictionary<Guid, ITransformer> guid2Transformer;
     private Dictionary<ITransformer, Guid> transformer2Guid;
-    private Dictionary<string, Type> guid2Type;
-    private Dictionary<Type, string> type2Guid;
+    //private Dictionary<string, Type> guid2Type;
+    //private Dictionary<Type, string> type2Guid;
     private Dictionary<Type, TypeInfo> typeInfos;
     private ExtensionRegistry extensionRegistry;
@@ -43,6 +43,6 @@
       guid2Transformer = new Dictionary<Guid, ITransformer>();
       transformer2Guid = new Dictionary<ITransformer, Guid>();
-      guid2Type = new Dictionary<string, Type>();
-      type2Guid = new Dictionary<Type, string>();
+      //guid2Type = new Dictionary<string, Type>();
+      //type2Guid = new Dictionary<Type, string>();
       typeInfos = new Dictionary<Type, TypeInfo>();
       extensionRegistry = ExtensionRegistry.CreateInstance();
@@ -104,68 +104,71 @@
       //       RegisterType(new Guid("E92C35AD-32B1-4F37-B8D2-BE2F5FEB465B"), typeof(Dictionary<,>));
 
-      RegisterTypeAndFullName(typeof(object));
-      RegisterTypeAndFullName(typeof(bool));
-      RegisterTypeAndFullName(typeof(byte));
-      RegisterTypeAndFullName(typeof(sbyte));
-      RegisterTypeAndFullName(typeof(short));
-      RegisterTypeAndFullName(typeof(ushort));
-      RegisterTypeAndFullName(typeof(char));
-      RegisterTypeAndFullName(typeof(int));
-      RegisterTypeAndFullName(typeof(uint));
-      RegisterTypeAndFullName(typeof(long));
-      RegisterTypeAndFullName(typeof(ulong));
-      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));
-
-      RegisterTypeAndFullName(typeof(Array));
-      RegisterTypeAndFullName(typeof(bool[]));
-      RegisterTypeAndFullName(typeof(byte[]));
-      RegisterTypeAndFullName(typeof(sbyte[]));
-      RegisterTypeAndFullName(typeof(short[]));
-      RegisterTypeAndFullName(typeof(ushort[]));
-      RegisterTypeAndFullName(typeof(char[]));
-      RegisterTypeAndFullName(typeof(int[]));
-      RegisterTypeAndFullName(typeof(uint[]));
-      RegisterTypeAndFullName(typeof(long[]));
-      RegisterTypeAndFullName(typeof(ulong[]));
-      RegisterTypeAndFullName(typeof(float[]));
-      RegisterTypeAndFullName(typeof(double[]));
-      RegisterTypeAndFullName(typeof(string[]));
-      RegisterTypeAndFullName(typeof(List<>));
-      RegisterTypeAndFullName(typeof(ArrayList));
-      RegisterTypeAndFullName(typeof(HashSet<>));
-      RegisterTypeAndFullName(typeof(Stack<>));
-      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) || x.IsValueType && !x.IsPrimitive && !x.IsEnum && x.IsSealed))
-          RegisterTypeAndFullName(t);
-      }
-
-      var registeredTypes = type2Guid.Keys.ToArray();
-      foreach (var t in registeredTypes) {
-        AddBaseTypesRec(t);
-      }
+      //RegisterTypeAndFullName(typeof(object));
+      //RegisterTypeAndFullName(typeof(bool));
+      //RegisterTypeAndFullName(typeof(byte));
+      //RegisterTypeAndFullName(typeof(sbyte));
+      //RegisterTypeAndFullName(typeof(short));
+      //RegisterTypeAndFullName(typeof(ushort));
+      //RegisterTypeAndFullName(typeof(char));
+      //RegisterTypeAndFullName(typeof(int));
+      //RegisterTypeAndFullName(typeof(uint));
+      //RegisterTypeAndFullName(typeof(long));
+      //RegisterTypeAndFullName(typeof(ulong));
+      //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));
+
+      //RegisterTypeAndFullName(typeof(Array));
+      //RegisterTypeAndFullName(typeof(bool[]));
+      //RegisterTypeAndFullName(typeof(byte[]));
+      //RegisterTypeAndFullName(typeof(sbyte[]));
+      //RegisterTypeAndFullName(typeof(short[]));
+      //RegisterTypeAndFullName(typeof(ushort[]));
+      //RegisterTypeAndFullName(typeof(char[]));
+      //RegisterTypeAndFullName(typeof(int[]));
+      //RegisterTypeAndFullName(typeof(uint[]));
+      //RegisterTypeAndFullName(typeof(long[]));
+      //RegisterTypeAndFullName(typeof(ulong[]));
+      //RegisterTypeAndFullName(typeof(float[]));
+      //RegisterTypeAndFullName(typeof(double[]));
+      //RegisterTypeAndFullName(typeof(string[]));
+      //RegisterTypeAndFullName(typeof(List<>));
+      //RegisterTypeAndFullName(typeof(ArrayList));
+      //RegisterTypeAndFullName(typeof(HashSet<>));
+      //RegisterTypeAndFullName(typeof(Stack<>));
+      //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) // storable classes
+      //                                           || x.IsValueType && !x.IsPrimitive && !x.IsEnum && x.IsSealed // structs
+      //                                           || typeof(IEqualityComparer).IsAssignableFrom(x) // equality comparers
+      //                                           || x.IsGenericType && typeof(IEqualityComparer<>).IsAssignableFrom(x.GetGenericTypeDefinition()))) // generic equality comparers
+      //    RegisterTypeAndFullName(t);
+      //}
+
+      //var registeredTypes = type2Guid.Keys.ToArray();
+      //foreach (var t in registeredTypes) {
+      //  AddBaseTypesRec(t);
+      //}
 
       RegisterExtension(BoolBox.Bool);
@@ -195,14 +198,14 @@
     }
 
-    private void AddBaseTypesRec(Type t) {
-      foreach (var interfaceType in t.GetInterfaces()) {
-        RegisterTypeAndFullName(interfaceType);
-        AddBaseTypesRec(interfaceType);
-      }
-      if (t.BaseType != null) {
-        RegisterTypeAndFullName(t.BaseType);
-        AddBaseTypesRec(t.BaseType);
-      }
-    }
+    //private void AddBaseTypesRec(Type t) {
+    //  foreach (var interfaceType in t.GetInterfaces()) {
+    //    RegisterTypeAndFullName(interfaceType);
+    //    AddBaseTypesRec(interfaceType);
+    //  }
+    //  if (t.BaseType != null) {
+    //    RegisterTypeAndFullName(t.BaseType);
+    //    AddBaseTypesRec(t.BaseType);
+    //  }
+    //}
 
     public void RegisterTransformer(ITransformer transformer) {
@@ -218,13 +221,13 @@
     //      }
     //    }
-    public void RegisterTypeAndFullName(Type type) {
-      lock (locker) {
-        var key = type.AssemblyQualifiedName ?? type.Name;
-        if (!guid2Type.ContainsKey(key)) {
-          guid2Type.Add(key, type);
-          type2Guid.Add(type, key);
-        }
-      }
-    }
+    //public void RegisterTypeAndFullName(Type type) {
+    //  lock (locker) {
+    //    var key = type.AssemblyQualifiedName ?? type.Name;
+    //    if (!guid2Type.ContainsKey(key)) {
+    //      guid2Type.Add(key, type);
+    //      type2Guid.Add(type, key);
+    //    }
+    //  }
+    //}
     public void RegisterExtension<TExtension>(GeneratedExtensionBase<TExtension> extension) {
       lock (locker) {
@@ -239,10 +242,10 @@
       return transformer2Guid[transformer];
     }
-    public Type GetType(string guid) {
-      return guid2Type[guid];
-    }
-    public string GetGuid(Type type) {
-      return type2Guid[type];
-    }
+    //public Type GetType(string guid) {
+    //  return guid2Type[guid];
+    //}
+    //public string GetGuid(Type type) {
+    //  return type2Guid[type];
+    //}
     public TypeInfo GetTypeInfo(Type type) {
       lock (locker) {
Index: /branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Transformers/StorableClassTransformer.cs
===================================================================
--- /branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Transformers/StorableClassTransformer.cs	(revision 14593)
+++ /branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Transformers/StorableClassTransformer.cs	(revision 14594)
@@ -30,5 +30,5 @@
   internal sealed class StorableClassBoxTransformer : BoxTransformer<object> {
     public override bool CanTransformType(Type type) {
-      return StorableClassAttribute.IsStorableClass(type);
+      return StorableClassAttribute.IsStorableClass(type) || type.BaseType != null && CanTransformType(type.BaseType);
     }
 
@@ -79,5 +79,8 @@
         uint componentId;
         bool found = components.TryGetValue(mapper.GetStringId(componentInfo.Name), out componentId);
-        field.SetValue(obj, found ? mapper.GetObject(componentId) : componentInfo.StorableAttribute.DefaultValue);
+        if (found)
+          field.SetValue(obj, mapper.GetObject(componentId));
+        else if (componentInfo.StorableAttribute.DefaultValue != null)
+          field.SetValue(obj, componentInfo.StorableAttribute.DefaultValue);
       }
 
@@ -86,5 +89,8 @@
         uint componentId;
         bool found = components.TryGetValue(mapper.GetStringId(componentInfo.Name), out componentId);
-        property.SetValue(obj, found ? mapper.GetObject(componentId) : componentInfo.StorableAttribute.DefaultValue, null);
+        if (found)
+          property.SetValue(obj, mapper.GetObject(componentId), null);
+        else if (componentInfo.StorableAttribute.DefaultValue != null)
+          property.SetValue(obj, componentInfo.StorableAttribute.DefaultValue, null);
       }
 
Index: /branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Transformers/Transformers.cs
===================================================================
--- /branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Transformers/Transformers.cs	(revision 14593)
+++ /branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Transformers/Transformers.cs	(revision 14594)
@@ -807,7 +807,4 @@
     }
     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);
@@ -816,22 +813,77 @@
     }
     private void Populate(Box.Builder box, object value, Mapper mapper) {
+      var type = value.GetType();
       var array = (Array)value;
-      var elementType = value.GetType().GetElementType();
+      var rank = array.Rank;
 
       var uIntArrayBox = UnsignedIntArrayBox.CreateBuilder();
-      foreach (var item in (IEnumerable)array)
-        uIntArrayBox.AddValues(mapper.GetBoxId(item));
-
-      box.TypeId = mapper.GetBoxId(elementType);
+      uIntArrayBox.AddValues(mapper.GetBoxId(rank));
+
+      int[] lengths = new int[rank];
+      int[] lowerBounds = new int[rank];
+      for (int i = 0; i < rank; i++) {
+        lengths[i] = array.GetLength(i);
+        lowerBounds[i] = array.GetLowerBound(i);
+      }
+
+      uIntArrayBox.AddRangeValues(lengths.Select(x => mapper.GetBoxId(x)));
+      uIntArrayBox.AddRangeValues(lowerBounds.Select(x => mapper.GetBoxId(x)));
+
+      int[] positions = (int[])lowerBounds.Clone();
+      while (positions[rank - 1] < lengths[rank - 1] + lowerBounds[rank - 1]) {
+        uIntArrayBox.AddValues(mapper.GetBoxId(array.GetValue(positions)));
+        positions[0] += 1;
+        for (int i = 0; i < rank - 1; i++) {
+          if (positions[i] >= lowerBounds[i] + lengths[i]) {
+            positions[i] = lowerBounds[i];
+            positions[i + 1] += 1;
+          } else {
+            break;
+          }
+        }
+      }
+
+      box.TypeId = mapper.GetBoxId(type);
       box.SetExtension(UnsignedIntArrayBox.UnsignedIntArray, uIntArrayBox.Build());
     }
     public override object ToObject(Box box, Mapper mapper) {
       var uIntArrayBox = box.GetExtension(UnsignedIntArrayBox.UnsignedIntArray);
+      var rank = (int)mapper.GetObject(uIntArrayBox.GetValues(0));
+
+      int[] lengths = new int[rank], lowerBounds = new int[rank];
+      for (int i = 0; i < rank; i++)
+        lengths[i] = (int)mapper.GetObject(uIntArrayBox.GetValues(i + 1));
+      for (int i = 0; i < rank; i++)
+        lowerBounds[i] = (int)mapper.GetObject(uIntArrayBox.GetValues(i + 1 + rank));
+
       var type = (Type)mapper.GetObject(box.TypeId);
-      return Array.CreateInstance(type, uIntArrayBox.ValuesCount);
+      return Array.CreateInstance(type.GetElementType(), lengths, lowerBounds);
     }
     public override void FillFromBox(object obj, Box box, Mapper mapper) {
+      var array = (Array)obj;
       var uIntArrayBox = box.GetExtension(UnsignedIntArrayBox.UnsignedIntArray);
-      Array.Copy(uIntArrayBox.ValuesList.Select(x => mapper.GetObject(x)).ToArray(), (Array)obj, uIntArrayBox.ValuesCount);
+      var rank = (int)mapper.GetObject(uIntArrayBox.GetValues(0));
+
+      int[] lengths = new int[rank], lowerBounds = new int[rank];
+      for (int i = 0; i < rank; i++)
+        lengths[i] = (int)mapper.GetObject(uIntArrayBox.GetValues(i + 1));
+      for (int i = 0; i < rank; i++)
+        lowerBounds[i] = (int)mapper.GetObject(uIntArrayBox.GetValues(i + 1 + rank));
+
+      int[] positions = (int[])lowerBounds.Clone();
+      var e = uIntArrayBox.ValuesList.Skip(1 + 2 * rank).GetEnumerator();
+      while (e.MoveNext()) {
+        int[] currentPositions = positions;
+        array.SetValue(mapper.GetObject(e.Current), currentPositions);
+        positions[0] += 1;
+        for (int i = 0; i < rank - 1; i++) {
+          if (positions[i] >= lengths[i] + lowerBounds[i]) {
+            positions[i] = lowerBounds[i];
+            positions[i + 1] += 1;
+          } else {
+            break;
+          }
+        }
+      }
     }
   }
@@ -857,7 +909,23 @@
     private void Populate(Box.Builder box, object value, Mapper mapper) {
       var uIntArrayBox = UnsignedIntArrayBox.CreateBuilder();
+
+      var type = value.GetType();
+      var propertyInfo = type.GetProperty("Comparer");
+      if (propertyInfo != null) {
+        // TODO: where to store id for comparer box? (atm: first element in int array ...)
+        var comparer = propertyInfo.GetValue(value);
+        var comparerType = comparer.GetType();
+        if (Default.CompositeSerializers.Storable.StorableClassAttribute.IsStorableClass(comparerType))
+          uIntArrayBox.AddValues(mapper.GetBoxId(comparer));
+        else if (comparerType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy).Any())
+          throw new NotSupportedException("Cannot serialize non-storable equality comparers with fields");
+        else
+          uIntArrayBox.AddValues(mapper.GetBoxId(comparerType));
+      }
+
       foreach (var item in (IEnumerable)value)
         uIntArrayBox.AddValues(mapper.GetBoxId(item));
-      box.TypeId = mapper.GetBoxId(value.GetType());
+
+      box.TypeId = mapper.GetBoxId(type);
       box.SetExtension(UnsignedIntArrayBox.UnsignedIntArray, uIntArrayBox.Build());
     }
@@ -865,5 +933,5 @@
       var uIntArrayBox = box.GetExtension(UnsignedIntArrayBox.UnsignedIntArray);
       var type = (Type)mapper.GetObject(box.TypeId);
-      return Activator.CreateInstance(type, uIntArrayBox.ValuesCount);
+      return Activator.CreateInstance(type);
     }
     public override void FillFromBox(object obj, Box box, Mapper mapper) {
@@ -871,4 +939,5 @@
       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)) {
@@ -879,4 +948,11 @@
       } else {
         methodName = "Add";
+        if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(HashSet<>)) {
+          var fieldInfo = type.GetField("m_comparer", BindingFlags.NonPublic | BindingFlags.Instance);
+          var comparerObj = mapper.GetObject(uIntArrayBox.GetValues(0));
+          var comparer = comparerObj is Type ? Activator.CreateInstance((Type)comparerObj) : comparerObj;
+          fieldInfo.SetValue(obj, comparer);
+          elements = elements.Skip(1);
+        }
       }
 
@@ -909,6 +985,13 @@
       var comparer = propertyInfo.GetValue(value);
 
-      dictionaryBox.SetComparerId(mapper.GetBoxId(comparer));
-      box.TypeId = mapper.GetBoxId(value.GetType());
+      var comparerType = comparer.GetType();
+      if (Default.CompositeSerializers.Storable.StorableClassAttribute.IsStorableClass(comparerType))
+        dictionaryBox.SetComparerId(mapper.GetBoxId(comparer));
+      else if (comparerType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy).Any())
+        throw new NotSupportedException("Cannot serialize non-storable equality comparers with fields");
+      else
+        dictionaryBox.SetComparerId(mapper.GetBoxId(comparerType));
+
+      box.TypeId = mapper.GetBoxId(type);
       box.SetExtension(DictionaryBox.Dictionary, dictionaryBox.Build());
     }
@@ -920,5 +1003,11 @@
       var type = obj.GetType();
       var dictionaryBox = box.GetExtension(DictionaryBox.Dictionary);
-      var comparer = mapper.GetObject(dictionaryBox.ComparerId);
+      var comparerObj = mapper.GetObject(dictionaryBox.ComparerId);
+      var comparer = comparerObj is Type ? Activator.CreateInstance((Type)comparerObj) : comparerObj;
+
+      var fieldInfo = type.GetField("comparer", BindingFlags.NonPublic | BindingFlags.Instance);
+      fieldInfo.SetValue(obj, comparer);
+
+
       var addMethod = type.GetMethod("Add");
       for (int i = 0; i < dictionaryBox.KeyIdsCount; i++) {
Index: /branches/PersistenceOverhaul/HeuristicLab.Tests/HeuristicLab.Persistence-3.3/UseCasesPersistenceNew.cs
===================================================================
--- /branches/PersistenceOverhaul/HeuristicLab.Tests/HeuristicLab.Persistence-3.3/UseCasesPersistenceNew.cs	(revision 14593)
+++ /branches/PersistenceOverhaul/HeuristicLab.Tests/HeuristicLab.Persistence-3.3/UseCasesPersistenceNew.cs	(revision 14594)
@@ -33,4 +33,5 @@
 using HeuristicLab.Algorithms.GeneticAlgorithm;
 using HeuristicLab.Data;
+using HeuristicLab.Persistence;
 using HeuristicLab.Persistence.Auxiliary;
 using HeuristicLab.Persistence.Core;
@@ -39,4 +40,5 @@
 using HeuristicLab.Persistence.Default.Xml;
 using HeuristicLab.Persistence.Tests;
+using HeuristicLab.Problems.TestFunctions;
 using HeuristicLab.Tests;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
@@ -401,5 +403,5 @@
 
     public string Profile(Func<object> GenerateDataFunc) {
-      int nrOfRepetitions = 100;
+      int nrOfRepetitions = 30;
       StringBuilder report = new StringBuilder();
       List<PerformanceData> dataList = new List<PerformanceData>();
@@ -411,5 +413,5 @@
       report.Append("Performance Report for " + GenerateDataFunc.Method.Name + ": " + Environment.NewLine);
       report.Append(Environment.NewLine);
-      report.AppendFormat("Avg. old vs. new time for serializing a file: {0} / {1}; Factor: {2}",
+      report.AppendFormat("Avg. old vs. new time for serializing a file; {0};{1};{2}",
               dataList.Select(x => x.OldSerializingTime).Average(),
               dataList.Select(x => x.NewSerializingTime).Average(),
@@ -417,5 +419,5 @@
               );
       report.Append(Environment.NewLine);
-      report.AppendFormat("Avg. old vs. new time for deserializing a file: {0} / {1}; Factor: {2}",
+      report.AppendFormat("Avg. old vs. new time for deserializing a file; {0};{1};{2}",
               dataList.Select(x => x.OldDeserializingTime).Average(),
               dataList.Select(x => x.NewDeserializingTime).Average(),
@@ -423,5 +425,5 @@
               );
       report.Append(Environment.NewLine);
-      report.AppendFormat("Avg. old vs. new file size (in bytes): {0} / {1}; Factor: {2}",
+      report.AppendFormat("Avg. old vs. new file size (in bytes); {0};{1};{2}",
               dataList.Select(x => x.OldFileSize).Average(),
               dataList.Select(x => x.NewFileSize).Average(),
@@ -429,5 +431,5 @@
               );
       report.Append(Environment.NewLine);
-      report.AppendFormat("Avg. old vs. new memory consumption for serializing a file (in bytes): {0} / {1}; Factor: {2}",
+      report.AppendFormat("Avg. old vs. new memory consumption for serializing a file (in bytes); {0};{1};{2}",
               dataList.Select(x => x.OldSerializingMemoryConsumed).Average(),
               dataList.Select(x => x.NewSerializingMemoryConsumed).Average(),
@@ -435,5 +437,5 @@
               );
       report.Append(Environment.NewLine);
-      report.AppendFormat("Avg. old vs. new memory consumption for deserializing a file (in bytes): {0} / {1}; Factor: {2}",
+      report.AppendFormat("Avg. old vs. new memory consumption for deserializing a file (in bytes); {0};{1};{2}",
               dataList.Select(x => x.OldDeserializingMemoryConsumed).Average(),
               dataList.Select(x => x.NewDeserializingMemoryConsumed).Average(),
@@ -944,5 +946,5 @@
     #region Old persistence test methods
     [TestMethod]
-    [TestCategory("Persistence4-EXEPTION")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void ComplexStorable() {
@@ -1034,5 +1036,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence4-EXEPTION")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void SelfReferences() {
@@ -1062,5 +1064,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence4-EXEPTION")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void ArrayCreation() {
@@ -1352,5 +1354,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence4-EXEPTION")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void InstantiateParentChainReference() {
@@ -1516,5 +1518,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence4-EXEPTION")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void TestStreaming() {
@@ -2060,5 +2062,7 @@
     public class A {
       [Storable]
-      public Tuple<B> B { get; set; }
+      public B B { get; set; }
+
+      [Storable] public int i;
     }
     [StorableClass("6075F1E8-948A-4AD8-8F5A-942B777852EC")]
@@ -2066,4 +2070,9 @@
       [Storable]
       public A A { get; set; }
+
+      [StorableHook(HookType.AfterDeserialization)]
+      void PostDeserializationHook() {
+        //Assert.AreEqual(3, A.i);
+      }
     }
 
@@ -2073,19 +2082,58 @@
     public void TestCyclicReferencesWithTuple() {
       var test = new Func<A>(() => {
-        var a = new A { };
+        var a = new A { i = 4 };
         var b = new B { A = a };
-        a.B = Tuple.Create(b);
+        a.B = 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);
+
+      //ProtoBufSerializer serializer = new ProtoBufSerializer();
+      //serializer.Serialize(test(), tempFile);
+      //object o = serializer.Deserialize(tempFile);
+      //A result = (A)o;
+
+      XmlGenerator.Serialize(test(), tempFile);
+      object o = XmlParser.Deserialize(tempFile);
+
+      string msg = Profile(test);
+      Console.WriteLine(msg);
+    }
+
+    [TestMethod]
+    [TestCategory("Persistence4")]
+    [TestProperty("Time", "short")]
+    public void TestGASerializeDeserializeExecute() {
+      var test = new Func<GeneticAlgorithm>(() => {
+        var ga = new GeneticAlgorithm();
+        ga.Problem = new SingleObjectiveTestFunctionProblem();
+        ga.MaximumGenerations.Value = 100;
+        ga.SetSeedRandomly.Value = false;
+        return ga;
+      });
+      ProtoBufSerializer serializer = new ProtoBufSerializer();
+      serializer.Serialize(test(), tempFile);
+      object o = serializer.Deserialize(tempFile);
+      GeneticAlgorithm result = (GeneticAlgorithm)o;
+      SamplesUtils.RunAlgorithm(result);
+      GeneticAlgorithm original = test();
+      SamplesUtils.RunAlgorithm(original);
+      //Assert.AreEqual(original.Results[""], result);
+
+      //string msg = Profile(test);
+      //Console.WriteLine(msg);
+    }
+    [TestMethod]
+    [TestCategory("Persistence4")]
+    [TestProperty("Time", "short")]
+    public void TestLoadingSamples() {
+      var path = @"D:\Dev\HL\branches\PersistenceOverhaul\HeuristicLab.Optimizer\3.3\Documents";
+      var serializer = new ProtoBufSerializer();
+      foreach (var fileName in Directory.EnumerateFiles(path, "*.hl")) {
+        var original = XmlParser.Deserialize(fileName);
+        serializer.Serialize(original, fileName + ".proto");
+        // var newVersion = serializer.Deserialize(fileName + ".proto");
+        var p = Profile(() => original);
+        Console.WriteLine(p);
+      }
     }
   }
