Index: /branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/Mapper.cs
===================================================================
--- /branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/Mapper.cs	(revision 14536)
+++ /branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/Mapper.cs	(revision 14537)
@@ -23,7 +23,5 @@
 using System.Collections.Generic;
 using System.Linq;
-using HeuristicLab.PluginInfrastructure;
 using Google.ProtocolBuffers;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
 namespace HeuristicLab.Persistence {
@@ -122,5 +120,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.CopyFrom(x.ToByteArray())));
+      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());
@@ -129,5 +127,5 @@
     public static object ToObject(Bundle bundle) {
       var mapper = new Mapper();
-      mapper.types = new Index<Type>(bundle.TypeGuidsList.Select(x => new Guid(x.ToByteArray())).Select(x => StaticCache.GetType(x)));
+      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);
Index: /branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/StaticCache.cs
===================================================================
--- /branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/StaticCache.cs	(revision 14536)
+++ /branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Core/StaticCache.cs	(revision 14537)
@@ -34,6 +34,6 @@
     private Dictionary<Guid, ITransformer> guid2Transformer;
     private Dictionary<ITransformer, Guid> transformer2Guid;
-    private Dictionary<Guid, Type> guid2Type;
-    private Dictionary<Type, Guid> type2Guid;
+    private Dictionary<string, Type> guid2Type;
+    private Dictionary<Type, string> type2Guid;
     private Dictionary<Type, TypeInfo> typeInfos;
     private ExtensionRegistry extensionRegistry;
@@ -42,47 +42,114 @@
       guid2Transformer = new Dictionary<Guid, ITransformer>();
       transformer2Guid = new Dictionary<ITransformer, Guid>();
-      guid2Type = new Dictionary<Guid, Type>();
-      type2Guid = new Dictionary<Type, Guid>();
+      guid2Type = new Dictionary<string, Type>();
+      type2Guid = new Dictionary<Type, string>();
       typeInfos = new Dictionary<Type, TypeInfo>();
       extensionRegistry = ExtensionRegistry.CreateInstance();
 
-      foreach (var transformer in ApplicationManager.Manager.GetInstances<ITransformer>().OrderBy(x => x.Priority))
+      foreach (var transformer in ApplicationManager.Manager.GetInstances<ITransformer>())
         RegisterTransformer(transformer);
 
