Index: /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Core/CachedTypeSerializer.cs
===================================================================
--- /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Core/CachedTypeSerializer.cs	(revision 6737)
+++ /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Core/CachedTypeSerializer.cs	(revision 6737)
@@ -0,0 +1,67 @@
+﻿using System;
+using System.Linq;
+using System.Collections.Generic;
+using HeuristicLab.Persistence.Auxiliary;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Persistence.Interfaces;
+
+namespace HeuristicLab.Persistence.Core {
+
+  [StorableClass]
+  internal sealed class CachedTypeSerializer : ICompositeSerializer {
+
+    [StorableConstructor]
+    private CachedTypeSerializer(bool deserializing) { }
+
+    private TypeCache typeCache;
+    private Dictionary<int, Type> deserializationTypeCache;
+
+    internal CachedTypeSerializer(TypeCache typeCache) {
+      this.typeCache = typeCache;
+    }
+
+    internal CachedTypeSerializer(Dictionary<int, Type> deserializationTypeCache) {
+      this.deserializationTypeCache = deserializationTypeCache;
+    }
+
+    public int Priority {
+      get { return 1000; }
+    }
+
+    public bool CanSerialize(Type type) {
+      return type == typeof(Type) || type.VersionInvariantName() == "System.RuntimeType, mscorlib";
+    }
+
+    public string JustifyRejection(Type type) {
+      return "not System.Type nor System.RuntimeType";
+    }
+
+    public IEnumerable<Tag> CreateMetaInfo(object o) {
+      yield return new Tag("TypeId", typeCache.GetOrCreateId((Type)o));
+    }
+
+    public IEnumerable<Tag> Decompose(object obj) {
+      return new Tag[] { };
+    }
+
+    public object CreateInstance(Type type, IEnumerable<Tag> metaInfo) {
+      int typeId = -1;
+      try {
+        typeId = (int)metaInfo.First().Value;
+        return deserializationTypeCache[typeId];
+      } catch (InvalidOperationException e) {
+        throw new PersistenceException("Insufficient meta information to instantiate Type object", e);
+      } catch (InvalidCastException e) {
+        throw new PersistenceException("Invalid meta information during reconstruction of Type object", e);
+      } catch (KeyNotFoundException e) {
+        throw new PersistenceException(String.Format(
+          "TypeCache has not been loaded with type id {0}, make sure all required assemblies are available.",
+          typeId), e);
+      }
+    }
+
+    public void Populate(object instance, IEnumerable<Tag> objects, Type type) {
+      // Type ojects are populated during instance creation.
+    }
+  }
+}
Index: /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Core/DeSerializer.cs
===================================================================
--- /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Core/DeSerializer.cs	(revision 6736)
+++ /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Core/DeSerializer.cs	(revision 6737)
@@ -32,5 +32,5 @@
   /// instantiates objects and fills in values.
   /// </summary>
