Index: trunk/sources/HeuristicLab.Persistence/3.3/Auxiliary/StringExtensions.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Auxiliary/StringExtensions.cs	(revision 3937)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Auxiliary/StringExtensions.cs	(revision 3937)
@@ -0,0 +1,53 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+
+namespace HeuristicLab.Persistence.Auxiliary {
+  /// <summary>
+  /// Extension methods for the <see cref="System.String"/> class.
+  /// </summary>
+  public static class StringExtensions {
+
+    /// <summary>
+    /// Enumeration over the substrings when split with a certain delimiter.
+    /// </summary>
+    /// <param name="s">The string.</param>
+    /// <param name="delimiter">The delimiter.</param>
+    /// <returns>An enumeration over the delimited substrings.</returns>
+    public static IEnumerable<string> EnumerateSplit(this string s, char delimiter) {
+      int startIdx = 0;
+      for (int i = 0; i < s.Length; i++) {
+        if (s[i] == delimiter) {
+          if (i > startIdx) {
+            yield return s.Substring(startIdx, i - startIdx);
+          }
+          startIdx = i+1;
+        }
+      }
+      if (startIdx < s.Length)
+        yield return s.Substring(startIdx, s.Length - startIdx);
+    }
+
+    /// <summary>
+    /// Enumeration over the substrings when split with a certain delimiter..
+    /// </summary>
+    /// <param name="s">The string.</param>
+    /// <param name="delimiter">The delimiter.</param>
+    /// <returns>An enumerator over the delimited substrings.</returns>
+    public static IEnumerator<string> GetSplitEnumerator(this string s, char delimiter) {
+      int startIdx = 0;
+      for (int i = 0; i < s.Length; i++) {
+        if (s[i] == delimiter) {
+          if (i > startIdx) {
+            yield return s.Substring(startIdx, i - startIdx);
+          }
+          startIdx = i + 1;
+        }
+      }
+      if (startIdx < s.Length)
+        yield return s.Substring(startIdx, s.Length - startIdx);
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Persistence/3.3/Core/TypeMapping.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Core/TypeMapping.cs	(revision 3935)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Core/TypeMapping.cs	(revision 3937)
@@ -65,7 +65,7 @@
     /// <returns>A dictionary containing all properties
     /// and values of this instance.</returns>
-    public Dictionary<string, object> GetDict() {
-      return new Dictionary<string, object> {
-        {"id", Id},
+    public Dictionary<string, string> GetDict() {
+      return new Dictionary<string, string> {
+        {"id", Id.ToString()},
         {"typeName", TypeName},
         {"serializer", Serializer}};
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/CompactNumberArray2StringSerializer.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/CompactNumberArray2StringSerializer.cs	(revision 3935)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/CompactNumberArray2StringSerializer.cs	(revision 3937)
@@ -21,4 +21,5 @@
 
 using System;
+using System.Linq;
 using HeuristicLab.Persistence.Interfaces;
 using HeuristicLab.Persistence.Core;
@@ -28,4 +29,5 @@
 using System.Text;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Persistence.Auxiliary;
 
 namespace HeuristicLab.Persistence.Default.CompositeSerializers {
@@ -58,10 +60,13 @@
       int[] lengths = new int[a.Rank];
       int[] lowerBounds = new int[a.Rank];
-      StringBuilder sb = new StringBuilder();
+      StringBuilder sb = new StringBuilder(a.Rank * 3);
       sb.Append(a.Rank).Append(';');
+      int capacity = 1;
       for (int i = 0; i < a.Rank; i++) {
         sb.Append(a.GetLength(i)).Append(';');
         lengths[i] = a.GetLength(i);
+        capacity *= lengths[i];
       }
+      sb.EnsureCapacity(capacity * 3);
       for (int i = 0; i < a.Rank; i++) {
         sb.Append(a.GetLowerBound(i)).Append(';');
@@ -92,7 +97,5 @@
         var tagIter = metaInfo.GetEnumerator();
         tagIter.MoveNext();
-        var valueIter = ((string)tagIter.Current.Value)
-          .Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
-          .GetEnumerator();
+        var valueIter = ((string)tagIter.Current.Value).GetSplitEnumerator(';');
         valueIter.MoveNext();
         int rank = int.Parse((string)valueIter.Current);
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/NumberEnumerable2StringSerializer.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/NumberEnumerable2StringSerializer.cs	(revision 3935)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/NumberEnumerable2StringSerializer.cs	(revision 3937)
@@ -93,4 +93,5 @@
     }
 
+    private static object[] emptyArgs = new object[0];
     public IEnumerable<Tag> Decompose(object obj) {
       Type type = obj.GetType();
@@ -102,10 +103,9 @@
           iMap.InterfaceMethods,
           enumerable.GetMethod("GetEnumerator"))];
-      object[] empty = new object[] { };
-      object genericEnumerator = getEnumeratorMethod.Invoke(obj, empty);
+      object genericEnumerator = getEnumeratorMethod.Invoke(obj, emptyArgs);
       MethodInfo moveNextMethod = genericEnumerator.GetType().GetMethod("MoveNext");
       PropertyInfo currentProperty = genericEnumerator.GetType().GetProperty("Current");
       StringBuilder sb = new StringBuilder();
-      while ((bool)moveNextMethod.Invoke(genericEnumerator, empty))
+      while ((bool)moveNextMethod.Invoke(genericEnumerator, emptyArgs))
         sb.Append(
           numberConverter.Format(
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/Xml/Compact/DoubleList2XmlSerializer.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/Xml/Compact/DoubleList2XmlSerializer.cs	(revision 3935)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/Xml/Compact/DoubleList2XmlSerializer.cs	(revision 3937)
@@ -27,4 +27,5 @@
 using HeuristicLab.Persistence.Default.Xml.Primitive;
 using System.Text;
+using HeuristicLab.Persistence.Auxiliary;
 
 namespace HeuristicLab.Persistence.Default.Xml.Compact {
@@ -32,8 +33,6 @@
   internal sealed class DoubleList2XmlSerializer : CompactXmlSerializerBase<List<double>> {
 
-    private static readonly char[] separators = new char[] { ';' };
-
     public override XmlString Format(List<double> list) {
-      StringBuilder sb = new StringBuilder();
+      StringBuilder sb = new StringBuilder(list.Count * 3);
       foreach (var d in list) {
         sb.Append(Double2XmlSerializer.FormatG17(d)).Append(';');
@@ -44,7 +43,6 @@
     public override List<double> Parse(XmlString data) {
       try {
-        var values = data.Data.Split(separators, StringSplitOptions.RemoveEmptyEntries);
-        List<double> list = new List<double>(values.Length);
-        foreach (var value in values) {
+        List<double> list = new List<double>();
+        foreach (var value in data.Data.EnumerateSplit(';')) {
           list.Add(Double2XmlSerializer.ParseG17(value));
         }
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/Xml/Compact/NumberArray2XmlSerializerBase.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/Xml/Compact/NumberArray2XmlSerializerBase.cs	(revision 3935)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/Xml/Compact/NumberArray2XmlSerializerBase.cs	(revision 3937)
@@ -26,4 +26,5 @@
 using HeuristicLab.Persistence.Core;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Persistence.Auxiliary;
 
 namespace HeuristicLab.Persistence.Default.Xml.Compact {
@@ -32,5 +33,5 @@
   internal abstract class NumberArray2XmlSerializerBase<T> : CompactXmlSerializerBase<T> where T : class {
 
-    protected virtual string Separator { get { return ";"; } }
+    protected virtual char Separator { get { return ';'; } }
     protected abstract string FormatValue(object o);
     protected abstract object ParseValue(string o);
@@ -40,11 +41,14 @@
       int[] lengths = new int[a.Rank];
       int[] lowerBounds = new int[a.Rank];
-      StringBuilder sb = new StringBuilder();
+      StringBuilder sb = new StringBuilder(a.Rank * 3);
       sb.Append(a.Rank);
+      int capacity = 1;
       for (int i = 0; i < a.Rank; i++) {
         sb.Append(Separator);
         sb.Append(a.GetLength(i));
         lengths[i] = a.GetLength(i);
+        capacity *= lengths[i];
       }
+      sb.EnsureCapacity(capacity * 3);
       for (int i = 0; i < a.Rank; i++) {
         sb.Append(Separator);
@@ -71,7 +75,5 @@
     public override T Parse(XmlString x) {
       try {
-        IEnumerator values =
-          x.Data.Split(new[] { Separator },
-          StringSplitOptions.RemoveEmptyEntries).GetEnumerator();
+        IEnumerator values = x.Data.GetSplitEnumerator(Separator);
         values.MoveNext();
         int rank = int.Parse((string)values.Current);
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/Xml/Compact/NumberEnumeration2XmlSerializerBase.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/Xml/Compact/NumberEnumeration2XmlSerializerBase.cs	(revision 3935)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/Xml/Compact/NumberEnumeration2XmlSerializerBase.cs	(revision 3937)
@@ -26,4 +26,5 @@
 using HeuristicLab.Persistence.Core;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Persistence.Auxiliary;
 
 namespace HeuristicLab.Persistence.Default.Xml.Compact {
@@ -32,5 +33,5 @@
   internal abstract class NumberEnumeration2XmlSerializerBase<T> : CompactXmlSerializerBase<T> where T : IEnumerable {
 
-    protected virtual string Separator { get { return ";"; } }
+    protected virtual char Separator { get { return ';'; } }
     protected abstract void Add(IEnumerable enumeration, object o);
     protected abstract IEnumerable Instantiate();
@@ -50,6 +51,5 @@
       try {
         IEnumerable enumeration = Instantiate();
-        string[] values = x.Data.Split(new[] { Separator }, StringSplitOptions.RemoveEmptyEntries);
-        foreach (var value in values) {
+        foreach (var value in x.Data.EnumerateSplit(Separator)) {
           Add(enumeration, ParseValue(value));
         }
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/Xml/EasyXmlGenerator.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/Xml/EasyXmlGenerator.cs	(revision 3935)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/Xml/EasyXmlGenerator.cs	(revision 3937)
@@ -49,8 +49,8 @@
     /// <returns>The token in serialized form.</returns>
     protected override string Format(BeginToken beginToken) {
-      var dict = new Dictionary<string, object> {
+      var dict = new Dictionary<string, string> {
           {"name", beginToken.Name},
-          {"id", beginToken.Id}};
-      return CreateNodeStart(typeCache[beginToken.TypeId], dict);        
+          {"id", beginToken.Id.ToString()}};
+      return CreateNodeStart(typeCache[beginToken.TypeId], dict);
     }
 
@@ -70,7 +70,7 @@
     /// <returns>The token in serialized form.</returns>
     protected override string Format(PrimitiveToken dataToken) {
-      var dict = new Dictionary<string, object> {
+      var dict = new Dictionary<string, string> {
             {"name", dataToken.Name},
-            {"id", dataToken.Id}};
+            {"id", dataToken.Id.ToString()}};
       return CreateNode(typeCache[dataToken.TypeId], dict,
         ((XmlString)dataToken.SerialData).Data);
@@ -84,5 +84,5 @@
     protected override string Format(ReferenceToken refToken) {
       return CreateNode(refToken.Id.ToString(),
-        new Dictionary<string, object> {
+        new Dictionary<string, string> {
           {"name", refToken.Name}});
     }
@@ -95,5 +95,5 @@
     protected override string Format(NullReferenceToken nullRefToken) {
       return CreateNode(XmlStringConstants.NULL,
-        new Dictionary<string, object>{
+        new Dictionary<string, string>{
           {"name", nullRefToken.Name}});
     }
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/Xml/XmlGenerator.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/Xml/XmlGenerator.cs	(revision 3935)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/Xml/XmlGenerator.cs	(revision 3937)
@@ -23,4 +23,5 @@
 using System;
 using System.Text;
+using System.Linq;
 using HeuristicLab.Persistence.Interfaces;
 using HeuristicLab.Persistence.Core;
@@ -63,5 +64,5 @@
     protected enum NodeType { Start, End, Inline } ;
 
-    protected static void AddXmlTagContent(StringBuilder sb, string name, Dictionary<string, object> attributes) {
+    protected static void AddXmlTagContent(StringBuilder sb, string name, Dictionary<string, string> attributes) {
       sb.Append(name);
       foreach (var attribute in attributes) {
@@ -76,5 +77,11 @@
     }
 
-    protected static void AddXmlStartTag(StringBuilder sb, string name, Dictionary<string, object> attributes) {
+    protected static int AttributeLength(Dictionary<string, string> attributes) {
+      return attributes
+        .Where(kvp => !string.IsNullOrEmpty(kvp.Key) && !string.IsNullOrEmpty(kvp.Value))
+        .Select(kvp => kvp.Key.Length + kvp.Value.Length + 4).Sum();
+    }
+
+    protected static void AddXmlStartTag(StringBuilder sb, string name, Dictionary<string, string> attributes) {
       sb.Append('<');
       AddXmlTagContent(sb, name, attributes);
@@ -82,5 +89,5 @@
     }
 
-    protected static void AddXmlInlineTag(StringBuilder sb, string name, Dictionary<string, object> attributes) {
+    protected static void AddXmlInlineTag(StringBuilder sb, string name, Dictionary<string, string> attributes) {
       sb.Append('<');
       AddXmlTagContent(sb, name, attributes);
@@ -94,6 +101,7 @@
     }
 
-    protected string CreateNodeStart(string name, Dictionary<string, object> attributes) {
-      StringBuilder sb = new StringBuilder();
+    protected string CreateNodeStart(string name, Dictionary<string, string> attributes) {
+      StringBuilder sb = new StringBuilder(prefix.Length + name.Length + 4
+        + AttributeLength(attributes));
       sb.Append(prefix);
       Depth += 1;
@@ -103,11 +111,12 @@
     }
 
+    private static Dictionary<string, string> emptyDict = new Dictionary<string, string>();
     protected string CreateNodeStart(string name) {
-      return CreateNodeStart(name, new Dictionary<string, object>());
+      return CreateNodeStart(name, emptyDict);
     }
 
     protected string CreateNodeEnd(string name) {
       Depth -= 1;
-      StringBuilder sb = new StringBuilder();
+      StringBuilder sb = new StringBuilder(prefix.Length + name.Length + 5);
       sb.Append(prefix);
       AddXmlEndTag(sb, name);
@@ -116,6 +125,7 @@
     }
 
-    protected string CreateNode(string name, Dictionary<string, object> attributes) {
-      StringBuilder sb = new StringBuilder();
+    protected string CreateNode(string name, Dictionary<string, string> attributes) {
+      StringBuilder sb = new StringBuilder(prefix.Length + name.Length + 5
+        + AttributeLength(attributes));
       sb.Append(prefix);
       AddXmlInlineTag(sb, name, attributes);
@@ -124,5 +134,5 @@
     }
 
-    protected string CreateNode(string name, Dictionary<string, object> attributes, string content) {
+    protected string CreateNode(string name, Dictionary<string, string> attributes, string content) {
       StringBuilder sb = new StringBuilder();
       sb.Append(prefix);
@@ -139,8 +149,8 @@
     /// <returns>The token in serialized form.</returns>
     protected override string Format(BeginToken beginToken) {
-      var dict = new Dictionary<string, object> {
+      var dict = new Dictionary<string, string> {
           {"name", beginToken.Name},
-          {"typeId", beginToken.TypeId},
-          {"id", beginToken.Id}};
+          {"typeId", beginToken.TypeId.ToString()},
+          {"id", beginToken.Id.ToString()}};
       AddTypeInfo(beginToken.TypeId, dict);
       return CreateNodeStart(XmlStringConstants.COMPOSITE, dict);
@@ -148,5 +158,5 @@
     }
 
-    protected void AddTypeInfo(int typeId, Dictionary<string, object> dict) {
+    protected void AddTypeInfo(int typeId, Dictionary<string, string> dict) {
       if (lastTypeToken != null) {
         if (typeId == lastTypeToken.Id) {
@@ -175,8 +185,8 @@
     /// <returns>The token in serialized form.</returns>
     protected override string Format(PrimitiveToken dataToken) {
-      var dict = new Dictionary<string, object> {
-            {"typeId", dataToken.TypeId},
+      var dict = new Dictionary<string, string> {
+            {"typeId", dataToken.TypeId.ToString()},
             {"name", dataToken.Name},
-            {"id", dataToken.Id}};
+            {"id", dataToken.Id.ToString()}};
       AddTypeInfo(dataToken.TypeId, dict);
       return CreateNode(XmlStringConstants.PRIMITIVE, dict,
@@ -191,6 +201,6 @@
     protected override string Format(ReferenceToken refToken) {
       return CreateNode(XmlStringConstants.REFERENCE,
-        new Dictionary<string, object> {
-          {"ref", refToken.Id},
+        new Dictionary<string, string> {
+          {"ref", refToken.Id.ToString()},
           {"name", refToken.Name}});
     }
@@ -203,5 +213,5 @@
     protected override string Format(NullReferenceToken nullRefToken) {
       return CreateNode(XmlStringConstants.NULL,
-        new Dictionary<string, object>{
+        new Dictionary<string, string>{
           {"name", nullRefToken.Name}});
     }
@@ -241,6 +251,6 @@
       try {
         return CreateNode(XmlStringConstants.TYPE,
-          new Dictionary<string, object> {
-          {"id", lastTypeToken.Id},
+          new Dictionary<string, string> {
+          {"id", lastTypeToken.Id.ToString()},
           {"typeName", lastTypeToken.TypeName },
           {"serializer", lastTypeToken.Serializer }});
Index: trunk/sources/HeuristicLab.Persistence/3.3/HeuristicLab.Persistence-3.3.csproj
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/HeuristicLab.Persistence-3.3.csproj	(revision 3935)
+++ trunk/sources/HeuristicLab.Persistence/3.3/HeuristicLab.Persistence-3.3.csproj	(revision 3937)
@@ -98,4 +98,5 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Auxiliary\StringExtensions.cs" />
     <Compile Include="Auxiliary\TypeLoader.cs" />
     <Compile Include="Auxiliary\TypeNameParser.cs" />
Index: trunk/sources/HeuristicLab.Persistence/3.3/Tests/UseCases.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Tests/UseCases.cs	(revision 3935)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Tests/UseCases.cs	(revision 3937)
@@ -1065,4 +1065,14 @@
     }
 
+    [TestMethod]
+    public void TestStringSplit() {
+      string s = "1.2;2.3;3.4;;;4.9";
+      var l = s.EnumerateSplit(';').ToList();
+      Assert.AreEqual("1.2", l[0]);
+      Assert.AreEqual("2.3", l[1]);
+      Assert.AreEqual("3.4", l[2]);
+      Assert.AreEqual("4.9", l[3]);
+    }
+
 
     [ClassInitialize]