-      RegisterType(new Guid("94AD8522-3F55-4580-A6F8-2D2AAEDD4B8C"), typeof(bool));
-      RegisterType(new Guid("4A1C0FD5-423D-4F96-AB22-A496578C25AC"), typeof(byte));
-      RegisterType(new Guid("C4B00F0B-FED7-439F-B1B2-8A0048B64882"), typeof(sbyte));
-      RegisterType(new Guid("9F451811-3DE1-43AB-8B74-D7E03851857B"), typeof(short));
-      RegisterType(new Guid("46244D54-0145-49F7-9CF3-9CDB7FB5F240"), typeof(ushort));
-      RegisterType(new Guid("1FDDE40C-09E3-491F-8FBB-32BB3C885E9E"), typeof(char));
-      RegisterType(new Guid("EE3E0F9C-A5C2-4461-AF36-28BD8F26E6FB"), typeof(int));
-      RegisterType(new Guid("69476D18-D285-43E9-BC7C-6CC9E9F2321E"), typeof(uint));
-      RegisterType(new Guid("7C7BC5EC-F001-4BA0-9F85-50DCBAA9AE81"), typeof(long));
-      RegisterType(new Guid("AC808D5A-63BB-457C-9B92-C9B83DA2B139"), typeof(ulong));
-      RegisterType(new Guid("BF22653A-026C-4367-BBBA-2125AECF6C08"), typeof(float));
-      RegisterType(new Guid("8B49821A-3ADC-4715-9DB1-08E2F3CFDF15"), typeof(double));
-      RegisterType(new Guid("7BB386BF-6FD4-443D-A6C1-387096798C67"), typeof(DateTime));
-      RegisterType(new Guid("724A2D49-7E7B-455B-BBA9-4214C64E8A21"), typeof(TimeSpan));
-      RegisterType(new Guid("4DB2ED2B-D9F2-4695-B555-A2CF42740740"), typeof(Color));
-      RegisterType(new Guid("9BC74087-D5C0-4C39-99B4-D7465F478492"), typeof(Point));
-      RegisterType(new Guid("E84C326A-7E14-4F28-AEFF-BC16CC671655"), typeof(KeyValuePair<,>));
-      RegisterType(new Guid("F0280B55-25E8-4981-B309-D675D081402A"), typeof(string));
-
-      RegisterType(new Guid("D15AD28B-203A-460E-815C-F7230C4B1F75"), typeof(bool[]));
-      RegisterType(new Guid("EE318DC4-580D-4DB1-9AAD-988B0E50A3DB"), typeof(byte[]));
-      RegisterType(new Guid("326B9484-361F-46F8-B8A6-46C781A8C51F"), typeof(sbyte[]));
-      RegisterType(new Guid("C854783D-4C91-43C8-A19A-F96012494F8A"), typeof(short[]));
-      RegisterType(new Guid("C47FB329-2A1D-4EB7-AFB1-1CF72AB30E98"), typeof(ushort[]));
-      RegisterType(new Guid("9681D044-B50C-4907-B23E-BDFEBC6C3FFC"), typeof(char[]));
-      RegisterType(new Guid("0FC62D91-D63F-4507-8696-885D4C07285A"), typeof(int[]));
-      RegisterType(new Guid("C43A25A0-9B99-4DA4-9279-7495FE10428E"), typeof(uint[]));
-      RegisterType(new Guid("7AC4DDAC-0E13-428E-BF49-7BE7B76746CB"), typeof(long[]));
-      RegisterType(new Guid("8D9283A7-FE49-4AEA-A09F-D53CF3BE520A"), typeof(ulong[]));
-      RegisterType(new Guid("BB9CFA0B-DD29-4C44-85C6-3A6289C55448"), typeof(float[]));
-      RegisterType(new Guid("3B3AA69E-1641-4202-AE1D-7EEFF60FA355"), typeof(double[]));
-      RegisterType(new Guid("7DF325A6-2553-4915-B7C6-D98191107CB7"), typeof(string[]));
+
+      // ECC12A57-DA8D-43D9-9EC7-FCAC878A4D69
+      // E8348C94-9817-4164-9C98-377689F83F30
+      // 05551382-E894-4218-B860-FEE1D92CA07D
+      // 4CC0D44E-65B2-4DF1-A333-30F058CB78CA
+      // 5D451A64-EBD9-411F-A07E-232250B33784
+      // EEBD2D26-56CC-45EA-900A-DD29B9F598CE
+      // B8EEEFA7-8576-42DD-937C-AFBB66297B56
+      // 4C3C8E0A-7DCF-4814-B798-AECB86E1E4E3
+      // EAA4FF91-B90C-47CB-AC0F-66AB66D41186
+      // EB51B342-826F-4004-B2C6-F2A03A8C35C9
+      // 14138614-45DB-4A0D-9E59-AE9373241D6B
+
+
+      //       RegisterType(new Guid("94AD8522-3F55-4580-A6F8-2D2AAEDD4B8C"), typeof(bool));
+      //       RegisterType(new Guid("4A1C0FD5-423D-4F96-AB22-A496578C25AC"), typeof(byte));
+      //       RegisterType(new Guid("C4B00F0B-FED7-439F-B1B2-8A0048B64882"), typeof(sbyte));
+      //       RegisterType(new Guid("9F451811-3DE1-43AB-8B74-D7E03851857B"), typeof(short));
+      //       RegisterType(new Guid("46244D54-0145-49F7-9CF3-9CDB7FB5F240"), typeof(ushort));
+      //       RegisterType(new Guid("1FDDE40C-09E3-491F-8FBB-32BB3C885E9E"), typeof(char));
+      //       RegisterType(new Guid("EE3E0F9C-A5C2-4461-AF36-28BD8F26E6FB"), typeof(int));
+      //       RegisterType(new Guid("69476D18-D285-43E9-BC7C-6CC9E9F2321E"), typeof(uint));
+      //       RegisterType(new Guid("7C7BC5EC-F001-4BA0-9F85-50DCBAA9AE81"), typeof(long));
+      //       RegisterType(new Guid("AC808D5A-63BB-457C-9B92-C9B83DA2B139"), typeof(ulong));
+      //       RegisterType(new Guid("BF22653A-026C-4367-BBBA-2125AECF6C08"), typeof(float));
+      //       RegisterType(new Guid("8B49821A-3ADC-4715-9DB1-08E2F3CFDF15"), typeof(double));
+      //       RegisterType(new Guid("7BB386BF-6FD4-443D-A6C1-387096798C67"), typeof(DateTime));
+      //       RegisterType(new Guid("724A2D49-7E7B-455B-BBA9-4214C64E8A21"), typeof(TimeSpan));
+      //       RegisterType(new Guid("4DB2ED2B-D9F2-4695-B555-A2CF42740740"), typeof(Color));
+      //       RegisterType(new Guid("9BC74087-D5C0-4C39-99B4-D7465F478492"), typeof(Point));
+      //       RegisterType(new Guid("E84C326A-7E14-4F28-AEFF-BC16CC671655"), typeof(KeyValuePair<,>));
+      //       RegisterType(new Guid("F0280B55-25E8-4981-B309-D675D081402A"), typeof(string));
+      // 
+      //       RegisterType(new Guid("9CF55419-439B-4A90-B2ED-8C7F7768EB61"), typeof(Array));
+      //       RegisterType(new Guid("D15AD28B-203A-460E-815C-F7230C4B1F75"), typeof(bool[]));
+      //       RegisterType(new Guid("EE318DC4-580D-4DB1-9AAD-988B0E50A3DB"), typeof(byte[]));
+      //       RegisterType(new Guid("326B9484-361F-46F8-B8A6-46C781A8C51F"), typeof(sbyte[]));
+      //       RegisterType(new Guid("C854783D-4C91-43C8-A19A-F96012494F8A"), typeof(short[]));
+      //       RegisterType(new Guid("C47FB329-2A1D-4EB7-AFB1-1CF72AB30E98"), typeof(ushort[]));
+      //       RegisterType(new Guid("9681D044-B50C-4907-B23E-BDFEBC6C3FFC"), typeof(char[]));
+      //       RegisterType(new Guid("0FC62D91-D63F-4507-8696-885D4C07285A"), typeof(int[]));
+      //       RegisterType(new Guid("C43A25A0-9B99-4DA4-9279-7495FE10428E"), typeof(uint[]));
+      //       RegisterType(new Guid("7AC4DDAC-0E13-428E-BF49-7BE7B76746CB"), typeof(long[]));
+      //       RegisterType(new Guid("8D9283A7-FE49-4AEA-A09F-D53CF3BE520A"), typeof(ulong[]));
+      //       RegisterType(new Guid("BB9CFA0B-DD29-4C44-85C6-3A6289C55448"), typeof(float[]));
+      //       RegisterType(new Guid("3B3AA69E-1641-4202-AE1D-7EEFF60FA355"), typeof(double[]));
+      //       RegisterType(new Guid("7DF325A6-2553-4915-B7C6-D98191107CB7"), typeof(string[]));
+      //       RegisterType(new Guid("DB2A785C-5803-42C7-A01F-E1FD845A83A1"), typeof(List<>));
+      //       RegisterType(new Guid("EB98A564-BEDC-458A-9E9B-4BF3CDAFB9BE"), typeof(Stack<>));
+      //       RegisterType(new Guid("D5E3118B-957A-43B5-A740-1BBAA0EAB666"), typeof(System.Collections.Stack));
+      //       RegisterType(new Guid("7E2F3277-7216-4295-A498-9ACA43527D5B"), typeof(HashSet<>));
+      //       RegisterType(new Guid("E92C35AD-32B1-4F37-B8D2-BE2F5FEB465B"), typeof(Dictionary<,>));
+
+
+      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(DateTime));
+      RegisterTypeAndFullName(typeof(TimeSpan));
+      RegisterTypeAndFullName(typeof(Color));
+      RegisterTypeAndFullName(typeof(Point));
+      RegisterTypeAndFullName(typeof(KeyValuePair<,>));
+      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(Stack<>));
+      RegisterTypeAndFullName(typeof(System.Collections.Stack));
+      RegisterTypeAndFullName(typeof(HashSet<>));
+      RegisterTypeAndFullName(typeof(Dictionary<,>));
+
+
       foreach (var asm in AppDomain.CurrentDomain.GetAssemblies()) {
         foreach (var t in asm.GetTypes().Where(x => StorableClassAttribute.IsStorableClass(x)))
-          RegisterType(StorableClassAttribute.GetStorableClassAttribute(t).Guid, t);
+          RegisterTypeAndFullName(t);
+      }
+
+      var registeredTypes = type2Guid.Keys.ToArray();
+      foreach (var t in registeredTypes) {
+        AddBaseTypesRec(t);
       }
 