-  public class Deserializer {
+  public sealed class Deserializer {
 
     /// <summary>
@@ -40,4 +40,5 @@
     private class Midwife {
 
+      public string Name { get; private set; }
       public int? Id { get; private set; }
       public bool MetaMode { get; set; }
@@ -53,8 +54,9 @@
       }
 
-      public Midwife(Type type, ICompositeSerializer compositeSerializer, int? id) {
+      public Midwife(Type type, ICompositeSerializer compositeSerializer, int? id, string name) {
         this.type = type;
         this.compositeSerializer = compositeSerializer;
         this.Id = id;
+        this.Name = name;
         MetaMode = false;
         metaInfo = new List<Tag>();
@@ -82,8 +84,6 @@
 
     private readonly Dictionary<int, object> id2obj;
-    private readonly Dictionary<Type, object> serializerMapping;
     private readonly Stack<Midwife> parentStack;
-    private readonly Dictionary<int, Type> typeIds;
-    private Dictionary<Type, object> serializerInstances;
+    private ReverseTypeCache typeCache;
 
     /// <summary>
@@ -93,42 +93,8 @@
     /// </summary>
     /// <param name="typeCache">The type cache.</param>
-    public Deserializer(
-      IEnumerable<TypeMapping> typeCache) {
+    public Deserializer(ReverseTypeCache typeCache) {
+      this.typeCache = typeCache;
       id2obj = new Dictionary<int, object>();
       parentStack = new Stack<Midwife>();
-      typeIds = new Dictionary<int, Type>();
-      serializerMapping = new Dictionary<Type, object>();
-      serializerInstances = new Dictionary<Type, object>();
-      foreach (var typeMapping in typeCache) {
-        AddTypeInfo(typeMapping);
-      }
-    }
-
-    /// <summary>
-    /// Adds additionaly type information.
-    /// </summary>
-    /// <param name="typeMapping">The new type mapping.</param>
-    public void AddTypeInfo(TypeMapping typeMapping) {
-      if (typeIds.ContainsKey(typeMapping.Id))
-        return;
-      try {
-        Type type = TypeLoader.Load(typeMapping.TypeName);
-        typeIds.Add(typeMapping.Id, type);
-        Type serializerType = TypeLoader.Load(typeMapping.Serializer);
-        object serializer;
-        if (serializerInstances.ContainsKey(serializerType)) {
-          serializer = serializerInstances[serializerType];
-        } else {
-          serializer = Activator.CreateInstance(serializerType, true);
-          serializerInstances.Add(serializerType, serializer);
-        }
-        serializerMapping.Add(type, serializer);
-      } catch (PersistenceException) {
-        throw;
-      } catch (Exception e) {
-        throw new PersistenceException(string.Format(
-          "Could not add type info for {0} ({1})",
-          typeMapping.TypeName, typeMapping.Serializer), e);
-      }
     }
 
@@ -157,4 +123,6 @@
         } else if (t == typeof(TypeToken)) {
           Type((TypeToken)token);
+        } else if (t == typeof(SerializerToken)) {
+          Serializer((SerializerToken)token);
         } else {
           throw new PersistenceException("invalid token type");
@@ -173,12 +141,16 @@
 
     private void Type(TypeToken token) {
-      AddTypeInfo(new TypeMapping(token.Id, token.TypeName, token.Serializer));
+      typeCache.AddType(token.Id, TypeLoader.Load(token.TypeName));
+    }
+
+    private void Serializer(SerializerToken token) {
+      typeCache.AddSerializer(token.Id, TypeLoader.Load(token.Serializer));
     }
 
     private void CompositeStartHandler(BeginToken token) {
       InstantiateParent();
-      Type type = typeIds[(int)token.TypeId];
+      Type type = typeCache.GetType(token.TypeId);
       try {
-        parentStack.Push(new Midwife(type, (ICompositeSerializer)serializerMapping[type], token.Id));
+        parentStack.Push(new Midwife(type, typeCache.GetCompositeSerializer(token.TypeId), token.Id, token.Name));
       } catch (Exception e) {
         if (e is InvalidCastException || e is KeyNotFoundException) {
@@ -195,16 +167,14 @@
 
     private void CompositeEndHandler(EndToken token) {
-      Type type = typeIds[(int)token.TypeId];
       Midwife midwife = parentStack.Pop();
       if (midwife.Obj == null)
         CreateInstance(midwife);
       midwife.Populate();
-      SetValue(token.Name, midwife.Obj);
+      SetValue(midwife.Name, midwife.Obj);
     }
 
     private void PrimitiveHandler(PrimitiveToken token) {
-      Type type = typeIds[(int)token.TypeId];
       try {
-        object value = ((IPrimitiveSerializer)serializerMapping[type]).Parse(token.SerialData);
+        object value = typeCache.GetPrimitiveSerializer(token.TypeId).Parse(token.SerialData);
         if (token.Id != null)
           id2obj[(int)token.Id] = value;
@@ -214,9 +184,9 @@
           throw new PersistenceException(String.Format(
             "Invalid primitive serializer configuration for type \"{0}\".",
-            type.AssemblyQualifiedName), e);
+            typeCache.GetType(token.TypeId).AssemblyQualifiedName), e);
         } else {
           throw new PersistenceException(String.Format(
             "Unexpected exception while trying to parse object of type \"{0}\".",
-            type.AssemblyQualifiedName), e);
+            typeCache.GetType(token.TypeId).AssemblyQualifiedName), e);
         }
       }
Index: /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Core/GeneratorBase.cs
===================================================================
--- /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Core/GeneratorBase.cs	(revision 6736)
+++ /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Core/GeneratorBase.cs	(revision 6737)
@@ -57,4 +57,6 @@
       if (type == typeof(TypeToken))
         return Format((TypeToken)token);
+      if (type == typeof(SerializerToken))
+        return Format((SerializerToken)token);
       throw new ApplicationException("Invalid token of type " + type.FullName);
     }
@@ -116,4 +118,5 @@
     protected abstract T Format(TypeToken typeToken);
 
+    protected abstract T Format(SerializerToken serializerToken);
   }
 }
Index: /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Core/ReverseTypeCache.cs
===================================================================
--- /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Core/ReverseTypeCache.cs	(revision 6737)
+++ /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Core/ReverseTypeCache.cs	(revision 6737)
@@ -0,0 +1,50 @@
+﻿using System;
+using System.Collections.Generic;
+using HeuristicLab.Persistence.Interfaces;
+
+namespace HeuristicLab.Persistence.Core {
+
+  public sealed class ReverseTypeCache {
+
+    private readonly Dictionary<int, object> typeId2SerializerMapping;
+    private readonly Dictionary<Type, object> serializerInstances;
+    private readonly Dictionary<int, Type> typeIds;
+
+    public ReverseTypeCache() {
+      typeId2SerializerMapping = new Dictionary<int, object>();
+      serializerInstances = new Dictionary<Type, object>();
+      typeIds = new Dictionary<int, Type>();
+    }
+
+    public void AddSerializer(int typeId, Type serializerType) {
+      if (typeId2SerializerMapping.ContainsKey(typeId))
+        return;
+      object serializerInstance;
+      if (!serializerInstances.TryGetValue(serializerType, out serializerInstance)) {
+        if (serializerType == typeof(CachedTypeSerializer)) {
+          serializerInstance = new CachedTypeSerializer(typeIds);
+        } else {
+          serializerInstance = serializerType.GetConstructor(System.Type.EmptyTypes).Invoke(new object[0]);
+        }
+        serializerInstances.Add(serializerType, serializerInstance);
+      }
+      typeId2SerializerMapping.Add(typeId, serializerInstance);
+    }
+
+    public void AddType(int typeId, Type type) {
+      typeIds.Add(typeId, type);
+    }
+
+    public Type GetType(int id) {
+      return typeIds[id];
+    }
+
+    public ICompositeSerializer GetCompositeSerializer(int typeId) {
+      return (ICompositeSerializer)typeId2SerializerMapping[typeId];
+    }
+
+    public IPrimitiveSerializer GetPrimitiveSerializer(int typeId) {
+      return (IPrimitiveSerializer)typeId2SerializerMapping[typeId];
+    }
+  }
+}
Index: /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Core/Serializer.cs
===================================================================
--- /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Core/Serializer.cs	(revision 6736)
+++ /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Core/Serializer.cs	(revision 6737)
@@ -23,5 +23,5 @@
 using System.Collections;
 using System.Collections.Generic;
-using System.Reflection;
+using System.Linq;
 using System.Text;
 using HeuristicLab.Persistence.Auxiliary;
@@ -44,6 +44,7 @@
   /// and traverses the object graph while the enumerator is iterated
   /// </summary>  
-  public class Serializer : IEnumerable<ISerializationToken> {
-
+  public sealed class Serializer : IEnumerable<ISerializationToken> {
+
+    #region Nested Types
     private class ReferenceEqualityComparer : IEqualityComparer<object> {
 
@@ -59,12 +60,17 @@
 
     }
-
+    #endregion
+
+    #region Fields
     private readonly object obj;
     private readonly string rootName;
     private readonly Dictionary<object, int> obj2id;
-    private readonly Dictionary<Type, int> typeCache;
     private readonly Configuration configuration;
     private readonly bool isTestRun;
     private readonly List<Exception> exceptions;
+    private readonly Stack<string> objectGraphTrace;
+    private readonly CachedTypeSerializer typeSerializer;
+    private readonly TypeCache typeCache;
+    #endregion
 
     /// <summary>
@@ -80,13 +86,6 @@
     public bool InterleaveTypeInformation { get; set; }
 
-    /// <summary>
-    /// Contains a mapping of type id to type and serializer.
-    /// </summary>
-    /// <value>The type cache.</value>
-    public List<TypeMapping> TypeCache {
-      get {
-        BuildTypeCache();
-        return externalTypeCache;
-      }
+    public TypeCache TypeCache {
+      get { return typeCache; }
     }
 
@@ -95,42 +94,16 @@
     /// necessary to deserialize the object graph again.    
     /// </summary>
-    public List<string> RequiredFiles {
-      get {
-        BuildTypeCache();
-        return requiredFiles;
-      }
-    }
-
-    private List<TypeMapping> externalTypeCache;
-    private List<string> requiredFiles;
-    private void BuildTypeCache() {
-      externalTypeCache = new List<TypeMapping>();
-      Dictionary<Assembly, bool> assemblies = new Dictionary<Assembly, bool>();
-      foreach (var pair in typeCache) {
-        string serializer = null;
-        IPrimitiveSerializer f = configuration.GetPrimitiveSerializer(pair.Key);
-        if (f != null) {
-          serializer = f.GetType().AssemblyQualifiedName;
-          assemblies[f.GetType().Assembly] = true;
-        } else {
-          ICompositeSerializer d = configuration.GetCompositeSerializer(pair.Key);
-          serializer = d.GetType().AssemblyQualifiedName;
-          assemblies[d.GetType().Assembly] = true;
-        }
-        externalTypeCache.Add(new TypeMapping(pair.Value, pair.Key.AssemblyQualifiedName, serializer));
-        assemblies[pair.Key.Assembly] = true;
-      }
-      Dictionary<string, bool> files = new Dictionary<string, bool>();
-      foreach (Assembly a in assemblies.Keys) {
-        files[a.CodeBase] = true;
-      }
-      requiredFiles = new List<string>(files.Keys);
-    }
-
-    public IEnumerable<Type> SerializedTypes {
-      get {
-        return typeCache.Keys;
-      }
-    }
+    public IEnumerable<string> GetRequiredFiles() {
+      HashSet<string> files = new HashSet<string>();
+      foreach (var t in typeCache.Types) {
+        files.Add(t.Assembly.CodeBase);
+        Type serializer = typeCache.GetSerializer(typeCache.GetOrCreateId(t));
+        if (serializer != null)
+          files.Add(serializer.Assembly.CodeBase);
+      }
+      return files;
+    }
+
+    public IEnumerable<Type> SerializedTypes { get { return typeCache.Types; } }
 
     /// <summary>
@@ -139,6 +112,6 @@
     /// <param name="obj">The object to serialize.</param>
     /// <param name="configuration">The configuration.</param>
-    public Serializer(object obj, Configuration configuration) :
-      this(obj, configuration, "ROOT") { }
+    public Serializer(object obj, Configuration configuration)
+      : this(obj, configuration, "ROOT") { }
 
     /// <summary>
@@ -163,9 +136,14 @@
       this.obj = obj;
       this.rootName = rootName;
-      this.configuration = configuration;
       obj2id = new Dictionary<object, int>(new ReferenceEqualityComparer()) { { new object(), 0 } };
-      typeCache = new Dictionary<Type, int>();
+      typeCache = new TypeCache();
       this.isTestRun = isTestRun;
       this.exceptions = new List<Exception>();
+      this.objectGraphTrace = new Stack<string>();
+      this.typeSerializer = new CachedTypeSerializer(typeCache);
+      this.configuration = new Configuration(
+        configuration.Format,
+        configuration.PrimitiveSerializers,
+        new[] { typeSerializer }.Concat(configuration.CompositeSerializers));
     }
 
@@ -206,8 +184,6 @@
     }
 
-    private Stack<string> objectGraphTrace = new Stack<string>();
 
     private IEnumerator<ISerializationToken> Serialize(string name, object obj) {
-
       object value = obj;
       if (value == null)
@@ -216,10 +192,5 @@
       if (obj2id.ContainsKey(value))
         return ReferenceEnumerator(name, obj2id[value]);
-      bool emitTypeInfo = false;
-      if (!typeCache.ContainsKey(type)) {
-        typeCache.Add(type, typeCache.Count);
-        emitTypeInfo = InterleaveTypeInformation;
-      }
-      int typeId = typeCache[type];
+      int typeId = typeCache.GetOrCreateId(type);
       int? id = null;
       if (!type.IsValueType) {
@@ -230,12 +201,14 @@
         objectGraphTrace.Push(name);
         IPrimitiveSerializer primitiveSerializer = configuration.GetPrimitiveSerializer(type);
-        if (primitiveSerializer != null)
+        if (primitiveSerializer != null) {
+          typeCache.SetSerializer(typeId, primitiveSerializer.GetType());
           return PrimitiveEnumerator(
             name,
             typeId,
             primitiveSerializer.Format(value),
-            id,
-            emitTypeInfo);
+            id);
+        }
         ICompositeSerializer compositeSerializer = configuration.GetCompositeSerializer(type);
+        typeCache.SetSerializer(typeId, compositeSerializer.GetType());
         if (compositeSerializer != null)
           return CompositeEnumerator(
@@ -244,9 +217,7 @@
             id,
             typeId,
-            compositeSerializer.CreateMetaInfo(value),
-            emitTypeInfo);
-        throw CreatePersistenceException(type, "Could not determine how to serialize a value.");
-      }
-      catch (Exception x) {
+            compositeSerializer.CreateMetaInfo(value));
+        throw CreatePersistenceException(type, "Could not determine how to serialize a value.", null);
+      } catch (Exception x) {
         if (isTestRun) {
           exceptions.Add(x);
@@ -255,13 +226,12 @@
           throw;
         } else {
-          throw CreatePersistenceException(type, "Uncaught exception during serialization: " + x.Message);
+          throw CreatePersistenceException(type, "Uncaught exception during serialization: ", x);
         }
-      }
-      finally {
+      } finally {
         objectGraphTrace.Pop();
       }
     }
 
