Index: branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Transformers/StorableClassTransformer.cs
===================================================================
--- branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Transformers/StorableClassTransformer.cs	(revision 14549)
+++ 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 14549)
+++ 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++) {
