Index: branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/StorableAttribute.cs
===================================================================
--- branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/StorableAttribute.cs	(revision 15986)
+++ branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/StorableAttribute.cs	(revision 16210)
@@ -21,10 +21,8 @@
 
 using System;
+using System.Collections.Generic;
 using System.Reflection;
-using System.Text;
 
 namespace HeuristicLab.Persistence {
-
-
   /// <summary>
   /// Mark the member of a class to be considered by the <c>StorableSerializer</c>.
@@ -36,13 +34,10 @@
     AttributeTargets.Field | AttributeTargets.Property,
     AllowMultiple = false,
-    Inherited = false)]
-  public class StorableAttribute : Attribute {
-    public static bool IsStorable(MemberInfo memberInfo) {
-      return Attribute.IsDefined(memberInfo, typeof(StorableAttribute), false);
-    }
-    public static StorableAttribute GetStorableAttribute(MemberInfo memberInfo) {
-      return (StorableAttribute)Attribute.GetCustomAttribute(memberInfo, typeof(StorableAttribute), false);
-    }
+    Inherited = false
+  )]
+  public sealed class StorableAttribute : Attribute {
+    private static IDictionary<MemberInfo, StorableAttribute> attributeCache = new Dictionary<MemberInfo, StorableAttribute>();
 
+    #region Properties
     /// <summary>
     /// An optional name for this member that will be used during serialization.
@@ -67,28 +62,22 @@
     /// deserialized (setter only) but not serialized again.
     /// </summary>
+    [Obsolete("Use OldName instead.")]
     public bool AllowOneWay { get; set; }
 
-    /// <summary>
-    /// Returns a <see cref="System.String"/> that represents this instance.
-    /// </summary>
-    /// <returns>
-    /// A <see cref="System.String"/> that represents this instance.
-    /// </returns>
-    public override string ToString() {
-      StringBuilder sb = new StringBuilder();
-      sb.Append("[Storable");
-      if (Name != null || DefaultValue != null)
-        sb.Append('(');
-      if (Name != null) {
-        sb.Append("Name = \"").Append(Name).Append("\"");
-        if (DefaultValue != null)
-          sb.Append(", ");
+    public string OldName { get; set; }
+    #endregion
+
+    public static bool IsStorable(MemberInfo memberInfo) {
+      return GetStorableAttribute(memberInfo) != null;
+    }
+    public static StorableAttribute GetStorableAttribute(MemberInfo memberInfo) {
+      StorableAttribute attrib;
+
+      if (!attributeCache.TryGetValue(memberInfo, out attrib)) {
+        attrib = (StorableAttribute)GetCustomAttribute(memberInfo, typeof(StorableAttribute), false);
+        if (attrib != null) attributeCache[memberInfo] = attrib;
       }
-      if (DefaultValue != null)
-        sb.Append("DefaultValue = \"").Append(DefaultValue).Append("\"");
-      if (Name != null || DefaultValue != null)
-        sb.Append(')');
-      sb.Append(']');
-      return sb.ToString();
+
+      return attrib;
     }
   }
Index: branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/StorableHookAttribute.cs
===================================================================
--- branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/StorableHookAttribute.cs	(revision 15986)
+++ branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/StorableHookAttribute.cs	(revision 16210)
@@ -21,15 +21,13 @@
 
 using System;
+using System.Collections.Generic;
 using System.Linq;
 using System.Reflection;
 
 namespace HeuristicLab.Persistence {
-
-
   /// <summary>
   /// Indicates the time at which the hook should be invoked.
   /// </summary>
   public enum HookType {
-
     /// <summary>
     /// States that this hook should be called before the storable
@@ -45,5 +43,4 @@
   };
 
-
   /// <summary>
   /// Mark methods that should be called at certain times during
@@ -53,12 +50,7 @@
   [StorableType("983bf558-1458-4129-b018-7e121ac3840e")]
   public sealed class StorableHookAttribute : Attribute {
-    public static bool IsStorableHook(MethodInfo methodInfo) {
-      return Attribute.IsDefined(methodInfo, typeof(StorableHookAttribute), false);
-    }
-    public static StorableHookAttribute[] GetStorableHookAttributes(MethodInfo methodInfo) {
-      return Attribute.GetCustomAttributes(methodInfo, false).OfType<StorableHookAttribute>().ToArray();
-    }
+    private static IDictionary<MethodInfo, StorableHookAttribute[]> attributeCache = new Dictionary<MethodInfo, StorableHookAttribute[]>();
 
-    private readonly HookType hookType;
+    #region Properties
     /// <summary>
     /// Gets the type of the hook.
@@ -68,4 +60,6 @@
       get { return hookType; }
     }
+    private readonly HookType hookType;
+    #endregion
 
     /// <summary>
@@ -77,4 +71,19 @@
       this.hookType = hookType;
     }
+
+    public static bool IsStorableHook(MethodInfo methodInfo) {
+      return GetStorableHookAttributes(methodInfo) != null;
+    }
+
+    public static StorableHookAttribute[] GetStorableHookAttributes(MethodInfo methodInfo) {
+      StorableHookAttribute[] attribs;
+
+      if (!attributeCache.TryGetValue(methodInfo, out attribs)) {
+        attribs = (StorableHookAttribute[])GetCustomAttributes(methodInfo, typeof(StorableHookAttribute), false);
+        if (attribs.Any()) attributeCache[methodInfo] = attribs;
+      }
+
+      return attribs;
+    }
   }
 }