-    private PersistenceException CreatePersistenceException(Type type, string message) {
+    private PersistenceException CreatePersistenceException(Type type, string message, Exception x) {
       StringBuilder sb = new StringBuilder();
       sb.Append(message)
@@ -295,19 +265,20 @@
     }
 
-    private IEnumerator<ISerializationToken> PrimitiveEnumerator(string name,
-        int typeId, ISerialData serializedValue, int? id, bool emitTypeInfo) {
-      if (emitTypeInfo) {
-        var mapping = TypeCache[typeId];
-        yield return new TypeToken(mapping.Id, mapping.TypeName, mapping.Serializer);
+    private IEnumerator<ISerializationToken> PrimitiveEnumerator(string name, int typeId, ISerialData serializedValue, int? id) {
+      if (InterleaveTypeInformation) {
+        if (typeCache.HasUnpublishedType)
+          yield return typeCache.PublishUnpublishedType();
+        if (typeCache.HasUnpublishedSerializer)
+          yield return typeCache.PublishUnpublishedSerializer();
       }
       yield return new PrimitiveToken(name, typeId, id, serializedValue);
     }
 
-    private IEnumerator<ISerializationToken> CompositeEnumerator(
-        string name, IEnumerable<Tag> tags, int? id, int typeId, IEnumerable<Tag> metaInfo,
-        bool emitTypeInfo) {
-      if (emitTypeInfo) {
-        var mapping = TypeCache[typeId];
-        yield return new TypeToken(mapping.Id, mapping.TypeName, mapping.Serializer);
+    private IEnumerator<ISerializationToken> CompositeEnumerator(string name, IEnumerable<Tag> tags, int? id, int typeId, IEnumerable<Tag> metaInfo) {
+      if (InterleaveTypeInformation) {
+        if (typeCache.HasUnpublishedType)
+          yield return typeCache.PublishUnpublishedType();
+        if (typeCache.HasUnpublishedSerializer)
+          yield return typeCache.PublishUnpublishedSerializer();
       }
       yield return new BeginToken(name, typeId, id);
@@ -335,5 +306,5 @@
         }
       }
-      yield return new EndToken(name, typeId, id);
+      yield return new EndToken();
     }
   }
Index: /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Core/Tokens/SerializerToken.cs
===================================================================
--- /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Core/Tokens/SerializerToken.cs	(revision 6737)
+++ /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Core/Tokens/SerializerToken.cs	(revision 6737)
@@ -0,0 +1,54 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Persistence.Interfaces;
+
+namespace HeuristicLab.Persistence.Core.Tokens {
+
+  /// <summary>
+  /// A token containing type information and mapping.
+  /// </summary>
+  public sealed class SerializerToken : ISerializationToken {
+
+    /// <summary>
+    /// The type id.
+    /// </summary>
+    public readonly int Id;
+
+    /// <summary>
+    /// The full type name of the serialized used to
+    /// serialize the type.
+    /// </summary>
+    public readonly string Serializer;
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="TypeToken"/> class.
+    /// </summary>
+    /// <param name="id">The type id.</param>
+    /// <param name="typeName">Full name of the type.</param>
+    /// <param name="serializer">The full name of the serializer
+    /// used to serialize the type.</param>
+    public SerializerToken(int id, string serializer) {
+      Id = id;
+      Serializer = serializer;
+    }
+  }
+}
Index: /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Core/Tokens/TypeToken.cs
===================================================================
--- /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Core/Tokens/TypeToken.cs	(revision 6736)
+++ /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Core/Tokens/TypeToken.cs	(revision 6737)
@@ -40,10 +40,4 @@
 
     /// <summary>
-    /// The full type name of the serialized used to
-    /// serialize the type.
-    /// </summary>
-    public readonly string Serializer;
-
-    /// <summary>
     /// Initializes a new instance of the <see cref="TypeToken"/> class.
     /// </summary>
@@ -52,8 +46,7 @@
     /// <param name="serializer">The full name of the serializer
     /// used to serialize the type.</param>
-    public TypeToken(int id, string typeName, string serializer) {
+    public TypeToken(int id, string typeName) {
       Id = id;
       TypeName = typeName;
-      Serializer = serializer;
     }
   }
Index: /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Core/TypeCache.cs
===================================================================
--- /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Core/TypeCache.cs	(revision 6737)
+++ /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Core/TypeCache.cs	(revision 6737)
@@ -0,0 +1,69 @@
+﻿using System;
+using System.Collections.Generic;
+using HeuristicLab.Persistence.Core.Tokens;
+
+namespace HeuristicLab.Persistence.Core {
+
+  public sealed class TypeCache {
+
+    private Dictionary<Type, int> type2id;
+    private Dictionary<int, Type> id2serializer;
+    private Type unpublishedType;
+    private int? unpublishedSerializer;
+
+    public bool HasUnpublishedType { get { return unpublishedType != null; } }
+    public bool HasUnpublishedSerializer { get { return unpublishedSerializer != null; } }
+
+    public TypeToken PublishUnpublishedType() {
+      TypeToken token = new TypeToken(type2id[unpublishedType], unpublishedType.AssemblyQualifiedName);
+      unpublishedType = null;
+      return token;
+    }
+
+    public SerializerToken PublishUnpublishedSerializer() {
+      SerializerToken token = new SerializerToken((int)unpublishedSerializer, id2serializer[(int)unpublishedSerializer].AssemblyQualifiedName);
+      unpublishedSerializer = null;
+      return token;
+    }
+
+    public TypeCache() {
+      type2id = new Dictionary<Type, int>();
+      id2serializer = new Dictionary<int, Type>();
+    }
+
+    public IEnumerable<Type> Types { get { return type2id.Keys; } }
+
+    public int GetOrCreateId(Type type) {
+      int id;
+      if (!type2id.TryGetValue(type, out id)) {
+        id = type2id.Count;
+        type2id.Add(type, id);
+        unpublishedType = type;
+      }
+      return id;
+    }
+
+    public void SetSerializer(int typeId, Type serializerType) {
+      Type serializer;
+      if (!id2serializer.TryGetValue(typeId, out serializer)) {
+        id2serializer.Add(typeId, serializerType);
+        unpublishedSerializer = typeId;
+      }
+    }
+
+    public Type GetSerializer(int id) {
+      Type serializer = null;
+      id2serializer.TryGetValue(id, out serializer);
+      return serializer;
+    }
+
+    public ReverseTypeCache Reverse() {
+      var reverse = new ReverseTypeCache();
+      foreach (var t in type2id)
+        reverse.AddType(t.Value, t.Key);
+      foreach (var s in id2serializer)
+        reverse.AddSerializer(s.Key, s.Value);
+      return reverse;
+    }
+  }
+}
Index: anches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Core/TypeMapping.cs
===================================================================
--- /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Core/TypeMapping.cs	(revision 6736)
+++ 	(revision )
@@ -1,76 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System.Collections.Generic;
-
-namespace HeuristicLab.Persistence.Core {
-
-  /// <summary>
-  /// Association of id, type name and serializer
-  /// </summary>
-  public class TypeMapping {
-
-    /// <summary>
-    /// The type's id.
-    /// </summary>
-    public readonly int Id;
-
-    /// <summary>
-    /// The type's full name.
-    /// </summary>
-    public readonly string TypeName;
-
-
-    /// <summary>
-    /// The full name of the serializes used to serialize the
-    /// <see cref="TypeName"/>.
-    /// </summary>
-    public readonly string Serializer;
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="TypeMapping"/> class.
-    /// </summary>
-    /// <param name="id">The type's id.</param>
-    /// <param name="typeName">The type's full name.</param>
-    /// <param name="serializer">The full name of the serializer use to
-    /// serialize this type.</param>
-    public TypeMapping(int id, string typeName, string serializer) {
-      Id = id;
-      TypeName = typeName;
-      Serializer = serializer;
-    }
-
-    /// <summary>
-    /// Creates a dictionary that conatins all properties
-    /// and values of this instance.
-    /// </summary>
-    /// <returns>A dictionary containing all properties
-    /// and values of this instance.</returns>
-    public Dictionary<string, string> GetDict() {
-      return new Dictionary<string, string> {
-        {"id", Id.ToString()},
-        {"typeName", TypeName},
-        {"serializer", Serializer}};
-    }
-
-  }
-
-}
Index: /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Default/DebugString/DebugStringGenerator.cs
===================================================================
--- /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Default/DebugString/DebugStringGenerator.cs	(revision 6736)
+++ /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Default/DebugString/DebugStringGenerator.cs	(revision 6737)
@@ -169,4 +169,8 @@
     }
 
+    protected override string Format(SerializerToken serializerToken) {
+      return string.Empty;
+    }
+
     /// <summary>
     /// Serializes the specified object.
Index: /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Default/Xml/EasyXmlGenerator.cs
===================================================================
--- /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Default/Xml/EasyXmlGenerator.cs	(revision 6736)
+++ /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Default/Xml/EasyXmlGenerator.cs	(revision 6737)
@@ -58,5 +58,5 @@
     /// <returns>The token in serialized form.</returns>
     protected override string Format(EndToken endToken) {
-      return CreateNodeEnd(typeCache[endToken.TypeId]);
+      return CreateNodeEnd("END");
     }
 
@@ -154,6 +154,5 @@
         File.Copy(tempfile, filename, true);
         File.Delete(tempfile);
-      }
-      catch (Exception) {
+      } catch (Exception) {
         Logger.Warn("Exception caught, no data has been written.");
         throw;
@@ -190,9 +189,7 @@
           writer.Flush();
         }
