Index: /branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/StorableConversionAttribute.cs
===================================================================
--- /branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/StorableConversionAttribute.cs	(revision 15033)
+++ /branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/StorableConversionAttribute.cs	(revision 15034)
@@ -26,7 +26,9 @@
   [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
   public sealed class StorableConversionAttribute : Attribute {
-    public uint SrcVersion { get; set; }
+    public Guid Guid { get; private set; }
+    public uint SrcVersion { get; private set; }
 
-    public StorableConversionAttribute(uint srcVersion) {
+    public StorableConversionAttribute(string guid, uint srcVersion) {
+      this.Guid = new Guid(guid);
       this.SrcVersion = srcVersion;
     }
@@ -35,9 +37,13 @@
       return Attribute.IsDefined(mi, typeof(StorableConversionAttribute), false);
     }
-    public static StorableConversionAttribute GetTransformerAttribute(MethodInfo mi) {
+
+    public static StorableConversionAttribute GetStorableConversionAttribute(MethodInfo mi) {
       return (StorableConversionAttribute)Attribute.GetCustomAttribute(mi, typeof(StorableConversionAttribute), false);
     }
+    public static Guid GetGuid(MethodInfo mi) {
+      return GetStorableConversionAttribute(mi).Guid;
+    }
     public static uint GetVersion(MethodInfo mi) {
-      return GetTransformerAttribute(mi).SrcVersion;
+      return GetStorableConversionAttribute(mi).SrcVersion;
     }
   }
Index: /branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/StorableTypeAttribute.cs
===================================================================
--- /branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/StorableTypeAttribute.cs	(revision 15033)
+++ /branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/StorableTypeAttribute.cs	(revision 15034)
@@ -37,5 +37,5 @@
 
     public Guid Guid { get; private set; }
-    public uint Version { get; set; }
+    public uint Version { get; private set; }
 
     /// <summary>
Index: /branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/TypeInfo.cs
===================================================================
--- /branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/TypeInfo.cs	(revision 15033)
+++ /branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Core/TypeInfo.cs	(revision 15034)
@@ -59,10 +59,10 @@
       if (StorableTypeAttribute != null) {
         // check constructors (
-        if (!type.IsValueType && !type.IsEnum && !type.IsInterface && 
+        if (!type.IsValueType && !type.IsEnum && !type.IsInterface &&
           GetStorableConstructor() == null && GetDefaultConstructor() == null)
           throw new PersistenceException("No storable constructor or parameterless constructor found.");
 
-          // traverse type hierarchy from base type to sub types
-          Stack<Type> types = new Stack<Type>();
+        // traverse type hierarchy from base type to sub types
+        Stack<Type> types = new Stack<Type>();
         while (type != null) {
           types.Push(type);
@@ -95,5 +95,5 @@
             foreach (var property in propertyInfos) {
               var attrib = StorableAttribute.GetStorableAttribute(property);
-              if (!attrib.AllowOneWay && (!property.CanRead || !property.CanWrite))
+              if ((!property.CanRead || !property.CanWrite) && (attrib == null || !attrib.AllowOneWay))
                 throw new PersistenceException("Properties must be readable and writable or explicity enable one way serialization.");
 
Index: /branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Transformers/StorableClassTransformer.cs
===================================================================
--- /branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Transformers/StorableClassTransformer.cs	(revision 15033)
+++ /branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Transformers/StorableClassTransformer.cs	(revision 15034)
@@ -72,4 +72,5 @@
       var typeBox = mapper.GetBox(box.TypeId).GetExtension(TypeBox.Type);
       var version = typeBox.HasVersion ? typeBox.Version : 1;
+      var typeGuid = typeInfo.StorableTypeAttribute.Guid;
 
       var components = new Dictionary<uint, uint>();
@@ -79,10 +80,13 @@
 
       var conversionMethods =
-        type.GetMethods(BindingFlags.NonPublic | BindingFlags.Static)
+        type.Assembly.GetTypes().SelectMany(t =>
+          t.GetMethods(BindingFlags.NonPublic | BindingFlags.Static)
           .Where(StorableConversionAttribute.IsStorableConversionMethod)
-          .Where(mi => StorableConversionAttribute.GetVersion(mi) >= version)
-          .OrderBy(StorableConversionAttribute.GetVersion);
+          .Where(mi => StorableConversionAttribute.GetGuid(mi) == typeGuid &&
+                       StorableConversionAttribute.GetVersion(mi) >= version))
+          .OrderBy(StorableConversionAttribute.GetVersion)
+          .ToArray();
 
-      // put all objects into dictionary for optional conversion
+      // put all objects into dictionary for conversion 
       var dict = new Dictionary<string, object>();
       foreach (var component in components) {
@@ -90,28 +94,50 @@
       }
 
-      // TODO: check that all entries in the dictionary can be mapped to a field or property
       foreach (var convMeth in conversionMethods) {
+        if (StorableConversionAttribute.GetVersion(convMeth) != version)
+          throw new PersistenceException(string.Format("No conversion method defined for type {0} version {1}", typeGuid, version));
         dict = (Dictionary<string, object>)convMeth.Invoke(null, new object[] { dict });
+        version++;
+      }
+      if (version != typeInfo.StorableTypeAttribute.Version)
+        throw new PersistenceException(string.Format("Missing one or more conversion methods for type {0} version {1}",
+          typeGuid, typeInfo.StorableTypeAttribute.Version));
+
+      // set default values for all fields and properties
+      foreach (var componentInfo in typeInfo.Fields) {
+        var field = (FieldInfo)componentInfo.MemberInfo;
+        if (componentInfo.StorableAttribute != null && componentInfo.StorableAttribute.DefaultValue != null)
+          field.SetValue(obj, componentInfo.StorableAttribute.DefaultValue);
+      }
+      foreach (var componentInfo in typeInfo.Properties.Where(x => x.Writeable)) {
+        var property = (PropertyInfo)componentInfo.MemberInfo;
+        if (componentInfo.StorableAttribute != null && componentInfo.StorableAttribute.DefaultValue != null)
+          property.SetValue(obj, componentInfo.StorableAttribute.DefaultValue, null);
       }
 
-      foreach (var componentInfo in typeInfo.Fields) {
-        var field = (FieldInfo)componentInfo.MemberInfo;
-        object val = null;
-        bool found = dict.TryGetValue(componentInfo.Name, out val);
-        if (found)
+      // set all members as generated by conversion method chain
+      foreach (var kvp in dict.ToArray()) {
+        var key = kvp.Key;
+        var val = kvp.Value;
+        var fieldInfo = typeInfo.Fields.FirstOrDefault(fi => fi.Name == key);
+        if (fieldInfo != null) {
+          var field = (FieldInfo)fieldInfo.MemberInfo;
           field.SetValue(obj, val);
-        else if (componentInfo.StorableAttribute.DefaultValue != null)
-          field.SetValue(obj, componentInfo.StorableAttribute.DefaultValue);
+          dict.Remove(fieldInfo.Name);
+          continue;
+        }
+        var propInfo = typeInfo.Properties.Where(x => x.Writeable).FirstOrDefault(pi => pi.Name == key);
+        if (propInfo != null) {
+          var prop = (PropertyInfo)propInfo.MemberInfo;
+          prop.SetValue(obj, val, null);
+          dict.Remove(propInfo.Name);
+          continue;
+        }
       }
 
-      foreach (var componentInfo in typeInfo.Properties.Where(x => x.Writeable)) {
-        var property = (PropertyInfo)componentInfo.MemberInfo;
-        object val = null;
-        bool found = dict.TryGetValue(componentInfo.Name, out val);
-        if (found)
-          property.SetValue(obj, val, null);
-        else if (componentInfo.StorableAttribute.DefaultValue != null)
-          property.SetValue(obj, componentInfo.StorableAttribute.DefaultValue, null);
-      }
+      if (dict.Any())
+        throw new PersistenceException(string.Format("Invalid conversion method. The following members are undefined in type {0} version {1}: {2}",
+          typeGuid, typeInfo.StorableTypeAttribute.Version,
+          string.Join(", ", dict.Keys)));
 
       var emptyArgs = new object[0];
Index: /branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Transformers/Transformers.cs
===================================================================
--- /branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Transformers/Transformers.cs	(revision 15033)
+++ /branches/PersistenceReintegration/HeuristicLab.Persistence/4.0/Transformers/Transformers.cs	(revision 15034)
@@ -332,4 +332,5 @@
         return ((Type)mapper.GetObject(b.GetGenericTypeIds(0))).MakeArrayType();
       } else {
+        
         return type;
       }
Index: /branches/PersistenceReintegration/HeuristicLab.Tests/HeuristicLab.Persistence-3.3/UseCasesPersistenceNew.cs
===================================================================
--- /branches/PersistenceReintegration/HeuristicLab.Tests/HeuristicLab.Persistence-3.3/UseCasesPersistenceNew.cs	(revision 15033)
+++ /branches/PersistenceReintegration/HeuristicLab.Tests/HeuristicLab.Persistence-3.3/UseCasesPersistenceNew.cs	(revision 15034)
@@ -2166,5 +2166,5 @@
     }
     [StorableType("00000000-0000-0000-0000-BADCAFFEE000", 2)] // for testing (version 2)
-    private partial class V2 : NewBaseType {
+    private class V2 : NewBaseType {
       [Storable]
       public int a;
@@ -2186,7 +2186,24 @@
     }
 
-    // conversion part
-    private partial class V2 : NewBaseType {
-      [StorableConversion(srcVersion: 1)]
+    [StorableType("00000000-0000-0000-0000-BADCAFFEE200", 3)] // for testing (version 3)
+    private class V3 : NewBaseType {
+      [Storable]
+      public int a;
+
+      [Storable]
+      public int[] val;
+
+      [Storable]
+      public V3 mySelf;
+
+      [Storable]
+      public Tuple<int, int> tup;
+
+      [Storable]
+      public Point coords;
+    }
+
+    private static class Conversions {
+      [StorableConversion("D211A828-6440-4E72-A8C7-AA4F9B4FFA75", 1)]
       private static Dictionary<string, object> ConvertV1(Dictionary<string, object> values) {
         var newValues = new Dictionary<string, object>();
@@ -2208,48 +2225,6 @@
         return newValues;
       }
-    }
-
-    [StorableType("00000000-0000-0000-0000-BADCAFFEE200", 3)] // for testing (version 3)
-    private partial class V3 : NewBaseType {
-      [Storable]
-      public int a;
-
-      [Storable]
-      public int[] val;
-
-      [Storable]
-      public V3 mySelf;
-
-      [Storable]
-      public Tuple<int, int> tup;
-
-      [Storable]
-      public Point coords;
-    }
-
-    // conversion part
-    private partial class V3 {
-      [StorableConversion(srcVersion: 1)]
-      private static Dictionary<string, object> ConvertV1(Dictionary<string, object> values) {
-        var newValues = new Dictionary<string, object>();
-        var items = (ItemCollection<IItem>)values["OldBaseType.items"];
-        newValues["NewBaseType.items"] = items.Select(iv => new DoubleValue((double)(((dynamic)iv).Value))).ToArray();
-        newValues["V2.a"] = ((IntValue)values["V1.a"]).Value;
-        newValues["V2.val"] = ((ItemList<IntValue>)values["V1.vals"]).Select(iv => iv.Value).ToArray();
-
-        newValues["V2.mySelf"] = values["V1.mySelf"]; // myself type will be mapped correctly
-
-        var tup = (Tuple<int, int>)values["V1.tup"];
-        if (tup != null) {
-          newValues["V2.TupItem1"] = tup.Item1;
-          newValues["V2.TupItem2"] = tup.Item2;
-        }
-
-        newValues["V2.coords"] = new Point((int)values["V1.x"], (int)values["V1.y"]);
-
-        return newValues;
-      }
-
-      [StorableConversion(srcVersion: 2)]
+
+      [StorableConversion("D211A828-6440-4E72-A8C7-AA4F9B4FFA75", 2)]
       private static Dictionary<string, object> ConvertV2(Dictionary<string, object> values) {
         var newValues = new Dictionary<string, object>();
@@ -2286,47 +2261,17 @@
       Mapper.StaticCache.DeregisterType(StorableTypeAttribute.GetStorableTypeAttribute(typeof(V1)).Guid);
       Mapper.StaticCache.DeregisterType(StorableTypeAttribute.GetStorableTypeAttribute(typeof(V2)).Guid);
-
-      Mapper.StaticCache.RegisterType(StorableTypeAttribute.GetStorableTypeAttribute(typeof(V1)).Guid, typeof(V2));
-
-      object o = serializer.Deserialize(tempFile);
-      var restored = (V2)o;
+      Mapper.StaticCache.DeregisterType(StorableTypeAttribute.GetStorableTypeAttribute(typeof(V3)).Guid);
+
+      Mapper.StaticCache.RegisterType(StorableTypeAttribute.GetStorableTypeAttribute(typeof(V1)).Guid, typeof(V3));
+      var pi = typeof(StorableTypeAttribute).GetProperty("Guid");
+      pi.SetValue(
+        Mapper.StaticCache.GetTypeInfo(typeof(V3)).StorableTypeAttribute,
+        StorableTypeAttribute.GetStorableTypeAttribute(typeof(V1)).Guid,
+        null);
+
+      object o = serializer.Deserialize(tempFile);
+      var restored = (V3)o;
       Assert.AreEqual(restored.a, old.a.Value);
-      Assert.IsTrue(restored.val.SequenceEqual(old.vals.Select(iv => iv.Value)));
-      Assert.IsTrue(restored.items.Select(item => item.Value).SequenceEqual(old.items.Select(iv => (double)((dynamic)iv).Value)));
-      // Assert.AreSame(restored.items[0], restored.items[1]);
-      Assert.AreSame(restored, restored.mySelf);
-
-      //string msg = Profile(test);
-      //Console.WriteLine(msg);
-    }
-
-    [TestMethod]
-    [TestCategory("Persistence4")]
-    [TestProperty("Time", "short")]
-    public void TestConversion2() {
-      var test = new Func<V2>(() => {
-        var p = new V2();
-        p.a = 1;
-        p.mySelf = p;
-        p.val = new int[] { 2, 3, 4 };
-        p.TupItem1 = 17;
-        p.TupItem2 = 4;
-        p.items = new DoubleValue[] { new DoubleValue(1.0), new DoubleValue(2.0) };
-        return p;
-      });
-
-      ProtoBufSerializer serializer = new ProtoBufSerializer();
-      var old = test();
-      serializer.Serialize(old, tempFile);
-      Mapper.StaticCache.DeregisterType(StorableTypeAttribute.GetStorableTypeAttribute(typeof(V1)).Guid);
-      Mapper.StaticCache.DeregisterType(StorableTypeAttribute.GetStorableTypeAttribute(typeof(V2)).Guid);
-      Mapper.StaticCache.DeregisterType(StorableTypeAttribute.GetStorableTypeAttribute(typeof(V3)).Guid);
-
-      Mapper.StaticCache.RegisterType(StorableTypeAttribute.GetStorableTypeAttribute(typeof(V2)).Guid, typeof(V3));
-
-      object o = serializer.Deserialize(tempFile);
-      var restored = (V3)o;
-      Assert.AreEqual(restored.a, old.a);
-      Assert.IsTrue(restored.val.SequenceEqual(old.val));
+      Assert.IsTrue(restored.val.SequenceEqual(old.vals.Select(iv=>iv.Value)));
       Assert.IsTrue(restored.items.Select(item => item.Value).SequenceEqual(old.items.Select(iv => (double)((dynamic)iv).Value)));
       // Assert.AreSame(restored.items[0], restored.items[1]);