Index: branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/StorableTypeAttribute.cs
===================================================================
--- branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/StorableTypeAttribute.cs	(revision 15986)
+++ branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/StorableTypeAttribute.cs	(revision 16210)
@@ -21,14 +21,19 @@
 
 using System;
+using System.Collections.Generic;
 
 namespace HeuristicLab.Persistence {
-
   /// <summary>
   /// Mark a class to be considered by the <c>StorableSerializer</c>.
   /// </summary>
-  [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface | AttributeTargets.Enum | AttributeTargets.Delegate, Inherited = false, AllowMultiple = false)]
+  [AttributeUsage(
+    AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface | AttributeTargets.Enum | AttributeTargets.Delegate,
+    Inherited = false,
+    AllowMultiple = false
+  )]
   public sealed class StorableTypeAttribute : Attribute {
+    private static IDictionary<Type, StorableTypeAttribute> attributeCache = new Dictionary<Type, StorableTypeAttribute>();
 
-
+    #region Properties
     /// <summary>
     /// Specify how members are selected for serialization.
@@ -36,5 +41,10 @@
     public StorableMemberSelection MemberSelection { get; private set; }
 
+    /// <summary>
+    /// The GUID that identifies the type.
+    /// </summary>
+    /// <value>The GUID.</value>
     public Guid Guid { get; private set; }
+    #endregion
 
     /// <summary>
@@ -64,12 +74,17 @@
     /// <returns></returns>
     public static bool IsStorableType(Type type) {
-      object[] attribs = type.GetCustomAttributes(typeof(StorableTypeAttribute), false);
-      return attribs.Length > 0;
+      return GetStorableTypeAttribute(type) != null;
     }
 
     public static StorableTypeAttribute GetStorableTypeAttribute(Type type) {
-      return (StorableTypeAttribute)Attribute.GetCustomAttribute(type, typeof(StorableTypeAttribute), false);
+      StorableTypeAttribute attrib;
+
+      if (!attributeCache.TryGetValue(type, out attrib)) {
+        attrib = (StorableTypeAttribute)GetCustomAttribute(type, typeof(StorableTypeAttribute), false);
+        if (attrib != null) attributeCache[type] = attrib;
+      }
+
+      return attrib;
     }
-
   }
 }
Index: branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/TypeInfo.cs
===================================================================
--- branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/TypeInfo.cs	(revision 15986)
+++ branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/TypeInfo.cs	(revision 16210)
@@ -42,4 +42,5 @@
       constructor = null;
       Type = type;
+      StorableTypeAttribute = StorableTypeAttribute.GetStorableTypeAttribute(type);
       Fields = Enumerable.Empty<ComponentInfo>();
       Properties = Enumerable.Empty<ComponentInfo>();