-      }
-      catch (PersistenceException) {
+      } catch (PersistenceException) {
         throw;
-      }
-      catch (Exception e) {
+      } catch (Exception e) {
         throw new PersistenceException("Unexpected exception during Serialization.", e);
       }
Index: /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Default/Xml/XmlGenerator.cs
===================================================================
--- /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Default/Xml/XmlGenerator.cs	(revision 6736)
+++ /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Default/Xml/XmlGenerator.cs	(revision 6737)
@@ -157,5 +157,4 @@
       AddTypeInfo(beginToken.TypeId, dict);
       return CreateNodeStart(XmlStringConstants.COMPOSITE, dict);
-
     }
 
@@ -164,8 +163,15 @@
         if (typeId == lastTypeToken.Id) {
           dict.Add("typeName", lastTypeToken.TypeName);
-          dict.Add("serializer", lastTypeToken.Serializer);
           lastTypeToken = null;
         } else {
           FlushTypeToken();
+        }
+      }
+      if (lastSerializerToken != null) {
+        if (typeId == lastSerializerToken.Id) {
+          dict.Add("serializer", lastSerializerToken.Serializer);
+          lastSerializerToken = null;
+        } else {
+          FlushSerializerToken();
         }
       }
@@ -238,4 +244,5 @@
 
     protected TypeToken lastTypeToken;
