Index: /trunk/sources/HeuristicLab.Persistence/3.3/Core/Serializer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Persistence/3.3/Core/Serializer.cs	(revision 2992)
+++ /trunk/sources/HeuristicLab.Persistence/3.3/Core/Serializer.cs	(revision 2993)
@@ -137,13 +137,5 @@
         if (compositeSerializer != null)
           return CompositeEnumerator(accessor.Name, compositeSerializer.Decompose(value), id, typeId, compositeSerializer.CreateMetaInfo(value));
-        throw new PersistenceException(
-            String.Format(
-            "No suitable method for serializing values of type \"{0}\" found\r\n" +
-            "primitive serializers:\r\n{1}\r\n" +
-            "composite serializers:\r\n{2}",
-            value.GetType().VersionInvariantName(),
-            string.Join("\r\n", configuration.PrimitiveSerializers.Select(f => f.GetType().VersionInvariantName()).ToArray()),
-            string.Join("\r\n", configuration.CompositeSerializers.Select(d => d.GetType().VersionInvariantName()).ToArray())
-            ));
+        throw CreatePersistenceException(type);
       } catch (Exception x) {
         if (isTestRun) {
@@ -154,4 +146,25 @@
         }
       }
+    }
+
+    private PersistenceException CreatePersistenceException(Type type) {
+      StringBuilder sb = new StringBuilder();
+      sb.Append("Could not determine how to serialize a value of type \"")
+        .Append(type.VersionInvariantName())
+        .AppendLine("\"");
+      sb.AppendLine("No registered primitive serializer for this type:");
+      foreach (var ps in configuration.PrimitiveSerializers)
+        sb.Append(ps.SourceType.VersionInvariantName())
+          .Append(" ---- (")
+          .Append(ps.GetType().VersionInvariantName())
+          .AppendLine(")");          
+      sb.AppendLine("Rejected by all composite serializers:");
+      foreach (var cs in configuration.CompositeSerializers)
+        sb.Append("\"")
+          .Append(cs.JustifyRejection(type))
+          .Append("\" ---- (")
+          .Append(cs.GetType().VersionInvariantName())
+          .AppendLine(")");
+      return new PersistenceException(sb.ToString());              
     }
 
Index: /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/ArraySerializer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/ArraySerializer.cs	(revision 2992)
+++ /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/ArraySerializer.cs	(revision 2993)
@@ -4,4 +4,5 @@
 using System.Collections.Generic;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using System.Text;
 
 namespace HeuristicLab.Persistence.Default.CompositeSerializers {
@@ -16,4 +17,8 @@
     public bool CanSerialize(Type type) {
       return type.IsArray || type == typeof(Array);
+    }
+
+    public string JustifyRejection(Type type) {
+      return "not an array and not of type System.Array";
     }
 
Index: /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/CompactNumberArray2StringSerializer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/CompactNumberArray2StringSerializer.cs	(revision 2992)
+++ /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/CompactNumberArray2StringSerializer.cs	(revision 2993)
@@ -24,4 +24,11 @@
         (type.IsArray || type == typeof(Array)) &&
         numberConverter.CanSerialize(type.GetElementType());
+    }
+
+    public string JustifyRejection(Type type) {
+      if (!type.IsArray && type != typeof(Array))
+        return "not an array";
+      return string.Format("number converter cannot serialize elements: " +
+        numberConverter.JustifyRejection(type.GetElementType()));
     }
 
Index: /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/DictionarySerializer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/DictionarySerializer.cs	(revision 2992)
+++ /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/DictionarySerializer.cs	(revision 2993)
@@ -20,4 +20,10 @@
       return ReflectionTools.HasDefaultConstructor(type) &&
         type.GetInterface(typeof(IDictionary).FullName) != null;
+    }
+
+    public string JustifyRejection(Type type) {
+      if (!ReflectionTools.HasDefaultConstructor(type))
+        return "no default constructor";
+      return "interface IDictionary not implemented";
     }
 
Index: /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/EnumSerializer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/EnumSerializer.cs	(revision 2992)
+++ /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/EnumSerializer.cs	(revision 2993)
@@ -16,4 +16,8 @@
     public bool CanSerialize(Type type) {
       return type.IsEnum || type == typeof(Enum);
+    }
+
+    public string JustifyRejection(Type type) {
+      return "not an enum and not System.Enum";
     }
 
Index: /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/EnumerableSerializer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/EnumerableSerializer.cs	(revision 2992)
+++ /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/EnumerableSerializer.cs	(revision 2993)
@@ -26,4 +26,14 @@
     }
 
+    public string JustifyRejection(Type type) {
+      if (!ReflectionTools.HasDefaultConstructor(type))
+        return "no default constructor";
+      if (type.GetInterface(typeof(IEnumerable).FullName) == null)
+        return "interface IEnumerable not implemented";
+      if (type.GetMethod("Add") == null)
+        return "no 'Add()' method";      
+      return "no 'Add()' method with one argument";
+    }
+
     public IEnumerable<Tag> CreateMetaInfo(object o) {
       return new Tag[] { };
Index: /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/KeyValuePairSerializer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/KeyValuePairSerializer.cs	(revision 2992)
+++ /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/KeyValuePairSerializer.cs	(revision 2993)
@@ -16,9 +16,16 @@
     }
 
