Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/ArraySerializer.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/ArraySerializer.cs	(revision 2993)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/ArraySerializer.cs	(revision 2994)
@@ -8,5 +8,5 @@
 namespace HeuristicLab.Persistence.Default.CompositeSerializers {
 
-  [EmptyStorableClass]
+  [StorableClass(StorableClassType.Empty)]
   public class ArraySerializer : ICompositeSerializer {
 
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/CompactNumberArray2StringSerializer.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/CompactNumberArray2StringSerializer.cs	(revision 2993)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/CompactNumberArray2StringSerializer.cs	(revision 2994)
@@ -10,5 +10,5 @@
 namespace HeuristicLab.Persistence.Default.CompositeSerializers {
 
-  [EmptyStorableClass]
+  [StorableClass(StorableClassType.Empty)]
   public class CompactNumberArray2StringSerializer : ICompositeSerializer {
 
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/DictionarySerializer.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/DictionarySerializer.cs	(revision 2993)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/DictionarySerializer.cs	(revision 2994)
@@ -9,5 +9,5 @@
 namespace HeuristicLab.Persistence.Default.CompositeSerializers {
 
-  [EmptyStorableClass]
+  [StorableClass(StorableClassType.Empty)]
   public class DictionarySerializer : ICompositeSerializer {
 
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/EnumSerializer.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/EnumSerializer.cs	(revision 2993)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/EnumSerializer.cs	(revision 2994)
@@ -7,5 +7,5 @@
 namespace HeuristicLab.Persistence.Default.CompositeSerializers {
 
-  [EmptyStorableClass]
+  [StorableClass(StorableClassType.Empty)]
   public class EnumSerializer : ICompositeSerializer {
 
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/EnumerableSerializer.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/EnumerableSerializer.cs	(revision 2993)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/EnumerableSerializer.cs	(revision 2994)
@@ -10,5 +10,5 @@
 namespace HeuristicLab.Persistence.Default.CompositeSerializers {
 
-  [EmptyStorableClass]
+  [StorableClass(StorableClassType.Empty)]
   public class EnumerableSerializer : ICompositeSerializer {
 
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/KeyValuePairSerializer.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/KeyValuePairSerializer.cs	(revision 2993)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/KeyValuePairSerializer.cs	(revision 2994)
@@ -9,5 +9,5 @@
 namespace HeuristicLab.Persistence.Default.CompositeSerializers {
 
-  [EmptyStorableClass]
+  [StorableClass(StorableClassType.Empty)]
   public class KeyValuePairSerializer : ICompositeSerializer {
 
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Number2StringSerializer.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Number2StringSerializer.cs	(revision 2993)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Number2StringSerializer.cs	(revision 2994)
@@ -12,5 +12,5 @@
 namespace HeuristicLab.Persistence.Default.CompositeSerializers {
 
-  [EmptyStorableClass]
+  [StorableClass(StorableClassType.Empty)]
   public class Number2StringSerializer : ICompositeSerializer {
 
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/NumberEnumerable2StringSerializer.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/NumberEnumerable2StringSerializer.cs	(revision 2993)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/NumberEnumerable2StringSerializer.cs	(revision 2994)
@@ -11,5 +11,5 @@
 namespace HeuristicLab.Persistence.Default.CompositeSerializers {
 
-  [EmptyStorableClass]
+  [StorableClass(StorableClassType.Empty)]
   public class NumberEnumerable2StringSerializer : ICompositeSerializer {
 
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/StackSerializer.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/StackSerializer.cs	(revision 2993)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/StackSerializer.cs	(revision 2994)
@@ -10,5 +10,5 @@
 namespace HeuristicLab.Persistence.Default.CompositeSerializers {
 
-  [EmptyStorableClass]
+  [StorableClass(StorableClassType.Empty)]
   public class StackSerializer : ICompositeSerializer {
 
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/EmptyStorableClassAttribute.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/EmptyStorableClassAttribute.cs	(revision 2993)
+++ 	(revision )
@@ -1,53 +1,0 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Reflection;
-
-namespace HeuristicLab.Persistence.Default.CompositeSerializers.Storable {
-
-  [AttributeUsage(
-    AttributeTargets.Class,
-    AllowMultiple = false,
-    Inherited = false)]
-  public class EmptyStorableClassAttribute : Attribute {
-
-    private static readonly Dictionary<Type, bool> emptyTypeInfo = new Dictionary<Type, bool>();
-
-    private const BindingFlags BINDING_FLAGS =
-      BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly;
-
-    /// <summary>
-    /// Check if supplied type is empty (i.e. no properties or fields) or is marked as empty storable.
-    /// This method is not recusrice and does not check if base types are also empty.
-    /// </summary>    
-    public static bool IsEmptyStorable(Type type) {
-      if (emptyTypeInfo.ContainsKey(type))
-        return emptyTypeInfo[type];
-      if (type == typeof(object)) {
-        return true;
-      }
-      foreach (var attribute in type.GetCustomAttributes(false)) {        
-        if (attribute as EmptyStorableClassAttribute != null) {
-          emptyTypeInfo.Add(type, true);
-          return true;
-        }
-      }      
-      foreach (MemberInfo memberInfo in type.GetMembers(BINDING_FLAGS)) {
-        if ( 
-          memberInfo.MemberType == MemberTypes.Field && IsModifiableField((FieldInfo)memberInfo) ||          
-          memberInfo.MemberType == MemberTypes.Property && IsModifiableProperty((PropertyInfo)memberInfo) ) {
-          emptyTypeInfo.Add(type, false);
-          return false;
-        }          
-      }      
-      emptyTypeInfo.Add(type, true);
-      return true;            
-    }
-
-    public static bool IsModifiableField(FieldInfo fi) {      
-      return !fi.IsLiteral && !fi.IsInitOnly;
-    }
-    public static bool IsModifiableProperty(PropertyInfo pi) {
-      return pi.CanWrite;
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableAttribute.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableAttribute.cs	(revision 2993)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableAttribute.cs	(revision 2994)
@@ -7,11 +7,31 @@
 namespace HeuristicLab.Persistence.Default.CompositeSerializers.Storable {
 
+
+  /// <summary>
+  /// Mark the member of a class to be considered by the <code>StorableSerializer</code>.
+  /// The class must be marked as <code>[StorableClass(StorableClassType.Empty)]</code> and the
+  /// <code>StorableClassType</code> should be set to <code>MarkedOnly</code> for
+  /// this attribute to kick in.
+  /// </summary>
   [AttributeUsage(
     AttributeTargets.Field | AttributeTargets.Property,
     AllowMultiple = false,
-    Inherited = false)]
+    Inherited = false)]    
   public class StorableAttribute : Attribute {
 
+    /// <summary>
+    /// An optional name for this member that will be used during serialization.
+    /// 
+    /// This allows to rename a field/property in code but still be able to read
+    /// the old serialized format.
+    /// </summary>
     public string Name { get; set; }
+
+
+    /// <summary>
+    /// A default value in case the field/property was not present or not serialized
+    /// in a previous version of the class and could therefore be absent during
+    /// deserialization.
+    /// </summary>
     public object DefaultValue { get; set; }
 
@@ -83,8 +103,18 @@
     private static MemberCache memberCache = new MemberCache();
 
+
+    /// <summary>
+    /// Get all fields and properties of a class that have the
+    /// <code>[Storable]</code> attribute set.
+    /// </summary>    
     public static IEnumerable<StorableMemberInfo> GetStorableMembers(Type type) {
       return GetStorableMembers(type, true);
     }
 
+    /// <summary>
+    /// Get all fields and properties of a class that have the
+    /// <code>[Storable]</code> attribute set.
+    /// </summary>        
+    /// <param name="inherited">should storable members from base classes be included</param>    
     public static IEnumerable<StorableMemberInfo> GetStorableMembers(Type type, bool inherited) {
       lock (memberCache) {
@@ -110,4 +140,10 @@
     }
 
+
+    /// <summary>
+    /// Get the associated accessors for all storable memebrs.
+    /// </summary>
+    /// <param name="obj"></param>
+    /// <returns></returns>
     public static IEnumerable<DataMemberAccessor> GetStorableAccessors(object obj) {      
       foreach (var memberInfo in GetStorableMembers(obj.GetType()))
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableClassAttribute.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableClassAttribute.cs	(revision 2994)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableClassAttribute.cs	(revision 2994)
@@ -0,0 +1,118 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Linq;
+
+namespace HeuristicLab.Persistence.Default.CompositeSerializers.Storable {
+
+
+  /// <summary>
+  /// Specifies which memebrs are selected for serialization by the StorableSerializer
+  /// </summary>
+  public enum StorableClassType {
+
+    /// <summary>
+    /// Serialize the class completely empty
+    /// (ignore further [Storable] attributes inside the class)
+    /// </summary>
+    Empty,
+
+    /// <summary>
+    /// Serialize only fields and properties that have been marked
+    /// with the [Storable] attribute
+    /// </summary>
+    MarkedOnly,
+
+    /// <summary>
+    /// Serialize all fields but ignore the 
+    /// [Storable] attribute on properties.
+    /// </summary>
+    [Obsolete("not implemented yet")]
+    AllFields,
+
+    /// <summary>
+    /// Serialize all properties but ignore the
+    /// [Storable] attirbute on fields.
+    /// </summary>
+    [Obsolete("not implemented yet")]
+    AllProperties,
+
+    /// <summary>
+    /// Serialize all fields and all properties
+    /// but ignore the [Storable] on all members.
+    /// </summary>
+    [Obsolete("not implemnted yet")]
+    AllFieldsAndAllProperties
+  };
+
+
+  /// <summary>
+  /// Mark a class to be considered by the <code>StorableSerializer</code>.
+  /// </summary>
+  [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
+  public sealed class StorableClassAttribute : Attribute {
+
+
+    /// <summary>
+    /// Specify how members are selected for serialization.
+    /// </summary>
+    public StorableClassType Type { get; set; }    
+
+    /// <summary>
+    /// Mark a class to be serialize by the <code>StorableSerizlier</code>    
+    /// </summary>    
+    public StorableClassAttribute(StorableClassType type) {
+      Type = type;
+    }
+
+    /// <summary>
+    /// Check that the type is either empty i.e. has no fields or properties
+    /// or conatins proper parameterization through the storable attribute.
+    /// </summary>
+    /// <param name="type"></param>
+    /// <param name="recusrive"></param>
+    /// <returns></returns>
+    public static bool IsStorableType(Type type, bool recusrive) {
+      if (IsEmptyType(type, recusrive))
+        return true;
+      StorableClassAttribute attribute = type
+        .GetCustomAttributes(typeof(StorableClassAttribute), false)
+        .Cast<StorableClassAttribute>().SingleOrDefault();
+      if (attribute == null)
+        return false;
+      if (!recusrive || type.BaseType == null)
+        return true;
+      else
+        return IsStorableType(type.BaseType, true);
+    }
+
+    private const BindingFlags allDeclaredMembers =
+      BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly;
+
+
+    public static bool IsEmptyType(Type type, bool recursive) {
+      foreach (MemberInfo memberInfo in type.GetMembers(allDeclaredMembers)) {
+        if (
+          memberInfo.MemberType == MemberTypes.Field && IsModifiableField((FieldInfo)memberInfo) ||
+          memberInfo.MemberType == MemberTypes.Property && IsModifiableProperty((PropertyInfo)memberInfo)) {
+          return false;
+        }
+      }
+      if (!recursive || type.BaseType == null)
+        return true;
+      else
+        return IsEmptyType(type.BaseType, true);
+    }
+
+    private static bool IsModifiableField(FieldInfo fi) {
+      return !fi.IsLiteral && !fi.IsInitOnly;
+    }
+
+    private static bool IsModifiableProperty(PropertyInfo pi) {
+      return pi.CanWrite;
+    }
+  }
+}
+
+
+  
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableConstructorAttribute.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableConstructorAttribute.cs	(revision 2993)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableConstructorAttribute.cs	(revision 2994)
@@ -8,4 +8,13 @@
 namespace HeuristicLab.Persistence.Default.CompositeSerializers.Storable {
 
+
+  /// <summary>
+  /// Indicate that this constructor should be used instead of the default constructor
+  /// when the <code>StorableSerializer</code> instantiates this class during
+  /// deserialization.
+  /// 
+  /// The constructor must take exactly one <code>bool</code> argument that will be
+  /// set to <code>true</code> during deserialization.
+  /// </summary>
   [AttributeUsage(AttributeTargets.Constructor, Inherited = false, AllowMultiple = false)]
   public sealed class StorableConstructorAttribute : Attribute {
@@ -17,4 +26,8 @@
       new Dictionary<Type, ConstructorInfo>();
 
+
+    /// <summary>
+    /// Get a designated storable constructor for a type or <code>null</code>.
+    /// </summary>    
     public static ConstructorInfo GetStorableConstructor(Type type) {
       lock (constructorCache) {
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableHookAttribute.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableHookAttribute.cs	(revision 2993)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableHookAttribute.cs	(revision 2994)
@@ -7,7 +7,16 @@
 namespace HeuristicLab.Persistence.Default.CompositeSerializers.Storable {
 
+
+  /// <summary>
+  /// Indicates the time at which the hook should be invoked.
+  /// </summary>
   public enum HookType { BeforeSerialization, AfterDeserialization };
 
-  [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
+
+  /// <summary>
+  /// Mark methods that should be called at certain times during
+  /// serialization/deserialization by the <code>StorableSerializer</code>.
+  /// </summary>
+  [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = true)]
   public sealed class StorableHookAttribute : Attribute {
 
@@ -27,4 +36,10 @@
     }
 
+
+    /// <summary>
+    /// Mark method as <code>StorableSerializer</code> hook to be run
+    /// at the <code>HookType</code> time.
+    /// </summary>
+    /// <param name="hookType"></param>
     public StorableHookAttribute(HookType hookType) {
       this.hookType = hookType;
@@ -39,4 +54,8 @@
       new Dictionary<HookDesignator, List<MethodInfo>>();
 
+
+    /// <summary>
+    /// Invoke <code>hookType</code> hook on <code>obj</code>.
+    /// </summary>    
     public static void InvokeHook(HookType hookType, object obj) {
       if (obj == null)
@@ -45,5 +64,5 @@
         mi.Invoke(obj, emptyArgs);
       }
-    }
+    }    
 
     private static IEnumerable<MethodInfo> GetHooks(HookType hookType, Type type) {
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableSerializer.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableSerializer.cs	(revision 2993)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableSerializer.cs	(revision 2994)
@@ -9,5 +9,11 @@
 namespace HeuristicLab.Persistence.Default.CompositeSerializers.Storable {
 
-  [EmptyStorableClass]
+  /// <summary>
+  /// Intended for serialization of all custom classes. Classes should have the
+  /// <code>[StorableClass(StorableClassType.Empty)]</code> attribute set and a serialization mode set.
+  /// Optionally selected fields and properties can be marked with the
+  /// <code>[Storable]</code> attribute.
+  /// </summary>
+  [StorableClass(StorableClassType.Empty)]    
   public class StorableSerializer : ICompositeSerializer {
 
@@ -20,11 +26,5 @@
         StorableConstructorAttribute.GetStorableConstructor(type) == null)
         return false;
-      while (type != null) {
-        if (StorableAttribute.GetStorableMembers(type, false).Count() == 0 &&
-            !EmptyStorableClassAttribute.IsEmptyStorable(type))
-          return false;
-        type = type.BaseType;
-      }
-      return true;
+      return StorableClassAttribute.IsStorableType(type, true);
     }
 
@@ -33,12 +33,5 @@
         StorableConstructorAttribute.GetStorableConstructor(type) == null)
         return "no default constructor and no storable constructor";
-      while (type != null) {
-        if (StorableAttribute.GetStorableMembers(type, false).Count() == 0 &&
-            !EmptyStorableClassAttribute.IsEmptyStorable(type))
-          return string.Format("{0} has no storable members and is not marked [EmtpyStorableClass]",
-            type);
-        type = type.BaseType;
-      }
-      return "no reason";
+      return "class or one of its base classes is not empty and has no [StorableClass(StorableClassType.Empty)] attribute";
     }
 
@@ -59,5 +52,5 @@
       try {
         ConstructorInfo constructor = StorableConstructorAttribute.GetStorableConstructor(type);
-        return constructor != null ? constructor.Invoke(defaultArgs) :  Activator.CreateInstance(type, true);        
+        return constructor != null ? constructor.Invoke(defaultArgs) : Activator.CreateInstance(type, true);
       } catch (TargetInvocationException x) {
         throw new PersistenceException(
@@ -72,5 +65,5 @@
       while (iter.MoveNext()) {
         memberDict.Add(iter.Current.Name, iter.Current);
-      }
+      }      
       foreach (var accessor in StorableAttribute.GetStorableAccessors(instance)) {
         if (memberDict.ContainsKey(accessor.Name)) {
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/StructSerializer.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/StructSerializer.cs	(revision 2993)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/StructSerializer.cs	(revision 2994)
@@ -10,5 +10,5 @@
 namespace HeuristicLab.Persistence.Default.CompositeSerializers {
 
-  [EmptyStorableClass]
+  [StorableClass(StorableClassType.Empty)]
   public class StructSerializer : ICompositeSerializer {    
 
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/TypeSerializer.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/TypeSerializer.cs	(revision 2993)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/TypeSerializer.cs	(revision 2994)
@@ -8,5 +8,5 @@
 namespace HeuristicLab.Persistence.Default.CompositeSerializers {
 
-  [EmptyStorableClass]
+  [StorableClass(StorableClassType.Empty)]
   public class TypeSerializer : ICompositeSerializer {
 