+    protected SerializerToken lastSerializerToken;
     /// <summary>
     /// Formats the specified token.
@@ -245,4 +252,9 @@
     protected override string Format(TypeToken token) {
       lastTypeToken = token;
+      return "";
+    }
+
+    protected override string Format(SerializerToken token) {
+      lastSerializerToken = token;
       return "";
     }
@@ -255,6 +267,5 @@
           new Dictionary<string, string> {
           {"id", lastTypeToken.Id.ToString()},
-          {"typeName", lastTypeToken.TypeName },
-          {"serializer", lastTypeToken.Serializer }});
+          {"typeName", lastTypeToken.TypeName }});
       } finally {
         lastTypeToken = null;
@@ -262,4 +273,17 @@
     }
 
+    protected string FlushSerializerToken() {
+      if (lastSerializerToken == null)
+        return "";
+      try {
+        return CreateNode(XmlStringConstants.SERIALIZER,
+          new Dictionary<string, string> {
+          {"id", lastSerializerToken.Id.ToString()},
+          {"serializer", lastSerializerToken.Serializer }});
+      } finally {
+        lastTypeToken = null;
+      }
+    }
+
     /// <summary>
     /// Formats the specified type cache.
@@ -267,10 +291,17 @@
     /// <param name="typeCache">The type cache.</param>
     /// <returns>An enumerable of formatted type cache tags.</returns>