+    private static readonly Type genericKeyValuePairType =
+      typeof(KeyValuePair<int, int>).GetGenericTypeDefinition();
 
     public bool CanSerialize(Type type) {
       return type.IsGenericType &&
-             type.GetGenericTypeDefinition() ==
-             typeof(KeyValuePair<int, int>).GetGenericTypeDefinition();
+             type.GetGenericTypeDefinition() == genericKeyValuePairType;             
+    }
+
+    public string JustifyRejection(Type type) {
+      if (!type.IsGenericType)
+        return "not even generic";      
+      return "not generic KeyValuePair<,>";
     }
 
Index: /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Number2StringSerializer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Number2StringSerializer.cs	(revision 2992)
+++ /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Number2StringSerializer.cs	(revision 2993)
@@ -1,3 +1,4 @@
 ﻿using System;
+using System.Linq;
 using HeuristicLab.Persistence.Interfaces;
 using HeuristicLab.Persistence.Core;
@@ -43,4 +44,9 @@
     public bool CanSerialize(Type type) {
       return numberParsers.ContainsKey(type);
+    }
+
+    public string JustifyRejection(Type type) {
+      return string.Format("not a number type (one of {0})",
+        string.Join(", ", numberTypes.Select(n => n.Name).ToArray()));
     }
 
Index: /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/NumberEnumerable2StringSerializer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/NumberEnumerable2StringSerializer.cs	(revision 2992)
+++ /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/NumberEnumerable2StringSerializer.cs	(revision 2993)
@@ -60,4 +60,12 @@
     }
 
+    public string JustifyRejection(Type type) {
+      if (!ReflectionTools.HasDefaultConstructor(type))
+        return "no default constructor";
+      if (!ImplementsGenericEnumerable(type))
+        return "IEnumerable<> not implemented";
+      return "no Add method with one parameter";
+    }
+
     public IEnumerable<Tag> CreateMetaInfo(object o) {
       return new Tag[] { };
Index: /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/StackSerializer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/StackSerializer.cs	(revision 2992)
+++ /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/StackSerializer.cs	(revision 2993)
@@ -22,4 +22,8 @@
         type.IsGenericType &&
         type.GetGenericTypeDefinition() == typeof(Stack<>);
+    }
+
+    public string JustifyRejection(Type type) {
+        return "not Stack or generic Stack<>";
     }
 
Index: /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableSerializer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableSerializer.cs	(revision 2992)
+++ /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableSerializer.cs	(revision 2993)
@@ -17,5 +17,6 @@
 
     public bool CanSerialize(Type type) {
-      if (!ReflectionTools.HasDefaultConstructor(type))
+      if (!ReflectionTools.HasDefaultConstructor(type) &&
+        StorableConstructorAttribute.GetStorableConstructor(type) == null)
         return false;
       while (type != null) {
@@ -26,4 +27,18 @@
       }
       return true;
+    }
+
+    public string JustifyRejection(Type type) {
+      if (!ReflectionTools.HasDefaultConstructor(type) &&
+        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";
     }
 
Index: /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/StructSerializer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/StructSerializer.cs	(revision 2992)
+++ /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/StructSerializer.cs	(revision 2993)
@@ -19,4 +19,14 @@
     public bool CanSerialize(Type type) {
       return type.IsValueType && !type.IsPrimitive && !type.IsEnum && type.IsSealed;      
+    }
+
+    public string JustifyRejection(Type type) {
+      if (!type.IsValueType)
+        return "not a value type";
+      if (type.IsPrimitive)
+        return "type is primitive (int, float, ...)";
+      if (type.IsEnum)
+        return "type is enum";
+      return "type is not sealed";
     }
 
Index: /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/TypeSerializer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/TypeSerializer.cs	(revision 2992)
+++ /trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/TypeSerializer.cs	(revision 2993)
@@ -18,4 +18,8 @@
       return type == typeof(Type) ||
              type.VersionInvariantName() == "System.RuntimeType, mscorlib";
+    }
+
+    public string JustifyRejection(Type type) {
+      return "not System.Type nor System.RuntimeType";
     }
 
Index: /trunk/sources/HeuristicLab.Persistence/3.3/Interfaces/ICompositeSerializer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Persistence/3.3/Interfaces/ICompositeSerializer.cs	(revision 2992)
+++ /trunk/sources/HeuristicLab.Persistence/3.3/Interfaces/ICompositeSerializer.cs	(revision 2993)
@@ -20,4 +20,10 @@
     /// </summary>    
     bool CanSerialize(Type type);
+
+    /// <summary>
+    /// Give a reason if possibly why the given type cannot be serialized by this
+    /// ICompositeSerializer.
+    /// </summary>
+    string JustifyRejection(Type type);
 
     /// <summary>
Index: /trunk/sources/HeuristicLab.Persistence/3.3/Tests/UseCases.cs
===================================================================
--- /trunk/sources/HeuristicLab.Persistence/3.3/Tests/UseCases.cs	(revision 2992)
+++ /trunk/sources/HeuristicLab.Persistence/3.3/Tests/UseCases.cs	(revision 2993)
@@ -736,4 +736,15 @@
     }
 
+    [TestMethod]
+    public void TestRejectionJustifications() { 
+      NonSerializable ns = new NonSerializable();
+      try {
+        XmlGenerator.Serialize(ns, tempFile);
+        Assert.Fail("PersistenceException expected");
+      } catch (PersistenceException x) {
+        Assert.IsTrue(x.Message.Contains(new StorableSerializer().JustifyRejection(typeof(NonSerializable))));        
+      }
+    }
+
     [ClassInitialize]
     public static void Initialize(TestContext testContext) {