@@ -97,4 +164,5 @@
       RegisterExtension(BytesBox.Bytes);
       RegisterExtension(BoolArrayBox.BoolArray);
+      RegisterExtension(ByteArrayBox.ByteArray);
       RegisterExtension(IntArrayBox.IntArray);
       RegisterExtension(LongArrayBox.LongArray);
@@ -108,4 +176,17 @@
       RegisterExtension(IntMatrixBox.IntMatrix);
       RegisterExtension(DictionaryBox.Dictionary);
+      RegisterExtension(StorableClassBox.StorableClass);
+      RegisterExtension(TypeBox.Type);
+    }
+
+    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);
+      }
     }
 
@@ -116,8 +197,17 @@
       }
     }
-    public void RegisterType(Guid guid, Type type) {
-      lock (locker) {
-        guid2Type.Add(guid, type);
-        type2Guid.Add(type, guid);
+    //    public void RegisterType(Guid guid, Type type) {
+    //      lock (locker) {
+    //        guid2Type.Add(guid, type);
+    //        type2Guid.Add(type, guid);
+    //      }
+    //    }
+    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);
+        }
       }
     }
@@ -134,8 +224,8 @@
       return transformer2Guid[transformer];
     }
-    public Type GetType(Guid guid) {
+    public Type GetType(string guid) {
       return guid2Type[guid];
     }
-    public Guid GetGuid(Type type) {
+    public string GetGuid(Type type) {
       return type2Guid[type];
     }
@@ -144,5 +234,5 @@
         TypeInfo typeInfo;
         if (!typeInfos.TryGetValue(type, out typeInfo)) {
-          var transformer = guid2Transformer.Values.First(x => x.CanTransformType(type));
+          var transformer = guid2Transformer.Values.OrderBy(x => x.Priority).First(x => x.CanTransformType(type));
           typeInfo = new TypeInfo(type, transformer);
           typeInfos.Add(type, typeInfo);
Index: /branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/HeuristicLab.Persistence-4.0.csproj
===================================================================
--- /branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/HeuristicLab.Persistence-4.0.csproj	(revision 14536)
+++ /branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/HeuristicLab.Persistence-4.0.csproj	(revision 14537)
@@ -62,4 +62,5 @@
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Protos\PersistenceMessages.cs" />
+    <Compile Include="Transformers\StorableClassTransformer.cs" />
     <Compile Include="Transformers\Transformers.cs" />
   </ItemGroup>
Index: /branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Protos/PersistenceMessages.proto
===================================================================
--- /branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Protos/PersistenceMessages.proto	(revision 14536)
+++ /branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Protos/PersistenceMessages.proto	(revision 14537)
@@ -15,4 +15,5 @@
   extensions 100 to max;
 }
+
 
 // scalar boxes
@@ -79,7 +80,13 @@
   repeated bool values = 1 [packed = true];
 }
+message ByteArrayBox {
+  extend Box {
+    required ByteArrayBox byte_array = 121;
+  }
+  required bytes values = 1;
+}
 message IntArrayBox {
   extend Box {
-    required IntArrayBox int_array = 121;
+    required IntArrayBox int_array = 122;
   }
   repeated int32 values = 1 [packed = true];
@@ -87,5 +94,5 @@
 message LongArrayBox {
   extend Box {
-    required LongArrayBox long_array = 122;
+    required LongArrayBox long_array = 123;
   }
   repeated int64 values = 1 [packed = true];
@@ -93,11 +100,13 @@
 message UnsignedIntArrayBox {
   extend Box {
-    required UnsignedIntArrayBox unsigned_int_array = 123;
+    required UnsignedIntArrayBox unsigned_int_array = 124;
   }
   repeated uint32 values = 1 [packed = true];
+
+  extensions 100 to max;
 }
 message UnsignedLongArrayBox {
   extend Box {
-    required UnsignedLongArrayBox unsigned_long_array = 124;
+    required UnsignedLongArrayBox unsigned_long_array = 125;
   }
   repeated uint64 values = 1 [packed = true];
@@ -105,5 +114,5 @@
 message FloatArrayBox {
   extend Box {
-    required FloatArrayBox float_array = 125;
+    required FloatArrayBox float_array = 126;
   }
   repeated float values = 1 [packed = true];
@@ -111,5 +120,5 @@
 message DoubleArrayBox {
   extend Box {
-    required DoubleArrayBox double_array = 126;
+    required DoubleArrayBox double_array = 127;
   }
   repeated double values = 1 [packed = true];
@@ -117,5 +126,5 @@
 message StringArrayBox {
   extend Box {
-    required StringArrayBox string_array = 127;
+    required StringArrayBox string_array = 128;
   }
   repeated string values = 1;
@@ -154,2 +163,19 @@
   required uint32 comparer_id = 3;
 }
+
+message StorableClassBox {
+  extend Box {
+    required StorableClassBox storable_class = 200;
+  }
+  repeated uint32 key_ids = 1 [packed = true];
+  repeated uint32 value_ids = 2 [packed = true];
+}
+
+
+message TypeBox {
+  extend Box {
+    required TypeBox type = 250;
+  }
+  repeated uint32 generic_type_ids = 1 [packed = true];
+}
+
Index: /branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Transformers/StorableClassTransformer.cs
===================================================================
--- /branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Transformers/StorableClassTransformer.cs	(revision 14536)
+++ /branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Transformers/StorableClassTransformer.cs	(revision 14537)
@@ -24,53 +24,50 @@
 using System.Linq;
 using System.Reflection;
-using HeuristicLab.Persistence.Data;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
 namespace HeuristicLab.Persistence {
   [Transformer("78556C88-0FEE-4602-95C7-A469B2DDB468", 100)]
-  internal sealed class StorableClassTransformer : TransformerBase {
+  internal sealed class StorableClassBoxTransformer : BoxTransformer<object> {
     public override bool CanTransformType(Type type) {
       return StorableClassAttribute.IsStorableClass(type);
     }
-    public override PersistenceData ToData(object o, PersistenceMapper mapper) {
-      var type = o.GetType();
-      var typeInfo = mapper.GetTypeInfo(type);
-      var attribute = typeInfo.StorableClassAttribute;
-      var data = new CompositeData(Id);
-      mapper.Cache(o, data);
-      data.TypeId = mapper.GetTypeId(type);
-      // data.GuidId = attribute.Guid;
-      // data.Version = attribute.Version;
+
+    protected override void Populate(Box.Builder box, object value, Mapper mapper) {
+      var b = StorableClassBox.CreateBuilder();
+      var type = value.GetType();
+      var typeInfo = Mapper.StaticCache.GetTypeInfo(type);
 
       var emptyArgs = new object[0];
       foreach (var hook in typeInfo.BeforeSerializationHooks) {
-        hook.Invoke(o, emptyArgs);
+        hook.Invoke(value, emptyArgs);
       }
+
       var components = new Dictionary<uint, uint>();
       foreach (var componentInfo in typeInfo.Fields) {
         var field = (FieldInfo)componentInfo.MemberInfo;
-        var component = mapper.GetDataId(field.GetValue(o));
+        var component = mapper.GetBoxId(field.GetValue(value));
         components.Add(mapper.GetStringId(componentInfo.Name), component);
       }
+
       foreach (var componentInfo in typeInfo.Properties.Where(x => x.Readable)) {
         var property = (PropertyInfo)componentInfo.MemberInfo;
-        var component = mapper.GetDataId(property.GetValue(o, null));
+        var component = mapper.GetBoxId(property.GetValue(value, null));
         components.Add(mapper.GetStringId(componentInfo.Name), component);
       }
-      data.ComponentNameIds = components.Keys.ToArray();
-      data.ComponentIds = components.Values.ToArray();
-      return data;
+
+      b.AddRangeKeyIds(components.Keys);
+      b.AddRangeValueIds(components.Values);
+
+      box.SetExtension(StorableClassBox.StorableClass, b.Build());
     }
 
-    public override object ToObject(PersistenceData data, PersistenceMapper mapper) {
-      var composite = (CompositeData)data;
-      var type = mapper.GetType(composite.TypeId);
-      var typeInfo = mapper.GetTypeInfo(type);
+    protected override object Extract(Box box, Type type, Mapper mapper) {
+      var data = box.GetExtension(StorableClassBox.StorableClass);
+      var typeInfo = Mapper.StaticCache.GetTypeInfo(type);
       var o = mapper.CreateInstance(type);
-      mapper.Cache(data, o);
 
       var components = new Dictionary<uint, uint>();
-      for (int i = 0; i < composite.ComponentNameIds.Length; i++) {
-        components.Add(composite.ComponentNameIds[i], composite.ComponentIds[i]);
+      for (int i = 0; i < data.KeyIdsList.Count; i++) {
+        components.Add(data.KeyIdsList[i], data.ValueIdsList[i]);
       }
 
@@ -78,17 +75,20 @@
         var field = (FieldInfo)componentInfo.MemberInfo;
         uint componentId;
-        components.TryGetValue(mapper.GetStringId(componentInfo.Name), out componentId);
-        field.SetValue(o, componentId != 0 ? mapper.GetObject(componentId) : componentInfo.StorableAttribute.DefaultValue);
+        bool found = components.TryGetValue(mapper.GetStringId(componentInfo.Name), out componentId);
+        field.SetValue(o, found ? mapper.GetObject(componentId) : componentInfo.StorableAttribute.DefaultValue);
       }
+
       foreach (var componentInfo in typeInfo.Properties.Where(x => x.Writeable)) {
         var property = (PropertyInfo)componentInfo.MemberInfo;
         uint componentId;
-        components.TryGetValue(mapper.GetStringId(componentInfo.Name), out componentId);
-        property.SetValue(o, componentId != 0 ? mapper.GetObject(componentId) : componentInfo.StorableAttribute.DefaultValue, null);
+        bool found = components.TryGetValue(mapper.GetStringId(componentInfo.Name), out componentId);
+        property.SetValue(o, found ? mapper.GetObject(componentId) : componentInfo.StorableAttribute.DefaultValue, null);
       }
+
       var emptyArgs = new object[0];
       foreach (var hook in typeInfo.AfterDeserializationHooks) {
         hook.Invoke(o, emptyArgs);
       }
+
       return o;
     }
Index: /branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Transformers/Transformers.cs
===================================================================
--- /branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Transformers/Transformers.cs	(revision 14536)
+++ /branches/PersistenceOverhaul/HeuristicLab.Persistence/4.0/Transformers/Transformers.cs	(revision 14537)
@@ -21,4 +21,5 @@
 
 using System;
+using System.Collections;
 using System.Collections.Generic;
 using System.Drawing;
@@ -158,4 +159,16 @@
 
   #region Array Box Transformers
+  public abstract class ByteArrayBoxTransformer<T> : BoxTransformer<T> {
+    protected override void Populate(Box.Builder box, T value, Mapper mapper) {
+      var b = ByteArrayBox.CreateBuilder();
+      b.SetValues(ToByteString(value));
+      box.SetExtension(ByteArrayBox.ByteArray, b.Build());
+    }
+    protected override T Extract(Box box, Type type, Mapper mapper) {
+      return FromByteString(box.GetExtension(ByteArrayBox.ByteArray).Values);
+    }
+    protected abstract ByteString ToByteString(T value);
+    protected abstract T FromByteString(ByteString byteString);
+  }
   public abstract class BoolArrayBoxTransformer<T> : BoxTransformer<T> {
     protected override void Populate(Box.Builder box, T value, Mapper mapper) {
@@ -407,26 +420,46 @@
   #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 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 Array Types
+  [Transformer("FF89F6D1-CDE3-498E-9166-F70AC6EB01F1", 301)]
+  internal sealed class ByteArrayTransformer : ByteArrayBoxTransformer<byte[]> {
+    protected override ByteString ToByteString(byte[] value) {
+      return ByteString.CopyFrom(value);
+    }
+    protected override byte[] FromByteString(ByteString byteString) {
+      return byteString.ToArray();
+    }
+  }
+
+  [Transformer("B49B3F2D-2E97-4BAB-8705-8D29DA707C6A", 302)]
+  internal sealed class SByteArrayTransformer : ByteArrayBoxTransformer<sbyte[]> {
+    protected override ByteString ToByteString(sbyte[] value) {
+      return ByteString.CopyFrom(value.Select(b => (byte)b).ToArray());
+    }
+    protected override sbyte[] FromByteString(ByteString byteString) {
+      return byteString.Select(b => (sbyte)b).ToArray();
+    }
+  }
+
   [Transformer("F25A73B2-6B67-4493-BD59-B836AF4455D1", 300)]
   internal sealed class BoolArrayTransformer : BoolArrayBoxTransformer<bool[]> {
@@ -435,32 +468,62 @@
   }
 
-  [Transformer("FF89F6D1-CDE3-498E-9166-F70AC6EB01F1", 301)]
-  internal sealed class ByteArrayTransformer : UnsignedIntArrayBoxTransformer<byte[]> {
-    protected override IEnumerable<uint> ToBoxType(byte[] value, Mapper mapper) { return value.Cast<uint>(); }
-    protected override byte[] ToValueType(IEnumerable<uint> value, Type type, Mapper mapper) { return value.Cast<byte>().ToArray(); }
-  }
-
-  [Transformer("B49B3F2D-2E97-4BAB-8705-8D29DA707C6A", 302)]
-  internal sealed class SByteArrayTransformer : IntArrayBoxTransformer<sbyte[]> {
-    protected override IEnumerable<int> ToBoxType(sbyte[] value, Mapper mapper) { return value.Cast<int>(); }
-    protected override sbyte[] ToValueType(IEnumerable<int> value, Type type, Mapper mapper) { return value.Cast<sbyte>().ToArray(); }
-  }
-
   [Transformer("2811FDD4-6800-4CBA-86D7-9071ED5775ED", 303)]
-  internal sealed class ShortArrayTransformer : IntArrayBoxTransformer<short[]> {
-    protected override IEnumerable<int> ToBoxType(short[] value, Mapper mapper) { return value.Cast<int>(); }
-    protected override short[] ToValueType(IEnumerable<int> value, Type type, Mapper mapper) { return value.Cast<short>().ToArray(); }
+  internal sealed class ShortArrayTransformer : ByteArrayBoxTransformer<short[]> {
+    protected override ByteString ToByteString(short[] value) {
+      var res = new byte[value.Length * 2];
+      for (int i = 0; i < value.Length; i++) {
+        var bytes = BitConverter.GetBytes(value[i]);
+        Array.Copy(bytes, 0, res, i * 2, 2);
+      }
+      return ByteString.CopyFrom(res);
+    }
+    protected override short[] FromByteString(ByteString byteString) {
+      var bytes = byteString.ToArray();
+      var res = new short[bytes.Length / 2];
+      for (int i = 0; i < bytes.Length; i += 2) {
+        res[i / 2] = BitConverter.ToInt16(bytes, i);
+      }
+      return res;
+    }
   }
 
   [Transformer("1AAC2625-356C-40BC-8CB4-15CB3D047EB8", 304)]
-  internal sealed class UShortArrayTransformer : UnsignedIntArrayBoxTransformer<ushort[]> {
-    protected override IEnumerable<uint> ToBoxType(ushort[] value, Mapper mapper) { return value.Cast<uint>(); }
-    protected override ushort[] ToValueType(IEnumerable<uint> value, Type type, Mapper mapper) { return value.Cast<ushort>().ToArray(); }
+  internal sealed class UShortArrayTransformer : ByteArrayBoxTransformer<ushort[]> {
+    protected override ByteString ToByteString(ushort[] value) {
+      var res = new byte[value.Length * 2];
+      for (int i = 0; i < value.Length; i++) {
+        var bytes = BitConverter.GetBytes(value[i]);
+        Array.Copy(bytes, 0, res, i * 2, 2);
+      }
+      return ByteString.CopyFrom(res);
+    }
+    protected override ushort[] FromByteString(ByteString byteString) {
+      var bytes = byteString.ToArray();
+      var res = new ushort[bytes.Length / 2];
+      for (int i = 0; i < bytes.Length; i += 2) {
+        res[i / 2] = BitConverter.ToUInt16(bytes, i);
+      }
+      return res;
+    }
   }
 
   [Transformer("12F19098-5D49-4C23-8897-69087F1C146D", 305)]
-  internal sealed class CharArrayTransformer : UnsignedIntArrayBoxTransformer<char[]> {
-    protected override IEnumerable<uint> ToBoxType(char[] value, Mapper mapper) { return value.Cast<uint>(); }
-    protected override char[] ToValueType(IEnumerable<uint> value, Type type, Mapper mapper) { return value.Cast<char>().ToArray(); }
+  internal sealed class CharArrayTransformer : ByteArrayBoxTransformer<char[]> {
+    protected override ByteString ToByteString(char[] value) {
+      var res = new byte[value.Length * 2];
+      for (int i = 0; i < value.Length; i++) {
+        var bytes = BitConverter.GetBytes(value[i]);
+        Array.Copy(bytes, 0, res, i * 2, 2);
+      }
+      return ByteString.CopyFrom(res);
+    }
+    protected override char[] FromByteString(ByteString byteString) {
+      var bytes = byteString.ToArray();
+      var res = new char[bytes.Length / 2];
+      for (int i = 0; i < bytes.Length; i += 2) {
+        res[i / 2] = BitConverter.ToChar(bytes, i);
+      }
+      return res;
+    }
   }
 
@@ -507,15 +570,201 @@
   }
 
-  [Transformer("C83F0B5A-68D8-4271-81F9-FF259FC6F126", 400)]
-  internal sealed class GenericArrayTransformer : UnsignedIntArrayBoxTransformer<object> {
+  //[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)]
+  internal sealed class ArrayTransformer : Transformer {
     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();
+    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 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 {
+    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 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();
+      foreach (DictionaryEntry item in (IDictionary)value) {
+        dictionaryBox.AddKeyIds(mapper.GetBoxId(item.Key));
+        dictionaryBox.AddValueIds(mapper.GetBoxId(item.Value));
+      }
+      // TODO: comparer
+    }
+    private object Extract(Box box, Type type, Mapper mapper) {
+      throw new NotImplementedException();
     }
   }
Index: /branches/PersistenceOverhaul/HeuristicLab.Tests/HeuristicLab.Persistence-3.3/UseCasesPersistenceNew.cs
===================================================================
--- /branches/PersistenceOverhaul/HeuristicLab.Tests/HeuristicLab.Persistence-3.3/UseCasesPersistenceNew.cs	(revision 14536)
+++ /branches/PersistenceOverhaul/HeuristicLab.Tests/HeuristicLab.Persistence-3.3/UseCasesPersistenceNew.cs	(revision 14537)
@@ -273,6 +273,9 @@
   }
 
+  [StorableClass("FD953B0A-BDE6-41E6-91A8-CA3D90C91CDB")]
   public class SimpleClass {
+    [Storable]
     public double x { get; set; }
+    [Storable]
     public int y { get; set; }
   }
@@ -653,4 +656,68 @@
     [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
+    public void TestSBytes() {
+      var test = new Func<sbyte[]>(() => { return new sbyte[] { 3, 1 }; });
+      ProtoBufSerializer serializer = new ProtoBufSerializer();
+      serializer.Serialize(test(), tempFile);
+      object o = serializer.Deserialize(tempFile);
+      sbyte[] result = (sbyte[])o;
+      Assert.AreEqual(test()[0], result[0]);
+      Assert.AreEqual(test()[1], result[1]);
+
+      string msg = Profile(test);
+      Console.WriteLine(msg);
+    }
+
+    [TestMethod]
+    [TestCategory("Persistence4")]
+    [TestProperty("Time", "short")]
+    public void TestChars() {
+      var test = new Func<char[]>(() => { return new char[] { 'a', 'b' }; });
+      ProtoBufSerializer serializer = new ProtoBufSerializer();
+      serializer.Serialize(test(), tempFile);
+      object o = serializer.Deserialize(tempFile);
+      char[] result = (char[])o;
+      Assert.AreEqual(test()[0], result[0]);
+      Assert.AreEqual(test()[1], result[1]);
+
+      string msg = Profile(test);
+      Console.WriteLine(msg);
+    }
+
+    [TestMethod]
+    [TestCategory("Persistence4")]
+    [TestProperty("Time", "short")]
+    public void TestShorts() {
+      var test = new Func<short[]>(() => { return new short[] { 3, 1 }; });
+      ProtoBufSerializer serializer = new ProtoBufSerializer();
+      serializer.Serialize(test(), tempFile);
+      object o = serializer.Deserialize(tempFile);
+      short[] result = (short[])o;
+      Assert.AreEqual(test()[0], result[0]);
+      Assert.AreEqual(test()[1], result[1]);
+
+      string msg = Profile(test);
+      Console.WriteLine(msg);
+    }
+
+    [TestMethod]
+    [TestCategory("Persistence4")]
+    [TestProperty("Time", "short")]
+    public void TestUShorts() {
+      var test = new Func<ushort[]>(() => { return new ushort[] { 3, 1 }; });
+      ProtoBufSerializer serializer = new ProtoBufSerializer();
+      serializer.Serialize(test(), tempFile);
+      object o = serializer.Deserialize(tempFile);
+      ushort[] result = (ushort[])o;
+      Assert.AreEqual(test()[0], result[0]);
+      Assert.AreEqual(test()[1], result[1]);
+
+      string msg = Profile(test);
+      Console.WriteLine(msg);
+    }
+
+    [TestMethod]
+    [TestCategory("Persistence4")]
+    [TestProperty("Time", "short")]
     public void TestString() {
       var test = new Func<object>(() => { return "Hello World!"; });
@@ -669,5 +736,5 @@
     [TestProperty("Time", "short")]
     public void TestColor() {
-      var test = new Func<object>(() => { return Color.DeepSkyBlue; });
+      var test = new Func<object>(() => { return Color.FromArgb(12, 34, 56, 78); });
       ProtoBufSerializer serializer = new ProtoBufSerializer();
       serializer.Serialize(test(), tempFile);
@@ -791,4 +858,56 @@
     [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
+    public void TestStack() {
+      var test = new Func<Stack>(() => {
+        return new Stack(new int[] { 1, 2, 3 });
+      });
+      ProtoBufSerializer serializer = new ProtoBufSerializer();
+      serializer.Serialize(test(), tempFile);
+      object o = serializer.Deserialize(tempFile);
+      Stack result = (Stack)o;
+      var actualStack = test();
+      Assert.AreEqual(actualStack.Pop(), result.Pop());
+      Assert.AreEqual(actualStack.Pop(), result.Pop());
+      Assert.AreEqual(actualStack.Pop(), result.Pop());
+
+      string msg = Profile(test);
+      Console.WriteLine(msg);
+    }
+
+    [TestMethod]
+    [TestCategory("Persistence4")]
+    [TestProperty("Time", "short")]
+    public void TestArrayOfStack() {
+      var test = new Func<object[]>(() => {
+        return new object[] {
+          new Stack(new int[] { 1, 2, 3 }),
+          new Stack<int>(new int[] { 1, 2, 3 }),
+      };
+      });
+      ProtoBufSerializer serializer = new ProtoBufSerializer();
+      serializer.Serialize(test(), tempFile);
+      object o = serializer.Deserialize(tempFile);
+      var result = (object[])o;
+      var firstStack = (Stack)result[0];
+      var secondStack = (Stack<int>)result[1];
+      var actual = test();
+      var actualFirst = (Stack)actual[0];
+      var actualSecond = (Stack<int>)actual[1];
+
+      Assert.AreEqual(actualFirst.Pop(), firstStack.Pop());
+      Assert.AreEqual(actualFirst.Pop(), firstStack.Pop());
+      Assert.AreEqual(actualFirst.Pop(), firstStack.Pop());
+      Assert.AreEqual(actualSecond.Pop(), secondStack.Pop());
+      Assert.AreEqual(actualSecond.Pop(), secondStack.Pop());
+      Assert.AreEqual(actualSecond.Pop(), secondStack.Pop());
+
+      string msg = Profile(test);
+      Console.WriteLine(msg);
+    }
+
+
+    [TestMethod]
+    [TestCategory("Persistence4")]
+    [TestProperty("Time", "short")]
     public void TestIntValueArray() {
       var test = new Func<IntValue[]>(() => { return new[] { new IntValue(41), new IntValue(22), new IntValue(13) }; });
@@ -797,7 +916,24 @@
       object o = serializer.Deserialize(tempFile);
       IntValue[] result = (IntValue[])o;
-      Assert.AreEqual(test()[0], result[0]);
-      Assert.AreEqual(test()[1], result[1]);
-      Assert.AreEqual(test()[2], result[2]);
+      Assert.AreEqual(test()[0].Value, result[0].Value);
+      Assert.AreEqual(test()[1].Value, result[1].Value);
+      Assert.AreEqual(test()[2].Value, result[2].Value);
+
+      string msg = Profile(test);
+      Console.WriteLine(msg);
+    }
+
+    [TestMethod]
+    [TestCategory("Persistence4")]
+    [TestProperty("Time", "short")]
+    public void TestIntValueArrayArray() {
+      var test = new Func<IntValue[][]>(() => { return new IntValue[][] { new IntValue[] { new IntValue(41), new IntValue(22), new IntValue(13) } }; });
+      ProtoBufSerializer serializer = new ProtoBufSerializer();
+      serializer.Serialize(test(), tempFile);
+      object o = serializer.Deserialize(tempFile);
+      IntValue[][] result = (IntValue[][])o;
+      Assert.AreEqual(test()[0][0].Value, result[0][0].Value);
+      Assert.AreEqual(test()[0][1].Value, result[0][1].Value);
+      Assert.AreEqual(test()[0][2].Value, result[0][2].Value);
 
       string msg = Profile(test);
@@ -809,5 +945,5 @@
     #region Old persistence test methods
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void ComplexStorable() {
@@ -899,5 +1035,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void SelfReferences() {
@@ -927,5 +1063,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void ArrayCreation() {
@@ -957,5 +1093,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void CustomSerializationProperty() {
@@ -974,5 +1110,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void Primitives() {
@@ -987,5 +1123,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void MultiDimensionalArray() {
@@ -1018,5 +1154,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void NestedTypeTest() {
@@ -1033,5 +1169,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void SimpleArray() {
@@ -1046,5 +1182,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void PrimitiveRoot() {
@@ -1101,5 +1237,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void Enums() {
@@ -1117,5 +1253,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void TestAliasingWithOverriddenEquals() {
@@ -1135,5 +1271,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void NonDefaultConstructorTest() {
@@ -1143,11 +1279,10 @@
         serializer.Serialize(c, tempFile);
         Assert.Fail("Exception not thrown");
-      }
-      catch (PersistenceException) {
-      }
-    }
-
-    [TestMethod]
-    [TestCategory("Persistence")]
+      } catch (PersistenceException) {
+      }
+    }
+
+    [TestMethod]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void TestSavingException() {
@@ -1159,6 +1294,5 @@
         serializer.Serialize(s, tempFile);
         Assert.Fail("Exception expected");
-      }
-      catch (PersistenceException) { }
+      } catch (PersistenceException) { }
       List<int> newList = (List<int>)serializer.Deserialize(tempFile);
       Assert.AreEqual(list[0], newList[0]);
@@ -1167,5 +1301,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void TestTypeStringConversion() {
@@ -1179,5 +1313,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void TestHexadecimalPublicKeyToken() {
@@ -1189,5 +1323,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void InheritanceTest() {
@@ -1219,5 +1353,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void InstantiateParentChainReference() {
@@ -1244,5 +1378,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void StructTest() {
@@ -1255,5 +1389,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void PointTest() {
@@ -1266,5 +1400,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void NullableValueTypes() {
@@ -1280,5 +1414,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void BitmapTest() {
@@ -1314,5 +1448,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void HookTest() {
@@ -1347,5 +1481,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void TestCustomConstructor() {
@@ -1368,5 +1502,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void TestConstructorExceptionUnwrapping() {
@@ -1377,6 +1511,5 @@
         ExplodingDefaultConstructor newX = (ExplodingDefaultConstructor)serializer.Deserialize(tempFile);
         Assert.Fail("Exception expected");
-      }
-      catch (PersistenceException pe) {
+      } catch (PersistenceException pe) {
         Assert.AreEqual(pe.InnerException.Message, "this constructor will always fail");
       }
@@ -1384,20 +1517,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
-    [TestProperty("Time", "short")]
-    public void TestRejectionJustifications() {
-      ProtoBufSerializer serializer = new ProtoBufSerializer();
-      NonSerializable ns = new NonSerializable();
-      try {
-        serializer.Serialize(ns, tempFile);
-        Assert.Fail("PersistenceException expected");
-      }
-      catch (PersistenceException x) {
-        Assert.IsTrue(x.Message.Contains(new StorableSerializer().JustifyRejection(typeof(NonSerializable))));
-      }
-    }
-
-    [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void TestStreaming() {
@@ -1436,5 +1554,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void TestLinkInheritance() {
@@ -1466,5 +1584,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void TestStorableClassDiscoveryAllFields() {
@@ -1498,5 +1616,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void TestStorableClassDiscoveryAllProperties() {
@@ -1531,5 +1649,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void TestStorableClassDiscoveryAllFieldsAndAllProperties() {
@@ -1563,5 +1681,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void TestStorableClassDiscoveryMarkedOnly() {
@@ -1577,5 +1695,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void TestLineEndings() {
@@ -1594,5 +1712,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void TestSpecialNumbers() {
@@ -1610,5 +1728,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void TestStringSplit() {
@@ -1633,5 +1751,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void TestHashSetSerializer() {
@@ -1654,5 +1772,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void TestConcreteDictionarySerializer() {
@@ -1695,5 +1813,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void TestReadOnlyFail() {
@@ -1702,8 +1820,6 @@
         serializer.Serialize(new ReadOnlyFail(), tempFile);
         Assert.Fail("Exception expected");
-      }
-      catch (PersistenceException) {
-      }
-      catch {
+      } catch (PersistenceException) {
+      } catch {
         Assert.Fail("PersistenceException expected");
       }
@@ -1720,5 +1836,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void TestWriteOnlyFail() {
@@ -1727,8 +1843,6 @@
         serializer.Serialize(new WriteOnlyFail(), tempFile);
         Assert.Fail("Exception expected");
-      }
-      catch (PersistenceException) {
-      }
-      catch {
+      } catch (PersistenceException) {
+      } catch {
         Assert.Fail("PersistenceException expected.");
       }
@@ -1751,5 +1865,5 @@
     //TODO
     /* [TestMethod]
-     [TestCategory("Persistence")]
+     [TestCategory("Persistence4")]
      [TestProperty("Time", "short")]
      public void TestTypeCacheExport() {
@@ -1769,5 +1883,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void TupleTest() {
@@ -1777,11 +1891,11 @@
       var t4 = Tuple.Create(Tuple.Create(1, 2, 3), Tuple.Create(4, 5, 6), Tuple.Create(8, 9, 10));
       var tuple = Tuple.Create(t1, t2, t3, t4);
-      XmlGenerator.Serialize(tuple, tempFile);
-      var newTuple = XmlParser.Deserialize<Tuple<Tuple<int>, Tuple<char, string>, Tuple<double, float, int>, Tuple<Tuple<int, int, int>, Tuple<int, int, int>, Tuple<int, int, int>>>>(tempFile);
+      SerializeNew(tuple);
+      var newTuple = DeserializeNew();
       Assert.AreEqual(tuple, newTuple);
     }
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void FontTest() {
@@ -1802,5 +1916,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "medium")]
     public void ConcurrencyTest() {
@@ -1821,5 +1935,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "medium")]
     public void ConcurrentBitmapTest() {
@@ -1852,5 +1966,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void TestSpecialCharacters() {
@@ -1863,5 +1977,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void TestByteArray() {
@@ -1877,5 +1991,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void TestOptionalNumberEnumerable() {
@@ -1888,5 +2002,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void TestOptionalDateTimeEnumerable() {
@@ -1900,5 +2014,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void TestStringEnumerable() {
@@ -1911,5 +2025,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void TestUnicodeCharArray() {
@@ -1922,5 +2036,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void TestUnicode() {
@@ -1933,5 +2047,5 @@
 
     [TestMethod]
-    [TestCategory("Persistence")]
+    [TestCategory("Persistence4")]
     [TestProperty("Time", "short")]
     public void TestQueue() {