-    public IEnumerable<string> Format(List<TypeMapping> typeCache) {
+    public IEnumerable<string> Format(TypeCache typeCache) {
       yield return CreateNodeStart(XmlStringConstants.TYPECACHE);
-      foreach (var mapping in typeCache)
-        yield return CreateNode(
-          XmlStringConstants.TYPE,
-          mapping.GetDict());
+      foreach (var type in typeCache.Types) {
+        int id = typeCache.GetOrCreateId(type);
+        var dict = new Dictionary<string, string> {
+          {"id", id.ToString()},
+          {"typeName", type.AssemblyQualifiedName},
+        };
+        Type serializer = typeCache.GetSerializer(id);
+        if (serializer != null)
+          dict.Add("serializer", serializer.AssemblyQualifiedName);
+        yield return CreateNode(XmlStringConstants.TYPE, dict); 
+      }
       yield return CreateNodeEnd(XmlStringConstants.TYPECACHE);
     }
@@ -342,5 +373,5 @@
             writer.Flush();
             if (includeAssemblies) {
-              foreach (string name in serializer.RequiredFiles) {
+              foreach (string name in serializer.GetRequiredFiles()) {
                 Uri uri = new Uri(name);
                 if (!uri.IsFile) {
Index: /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Default/Xml/XmlParser.cs
===================================================================
--- /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Default/Xml/XmlParser.cs	(revision 6736)
+++ /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Default/Xml/XmlParser.cs	(revision 6737)
@@ -26,4 +26,5 @@
 using System.IO.Compression;
 using System.Xml;
+using HeuristicLab.Persistence.Auxiliary;
 using HeuristicLab.Persistence.Core;
 using HeuristicLab.Persistence.Core.Tokens;
@@ -58,4 +59,5 @@
                      {XmlStringConstants.METAINFO, ParseMetaInfo},
                      {XmlStringConstants.TYPE, ParseTypeInfo},
+                     {XmlStringConstants.SERIALIZER, ParseSerializer},
                    };
     }
@@ -106,5 +108,7 @@
       string serializer = reader.GetAttribute("serializer");
       if (typeName != null)
-        yield return new TypeToken(typeId, typeName, serializer);
+        yield return new TypeToken(typeId, typeName);
+      if (serializer != null)
+        yield return new SerializerToken(typeId, serializer);
       XmlReader inner = reader.ReadSubtree();
       inner.Read();
@@ -124,10 +128,12 @@
       string serializer = reader.GetAttribute("serializer");
       if (typeName != null)
-        yield return new TypeToken(typeId, typeName, serializer);
+        yield return new TypeToken(typeId, typeName);
+      if (serializer != null)
+        yield return new SerializerToken(typeId, serializer);
       yield return new BeginToken(name, typeId, id);
       IEnumerator<ISerializationToken> iterator = GetEnumerator();
       while (iterator.MoveNext())
         yield return iterator.Current;
-      yield return new EndToken(name, typeId, id);
+      yield return new EndToken();
     }
 
@@ -151,8 +157,16 @@
 
     private IEnumerator<ISerializationToken> ParseTypeInfo() {
-      yield return new TypeToken(
-        int.Parse(reader.GetAttribute("id")),
-        reader.GetAttribute("typeName"),
-        reader.GetAttribute("serializer"));
+      int id = int.Parse(reader.GetAttribute("id"));
+      string typeName = reader.GetAttribute("typeName");
+      yield return new TypeToken(id, typeName);
+      string serializer = reader.GetAttribute("serializer");
+      if (serializer != null)
+        yield return new SerializerToken(id, serializer);
+    }
+
+    private IEnumerator<ISerializationToken> ParseSerializer() {
+      int id = int.Parse(reader.GetAttribute("id"));
+      string serializer = reader.GetAttribute("serializer");
+      yield return new SerializerToken(id, serializer);
     }
 
@@ -162,14 +176,19 @@
     /// <param name="reader">The reader.</param>
     /// <returns>A list of type mapping entries.</returns>
-    public static List<TypeMapping> ParseTypeCache(TextReader reader) {
-      try {
-        var typeCache = new List<TypeMapping>();
+    public static ReverseTypeCache ParseTypeCache(TextReader reader) {
+      ReverseTypeCache typeCache = new ReverseTypeCache();
+      try {
         XmlReader xmlReader = XmlReader.Create(reader);
         while (xmlReader.Read()) {
           if (xmlReader.Name == XmlStringConstants.TYPE) {
-            typeCache.Add(new TypeMapping(
+            int id = int.Parse(xmlReader.GetAttribute("id"));
+            typeCache.AddType(id, TypeLoader.Load(xmlReader.GetAttribute("typeName")));
+            string serializer = xmlReader.GetAttribute("serializer");
+            if (serializer != null)
+              typeCache.AddSerializer(id, TypeLoader.Load(serializer));
+          } else if (xmlReader.Name == XmlStringConstants.SERIALIZER) {
+            typeCache.AddSerializer(
               int.Parse(xmlReader.GetAttribute("id")),
-              xmlReader.GetAttribute("typeName"),
-              xmlReader.GetAttribute("serializer")));
+              TypeLoader.Load(xmlReader.GetAttribute("serializer")));
           }
         }
@@ -221,5 +240,5 @@
         using (StreamReader reader = new StreamReader(new GZipStream(stream, CompressionMode.Decompress))) {
           XmlParser parser = new XmlParser(reader);
-          Deserializer deserializer = new Deserializer(new TypeMapping[] { });
+          Deserializer deserializer = new Deserializer(new ReverseTypeCache());
           return deserializer.Deserialize(new AsyncBuffer<ISerializationToken>(parser));
         }
Index: /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Default/Xml/XmlStringConstants.cs
===================================================================
--- /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Default/Xml/XmlStringConstants.cs	(revision 6736)
+++ /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Default/Xml/XmlStringConstants.cs	(revision 6737)
@@ -30,4 +30,5 @@
     public const string TYPECACHE = "TYPECACHE";
     public const string TYPE = "TYPE";
+    public const string SERIALIZER = "SERIALIZER";
     public const string METAINFO = "METAINFO";
   }
Index: /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/HeuristicLab.Persistence-3.3.csproj
===================================================================
--- /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/HeuristicLab.Persistence-3.3.csproj	(revision 6736)
+++ /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/HeuristicLab.Persistence-3.3.csproj	(revision 6737)
@@ -126,11 +126,14 @@
     <Compile Include="Auxiliary\ReflectionTools.cs" />
     <None Include="HeuristicLabPersistencePlugin.cs.frame" />
+    <Compile Include="Core\CachedTypeSerializer.cs" />
     <Compile Include="Core\Configuration.cs" />
+    <Compile Include="Core\ReverseTypeCache.cs" />
     <Compile Include="Core\PersistenceException.cs" />
     <Compile Include="Core\PrimitiveSerializerBase.cs" />
     <Compile Include="Core\FormatBase.cs" />
     <Compile Include="Auxiliary\TypeExtensions.cs" />
+    <Compile Include="Core\Tokens\SerializerToken.cs" />
     <Compile Include="Core\Tokens\TypeToken.cs" />
-    <Compile Include="Core\TypeMapping.cs" />
+    <Compile Include="Core\TypeCache.cs" />
     <Compile Include="Auxiliary\TypeName.cs" />
     <Compile Include="Core\GeneratorBase.cs" />
Index: /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Tests/UseCases.cs
===================================================================
--- /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Tests/UseCases.cs	(revision 6736)
+++ /branches/PersistenceSpeedUp/HeuristicLab.Persistence/3.3/Tests/UseCases.cs	(revision 6737)
@@ -1129,12 +1129,14 @@
       Assert.AreEqual("ROOT", ((BeginToken)it.Current).Name); it.MoveNext();
       Assert.AreEqual("ReadOnly", ((PrimitiveToken)it.Current).Name); it.MoveNext();
-      Assert.AreEqual("ROOT", ((EndToken)it.Current).Name); it.MoveNext();
-      var deserializer = new Deserializer(new[] { 
-        new TypeMapping(0, typeof(OneWayTest).AssemblyQualifiedName, typeof(StorableSerializer).AssemblyQualifiedName),
-        new TypeMapping(1, typeof(string).AssemblyQualifiedName, typeof(String2XmlSerializer).AssemblyQualifiedName) });
+      ReverseTypeCache typeCache = new ReverseTypeCache();
+      typeCache.AddType(0, typeof(OneWayTest));
+      typeCache.AddSerializer(0, typeof(StorableSerializer));
+      typeCache.AddType(1, typeof(string));
+      typeCache.AddSerializer(1, typeof(String2XmlSerializer));
+      var deserializer = new Deserializer(typeCache);
       var newTest = (OneWayTest)deserializer.Deserialize(new ISerializationToken[] {
         new BeginToken("ROOT", 0, 0),
         new PrimitiveToken("WriteOnly", 1, 1, new XmlString("<![CDATA[serial data]]>")),
-        new EndToken("ROOT", 0, 0)
+        new EndToken()
       });
       Assert.AreEqual("serial data", newTest.value);
@@ -1168,4 +1170,17 @@
     }
 
+    [TestMethod]
+    public void TestCachedTypeSerializer() {
+      List<Type> types = new List<Type> { typeof(object), typeof(UseCases), typeof(XmlGenerator) };
+      var s = new Serializer(types, ConfigurationService.Instance.GetDefaultConfig(new XmlFormat()));
+      var tokens = s.ToList();
+      foreach (var type in types)
+        Assert.IsTrue(s.SerializedTypes.Contains(type));
+      var d = new Deserializer(s.TypeCache.Reverse());
+      var newTypes = (List<Type>)d.Deserialize(tokens);
+      for (int i = 0; i < types.Count; i++)
+        Assert.AreEqual(types[i], newTypes[i]);
+    }
+
 
 