@@ -56,5 +57,5 @@
     private void Reflect() {
       var type = Type;
-      StorableTypeAttribute = StorableTypeAttribute.GetStorableTypeAttribute(type);
+
       if (StorableTypeAttribute != null) {
         string guidPrefix = StorableTypeAttribute.Guid.ToString().ToUpper();
@@ -78,6 +79,38 @@
 
           foreach (var field in fieldInfos) {
+            var name = field.Name;
             var attrib = StorableAttribute.GetStorableAttribute(field);
-            var name = attrib == null || string.IsNullOrEmpty(attrib.Name) ? field.Name : attrib.Name;
+
+            if (attrib != null) {
+              if (!string.IsNullOrEmpty(attrib.Name) && !string.IsNullOrEmpty(attrib.OldName))
+                throw new PersistenceException("Cannot use Name and OldName at the same time.");
+
+              if (!string.IsNullOrEmpty(attrib.Name)) name = attrib.Name;
+              else if (!string.IsNullOrEmpty(attrib.OldName)) name = attrib.OldName;
+            }
+
+            var nameParts = name.Split('.').ToArray();
+            var sourceType = type;
+            var tmpGuid = Guid.Empty;
+
+            for (int i = 0; i < nameParts.Length; i++) {
+              var part = nameParts[i];
+              if (part == "base") sourceType = sourceType.BaseType;
+              else if (Guid.TryParse(part, out tmpGuid)) {
+                if (i != 0 || nameParts.Length != 2) throw new PersistenceException("Invalid field path specified.");
+                guidPrefix = tmpGuid.ToString().ToUpper();
+                break;
+              } else if (i != nameParts.Length - 1)
+                throw new PersistenceException("Invalid field path specified.");
+              else break;
+            }
+
+            if (sourceType != type) {
+              name = nameParts[nameParts.Length - 1];
+              guidPrefix = StorableTypeAttribute.GetStorableTypeAttribute(sourceType).Guid.ToString().ToUpper();
+            } else if (tmpGuid != Guid.Empty) {
+              name = nameParts[nameParts.Length - 1];
+            }
+
             fields.Add(new ComponentInfo(name, guidPrefix + "." + name, field, attrib, true, true));
           }
@@ -93,9 +126,44 @@
 
           foreach (var property in propertyInfos) {
+            var name = property.Name;
             var attrib = StorableAttribute.GetStorableAttribute(property);
-            if ((!property.CanRead || !property.CanWrite) && (attrib == null || !attrib.AllowOneWay))
-              throw new PersistenceException("Properties must be readable and writable or have one way serialization explicitly enabled.");
-
-            var name = attrib == null || string.IsNullOrEmpty(attrib.Name) ? property.Name : attrib.Name;
+
+            if (attrib != null) {
+              if (!string.IsNullOrEmpty(attrib.Name) && !string.IsNullOrEmpty(attrib.OldName))
+                throw new PersistenceException("Cannot use Name and OldName at the same time.");
+
+              if (attrib.AllowOneWay && !string.IsNullOrEmpty(attrib.OldName))
+                throw new PersistenceException("Cannot use AllowOneWay and OldName at the same time.");
+
+              if (!string.IsNullOrEmpty(attrib.Name)) name = attrib.Name;
+              else if (!string.IsNullOrEmpty(attrib.OldName)) name = attrib.OldName;
+            }
+
+            if ((!property.CanRead || !property.CanWrite) && (attrib == null || !attrib.AllowOneWay && string.IsNullOrEmpty(attrib.OldName)))
+              throw new PersistenceException("Properties must be readable and writable or have one way serialization explicitly enabled or use OldName.");
+
+            var nameParts = name.Split('.').ToArray();
+            var sourceType = type;
+            var tmpGuid = Guid.Empty;
+
+            for (int i = 0; i < nameParts.Length; i++) {
+              var part = nameParts[i];
+              if (part == "base") sourceType = sourceType.BaseType;
+              else if (Guid.TryParse(part, out tmpGuid)) {
+                if (i != 0 || nameParts.Length != 2) throw new PersistenceException("Invalid field path specified.");
+                guidPrefix = tmpGuid.ToString().ToUpper();
+                break;
+              } else if (i != nameParts.Length - 1)
+                throw new PersistenceException("Invalid field path specified.");
+              else break;
+            }
+
+            if (sourceType != type) {
+              name = nameParts[nameParts.Length - 1];
+              guidPrefix = StorableTypeAttribute.GetStorableTypeAttribute(sourceType).Guid.ToString().ToUpper();
+            } else if (tmpGuid != Guid.Empty) {
+              name = nameParts[nameParts.Length - 1];
+            }
+
             properties.Add(new ComponentInfo(name, guidPrefix + "." + name, property, attrib, property.CanRead, property.CanWrite));
           }
Index: branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Transformers/Transformers.cs
===================================================================
--- branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Transformers/Transformers.cs	(revision 15986)
+++ branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Transformers/Transformers.cs	(revision 16210)
@@ -473,5 +473,5 @@
   [Transformer("C47A62F5-F113-4A43-A8EE-CF817EC799A2", 303)]
   [StorableType("BA53DF84-DC97-4D8D-A493-868972ED1002")]
-  internal sealed class DictionaryTransformer : BoxTransformer<object> {
+  internal sealed class IDictionary : BoxTransformer<object> {
     public override bool CanTransformType(Type type) {
       return type.IsGenericType && typeof(Dictionary<,>) == type.GetGenericTypeDefinition();
@@ -480,5 +480,5 @@
     protected override void Populate(Box box, object value, Mapper mapper) {
       var kvps = box.KeyValuePairs;
-      foreach (DictionaryEntry item in (IDictionary)value)
+      foreach (DictionaryEntry item in (System.Collections.IDictionary)value)
         kvps.Add(mapper.GetBoxId(item.Key), mapper.GetBoxId(item.Value));
 
@@ -855,5 +855,12 @@
           if (attrib != null && attrib.DefaultValue != null)
             fieldInfo.SetValue(obj, attrib.DefaultValue);
+
+          object value;
+          if (!dict.TryGetValue(componentInfo.FullName, out value)) continue;
+
+          var field = (FieldInfo)componentInfo.MemberInfo;
+          field.SetValue(obj, value);
         }
+
         foreach (var componentInfo in typeInfo.Properties.Where(x => x.Writeable)) {
           var attrib = componentInfo.StorableAttribute;
@@ -861,33 +868,39 @@
           if (attrib != null && attrib.DefaultValue != null)
             property.SetValue(obj, attrib.DefaultValue, null);
+
+          object value;
+          if (!dict.TryGetValue(componentInfo.FullName, out value)) continue;
+
+          var prop = (PropertyInfo)componentInfo.MemberInfo;
+          prop.SetValue(obj, value, null);
         }
 
         // set all members
-        foreach (var kvp in dict) {
-          string key = kvp.Key;
-          object val = kvp.Value;
-
-          string[] keyParts = key.Split('.');
-          var guid = Guid.Parse(keyParts[0]);
-          string ident = keyParts[1];
-
-          if (guid != typeInfo.StorableTypeAttribute.Guid) continue;
-
-          var fieldInfo = typeInfo.Fields.FirstOrDefault(fi => fi.Name == ident);
-          if (fieldInfo != null) {
-            var field = (FieldInfo)fieldInfo.MemberInfo;
-            field.SetValue(obj, val);
-            //dict.Remove(guid.ToString().ToUpperInvariant() + "." + fieldInfo.Name); // only for consistency check
-            continue;
-          }
-
-          var propInfo = typeInfo.Properties.Where(x => x.Writeable).FirstOrDefault(fi => fi.Name == ident);
-          if (propInfo != null) {
-            var prop = (PropertyInfo)propInfo.MemberInfo;
-            prop.SetValue(obj, val, null);
-            //dict.Remove(guid.ToString().ToUpperInvariant() + "." + propInfo.Name); // only for consistency check
-            continue;
-          }
-        }
+        //foreach (var kvp in dict) {
+        //  string key = kvp.Key;
+        //  object val = kvp.Value;
+
+        //  string[] keyParts = key.Split('.');
+        //  var guid = Guid.Parse(keyParts[0]);
+        //  string ident = keyParts[1];
+
+        //  if (guid != typeInfo.StorableTypeAttribute.Guid) continue;
+
+        //  var fieldInfo = typeInfo.Fields.FirstOrDefault(fi => fi.Name == ident);
+        //  if (fieldInfo != null) {
+        //    var field = (FieldInfo)fieldInfo.MemberInfo;
+        //    field.SetValue(obj, val);
+        //    //dict.Remove(guid.ToString().ToUpperInvariant() + "." + fieldInfo.Name); // only for consistency check
+        //    continue;
+        //  }
+
+        //  var propInfo = typeInfo.Properties.Where(x => x.Writeable).FirstOrDefault(fi => fi.Name == ident);
+        //  if (propInfo != null) {
+        //    var prop = (PropertyInfo)propInfo.MemberInfo;
+        //    prop.SetValue(obj, val, null);
+        //    //dict.Remove(guid.ToString().ToUpperInvariant() + "." + propInfo.Name); // only for consistency check
+        //    continue;
+        //  }
+        //}
 
         //var undefinedMembers = dict.Where(x => Guid.Parse(x.Key.Split('.')[0]) == typeInfo.StorableTypeAttribute.Guid);
Index: branches/PersistenceReintegration/HeuristicLab.Tests/HeuristicLab.Persistence-3.3/UseCasesPersistenceNew.cs
===================================================================
--- branches/PersistenceReintegration/HeuristicLab.Tests/HeuristicLab.Persistence-3.3/UseCasesPersistenceNew.cs	(revision 15986)
+++ branches/PersistenceReintegration/HeuristicLab.Tests/HeuristicLab.Persistence-3.3/UseCasesPersistenceNew.cs	(revision 16210)
@@ -32,5 +32,4 @@
 using System.Threading.Tasks;
 using HeuristicLab.Algorithms.GeneticAlgorithm;
-using HeuristicLab.Core;
 using HeuristicLab.Data;
 using HeuristicLab.Persistence;
@@ -327,8 +326,8 @@
     }
 
-    public static void DeregisterType(Type type) {
-      var typeInfo = GetTypeInfo(type);
-      type2Guid.Remove(guid2Type[typeInfo.StorableTypeAttribute.Guid]);
-      guid2Type.Remove(typeInfo.StorableTypeAttribute.Guid);
+    public static void DeregisterType(Guid guid) {
+      if (!guid2Type.ContainsKey(guid)) return;
+      type2Guid.Remove(guid2Type[guid]);
+      guid2Type.Remove(guid);
     }
 
@@ -337,16 +336,24 @@
     }
 
-    //public static void RemoveTypeInfo(Type type) {
-    //  typeInfos.Remove(typeof(ConversionA));
+    private static void ReplaceTypeImplementation(Type old, Guid oldGuid, Type @new) {
+      DeregisterType(oldGuid);
+      DeregisterType(StorableTypeAttribute.GetStorableTypeAttribute(@new).Guid);
+
+      RegisterType(oldGuid, @new);
+      SetTypeGuid(@new, oldGuid);
+      typeInfos.Remove(old);
+    }
+
+    //public static Guid GetTypeGuid(Type type) {
+    //  var typeInfo = GetTypeInfo(type);
+    //  return typeInfo.StorableTypeAttribute.Guid;
     //}
-
-    public static Guid GetTypeGuid(Type type) {
-      var typeInfo = GetTypeInfo(type);
-      return typeInfo.StorableTypeAttribute.Guid;
-    }
 
     public static void SetTypeGuid(Type type, Guid guid) {
       var typeInfo = GetTypeInfo(type);
       guidPropertyInfo.SetValue(typeInfo.StorableTypeAttribute, guid);
+
+      var reflectMethod = typeInfo.GetType().GetMethod("Reflect", BindingFlags.NonPublic | BindingFlags.Instance);
+      reflectMethod.Invoke(typeInfo, new object[0]);
     }
     #endregion
@@ -2670,4 +2677,341 @@
     //}
     #endregion
+
+    [StorableType("28A5F6B8-49AF-4C6A-AF0E-F92EB4511722")]
+    private class PersistenceTestA0 {
+      [Storable]
+      public IntValue v;
+    }
+
+    [StorableType("00000000-0000-0000-0000-0000000000A1")]
+    private class PersistenceTestA1 {
+      [Storable(OldName = "v")]
+      private IntValue v1 {
+        set { v = value.Value; }
+      }
+
+      [Storable(Name = "v2")]
+      public int v;
+    }
+
+    [StorableType("00000000-0000-0000-0000-0000000000A2")]
+    private class PersistenceTestA2 {
+      [Storable(OldName = "v")]
+      private IntValue v1 {
+        set { v2 = value.Value; }
+      }
+
+      [Storable(OldName = "v2")]
+      private int v2 {
+        set { v = (double)value; }
+      }
+
+      [Storable(Name = "v3")]
+      public double v;
+    }
+
+    [TestMethod]
+    [TestCategory("PersistenceNew.Conversion")]
+    [TestProperty("Time", "short")]
+    public void TestConversionSample1() {
+      var v0Type = typeof(PersistenceTestA0);
+      var v0Guid = StorableTypeAttribute.GetStorableTypeAttribute(v0Type).Guid;
+
+      var test = new Func<PersistenceTestA0>(() => {
+        return new PersistenceTestA0() { v = new IntValue(1337) };
+      });
+
+      ProtoBufSerializer serializer = new ProtoBufSerializer();
+      var v0 = test();
+      serializer.Serialize(v0, tempFile);
+
+      ReplaceTypeImplementation(v0Type, v0Guid, typeof(PersistenceTestA1));
+
+      var v1 = (PersistenceTestA1)serializer.Deserialize(tempFile);
+      Assert.AreEqual(v0.v.Value, v1.v);
+
+      ReplaceTypeImplementation(typeof(PersistenceTestA1), v0Guid, typeof(PersistenceTestA2));
+
+      var v2 = (PersistenceTestA2)serializer.Deserialize(tempFile);
+      Assert.AreEqual(v2.v, v1.v);
+    }
+
+    [StorableType("7DCED655-D724-492E-9C6A-A22B376BADB2")]
+    private class PersistenceTestB0 {
+      [Storable]
+      public Point p;
+    }
+
+    [StorableType("00000000-0000-0000-0000-0000000000B1")]
+    private class PersistenceTestB1 {
+      [Storable(AllowOneWay = true)]
+      private Point p {
+        set {
+          x = value.X;
+          y = value.Y;
+        }
+      }
+
+      [Storable]
+      public int x;
+
+      [Storable]
+      public int y;
+    }
+
+    [StorableType("00000000-0000-0000-0000-0000000000B2")]
+    private class PersistenceTestB2 {
+      [Storable(AllowOneWay = true)]
+      private int x { set { p = new Point(value, p.Y); } }
+
+      [Storable(AllowOneWay = true)]
+      private int y { set { p = new Point(p.X, value); } }
+
+      [Storable]
+      public Point p { get; private set; }
+    }
+
+    [TestMethod]
+    [TestCategory("PersistenceNew.Conversion")]
+    [TestProperty("Time", "short")]
+    public void TestConversionSample2() {
+      var v0Type = typeof(PersistenceTestB0);
+      var v0Guid = StorableTypeAttribute.GetStorableTypeAttribute(v0Type).Guid;
+
+      var test = new Func<PersistenceTestB0>(() => {
+        return new PersistenceTestB0() { p = new Point(1, 2) };
+      });
+
+      ProtoBufSerializer serializer = new ProtoBufSerializer();
+      var v0 = test();
+
+      // seriealize B0, deserialize B0
+      serializer.Serialize(v0, tempFile);
+      var newV0 = (PersistenceTestB0)serializer.Deserialize(tempFile);
+      Assert.AreEqual(v0.p.X, newV0.p.X);
+      Assert.AreEqual(v0.p.Y, newV0.p.Y);
+
+      // serialize B0, deserialize B1
+      ReplaceTypeImplementation(v0Type, v0Guid, typeof(PersistenceTestB1));
+      var v1 = (PersistenceTestB1)serializer.Deserialize(tempFile);
+      Assert.AreEqual(v0.p.X, v1.x);
+      Assert.AreEqual(v0.p.Y, v1.y);
+
+      // serialize B0, deserialize B2
+      ReplaceTypeImplementation(v0Type, v0Guid, typeof(PersistenceTestB2));
+      var v2 = (PersistenceTestB2)serializer.Deserialize(tempFile);
+      Assert.AreEqual(v0.p.X, v2.p.X);
+      Assert.AreEqual(v0.p.Y, v2.p.Y);
+
+      // serialize B1, deserialize B1
+      ReplaceTypeImplementation(v0Type, v0Guid, typeof(PersistenceTestB1));
+      serializer.Serialize(v1, tempFile);
+      var newV1 = (PersistenceTestB1)serializer.Deserialize(tempFile);
+      Assert.AreEqual(v1.x, newV1.x);
+      Assert.AreEqual(v1.y, newV1.y);
+
+      // serialize B1, deserialize B2
+      ReplaceTypeImplementation(v0Type, v0Guid, typeof(PersistenceTestB2));
+      v2 = (PersistenceTestB2)serializer.Deserialize(tempFile);
+      Assert.AreEqual(v1.x, v2.p.X);
+      Assert.AreEqual(v1.y, v2.p.Y);
+
+      // serialize B2, deserialize B2
+      serializer.Serialize(v2, tempFile);
+      var newV2 = (PersistenceTestB2)serializer.Deserialize(tempFile);
+      Assert.AreEqual(v2.p.X, newV2.p.X);
+      Assert.AreEqual(v2.p.Y, newV2.p.Y);
+    }
+
+    [StorableType("FB649DF5-5B99-45DE-807A-27E86CB22F4B")]
+    private class PersistenceTestC0 {
+      [Storable]
+      public PersistenceTestC0 neighbor;
+
+      [Storable]
+      public int value;
+    }
+
+    [StorableType("00000000-0000-0000-0000-0000000000C1")]
+    private class PersistenceTestC1 {
+      [Storable]
+      private PersistenceTestC1 neighbor;
+
+      [Storable]
+      public int neighborValue;
+
+      [Storable]
+      public int value;
+
+      [StorableHook(HookType.AfterDeserialization)]
+      private void AfterDeserialization() {
+        if (neighbor != null)
+          neighborValue = neighbor.value;
+      }
+    }
+
+    [TestMethod]
+    [TestCategory("PersistenceNew.Conversion")]
+    [TestProperty("Time", "short")]
+    public void TestConversionSample3() {
+      var v0Type = typeof(PersistenceTestC0);
+      var v0Guid = StorableTypeAttribute.GetStorableTypeAttribute(v0Type).Guid;
+
+      var test = new Func<PersistenceTestC0>(() => {
+        var c0 = new PersistenceTestC0() {
+          value = 90
+        };
+        c0.neighbor = c0;
+        return c0;
+      });
+
+      ProtoBufSerializer serializer = new ProtoBufSerializer();
+      var v0 = test();
+
+      // seriealize C0, deserialize C0
+      serializer.Serialize(v0, tempFile);
+      var newV0 = (PersistenceTestC0)serializer.Deserialize(tempFile);
+      Assert.AreEqual(v0.value, newV0.value);
+      Assert.ReferenceEquals(newV0.neighbor, newV0);
+
+      // serialize C0, deserialize C1
+      ReplaceTypeImplementation(v0Type, v0Guid, typeof(PersistenceTestC1));
+      var v1 = (PersistenceTestC1)serializer.Deserialize(tempFile);
+      Assert.AreEqual(v0.value, v1.value);
+      Assert.AreEqual(v1.neighborValue, v0.neighbor.value);
+    }
+
+    [StorableType("5AF91FB9-DB53-40BD-B961-A968D2F7CDE3")]
+    private class PersistenceTestSample4A0 {
+      [Storable]
+      public string Name;
+
+      [Storable]
+      public string Description;
+    }
+
+    [StorableType("5EDF9D5D-3B60-42E9-BA8D-7A007916D6AE")]
+    private class PersistenceTestSample4C0 : PersistenceTestSample4A0 {
+      [Storable]
+      public int p;
+    }
+
+    [StorableType("00000000-0000-0000-0000-0000000000D1")]
+    private class PersistenceTestSample4A1 {
+      [Storable]
+      public string Name;
+    }
+
+    [StorableType("A55EE4D0-EE2F-4DBD-834E-51200BFDBB9C")]
+    private class PersistenceTestSample4B : PersistenceTestSample4A1 {
+      [Storable(OldName = "base.Description")]
+      private string Description1 { set { Description = value; } }
+
+      [Storable(Name = "Description2")]
+      public string Description;
+    }
+
+    [StorableType("00000000-0000-0000-0000-0000000000E1")]
+    private class PersistenceTestSample4C1 : PersistenceTestSample4B {
+      [Storable]
+      public int p;
+    }
+
+    [StorableType("8CB577B8-C36B-4749-8CF4-33DE4D5AC4BF")]
+    class PersistenceTestSample4NewType0 : PersistenceTestSample4A1 {
+      [Storable]
+      public StringValue Description;
+    }
+
+    [StorableType("BCD9D34C-901C-44E6-B1FD-8F5E9E09D686")]
+    class AB {
+      [Storable(OldName = "5AF91FB9-DB53-40BD-B961-A968D2F7CDE3.Name", DefaultValue = "No name")]
+      public string Name;
+
+      [Storable(OldName = "A55EE4D0-EE2F-4DBD-834E-51200BFDBB9C.Description2", DefaultValue = "No description")]
+      public string Description;
+    }
+
+    [StorableType("00000000-0000-0000-0000-0000000000F1")]
+    class PersistenceTestSample4C2 : AB {
+      [Storable]
+      public int p;
+    }
+
+    [StorableType("00000000-0000-0000-0000-0000000001A1")]
+    class PersistenceTestSample4NewType1 : AB {
+      [Storable(OldName = "Description")]
+      private StringValue Description_Persistence_Setter {
+        set {
+          base.Description = value.Value;
+        }
+      }
+    }
+
+    [TestMethod]
+    [TestCategory("PersistenceNew.Conversion")]
+    [TestProperty("Time", "short")]
+    public void TestConversionSample4() {
+      var a0Type = typeof(PersistenceTestSample4A0);
+      var a0Guid = StorableTypeAttribute.GetStorableTypeAttribute(a0Type).Guid;
+      var c0Type = typeof(PersistenceTestSample4C0);
+      var c0Guid = StorableTypeAttribute.GetStorableTypeAttribute(c0Type).Guid;
+
+      var test = new Func<PersistenceTestSample4C0>(() => {
+        return new PersistenceTestSample4C0 {
+          Name = "test",
+          Description = "description",
+          p = 99
+        };
+      });
+
+      ProtoBufSerializer serializer = new ProtoBufSerializer();
+      var c0 = test();
+
+      // seriealize C0, deserialize C0
+      serializer.Serialize(c0, tempFile);
+      var newC0 = (PersistenceTestSample4C0)serializer.Deserialize(tempFile);
+      Assert.AreEqual(c0.Name, newC0.Name);
+      Assert.AreEqual(c0.Description, newC0.Description);
+      Assert.AreEqual(c0.p, newC0.p);
+
+      // serialize C0, deserialize C1
+      ReplaceTypeImplementation(c0Type, c0Guid, typeof(PersistenceTestSample4C1));
+      ReplaceTypeImplementation(a0Type, a0Guid, typeof(PersistenceTestSample4A1));
+      var c1 = (PersistenceTestSample4C1)serializer.Deserialize(tempFile);
+      Assert.AreEqual(c0.Name, c1.Name);
+      Assert.AreEqual(c0.Description, c1.Description);
+      Assert.AreEqual(c0.p, c1.p);
+
+      // serialize C1, deserialize C1
+      serializer.Serialize(c1, tempFile);
+      var newC1 = (PersistenceTestSample4C1)serializer.Deserialize(tempFile);
+      Assert.AreEqual(c1.Name, newC1.Name);
+      Assert.AreEqual(c1.Description, newC1.Description);
+      Assert.AreEqual(c1.p, newC1.p);
+
+      // serialize C1, deserialize C2
+      serializer.Serialize(c1, tempFile);
+      ReplaceTypeImplementation(c0Type, c0Guid, typeof(PersistenceTestSample4C2));
+      var c2 = (PersistenceTestSample4C2)serializer.Deserialize(tempFile);
+      Assert.AreEqual(c1.Name, c2.Name);
+      Assert.AreEqual(c1.Description, c2.Description);
+      Assert.AreEqual(c1.p, c2.p);
+
+      // serialize NewType0, deserialize NewType1
+      var newType0Type = typeof(PersistenceTestSample4NewType0);
+      var newType0Guid = StorableTypeAttribute.GetStorableTypeAttribute(newType0Type).Guid;
+
+      var newType0 = new PersistenceTestSample4NewType0 {
+        Name = "yeah",
+        Description = new StringValue("blubb")
+      };
+
+      serializer.Serialize(newType0, tempFile);
+      ReplaceTypeImplementation(newType0Type, newType0Guid, typeof(PersistenceTestSample4NewType1));
+      var newType1 = (PersistenceTestSample4NewType1)serializer.Deserialize(tempFile);
+      Assert.AreEqual(newType0.Name, newType1.Name);
+      Assert.AreEqual(newType0.Description.Value, newType1.Description);
+    }
     #endregion
   }
