Index: trunk/sources/HeuristicLab.Persistence/3.3/Core/DeSerializer.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Core/DeSerializer.cs	(revision 1566)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Core/DeSerializer.cs	(revision 1567)
@@ -4,52 +4,50 @@
 using HeuristicLab.Persistence.Core.Tokens;
 
-namespace HeuristicLab.Persistence.Core {
+namespace HeuristicLab.Persistence.Core {  
 
-  public class ParentReference { }
+  public class Deserializer {    
 
-  class Midwife {
+    class Midwife {
 
-    public int? Id { get; private set; }
-    public bool MetaMode { get; set; }
-    public object Obj { get; private set; }
+      public int? Id { get; private set; }
+      public bool MetaMode { get; set; }
+      public object Obj { get; private set; }
 
-    private List<Tag> metaInfo;
-    private List<Tag> customValues;
-    private Type type;
-    private IDecomposer decomposer;
+      private List<Tag> metaInfo;
+      private List<Tag> customValues;
+      private Type type;
+      private IDecomposer decomposer;
 
-    public Midwife(object value) {
-      this.Obj = value;
-    }
+      public Midwife(object value) {
+        this.Obj = value;
+      }
 
-    public Midwife(Type type, IDecomposer decomposer, int? id) {
-      this.type = type;
-      this.decomposer = decomposer;
-      this.Id = id;
-      MetaMode = false;
-      metaInfo = new List<Tag>();
-      customValues = new List<Tag>();
-    }
+      public Midwife(Type type, IDecomposer decomposer, int? id) {
+        this.type = type;
+        this.decomposer = decomposer;
+        this.Id = id;
+        MetaMode = false;
+        metaInfo = new List<Tag>();
+        customValues = new List<Tag>();
+      }
 
-    public void CreateInstance() {
-      if (Obj != null)
-        throw new ApplicationException("object already instantiated");
-      Obj = decomposer.CreateInstance(type, metaInfo);
-    }
+      public void CreateInstance() {
+        if (Obj != null)
+          throw new ApplicationException("object already instantiated");
+        Obj = decomposer.CreateInstance(type, metaInfo);
+      }
 
-    public void AddValue(string name, object value) {
-      if (MetaMode) {
-        metaInfo.Add(new Tag(name, value));
-      } else {
-        customValues.Add(new Tag(name, value));
+      public void AddValue(string name, object value) {
+        if (MetaMode) {
+          metaInfo.Add(new Tag(name, value));
+        } else {
+          customValues.Add(new Tag(name, value));
+        }
+      }
+
+      public void Populate() {
+        decomposer.Populate(Obj, customValues, type);
       }
     }
-
-    public void Populate() {
-      decomposer.Populate(Obj, customValues, type);
-    }
-  }
-
-  public class Deserializer {
 
     private readonly Dictionary<int, object> id2obj;
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/Bool2DebugStringFormatter.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/Bool2DebugStringFormatter.cs	(revision 1567)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/Bool2DebugStringFormatter.cs	(revision 1567)
@@ -0,0 +1,14 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Text;
+using HeuristicLab.Persistence.Interfaces;
+using HeuristicLab.Persistence.Default.Xml;
+using HeuristicLab.Persistence.Core;
+using HeuristicLab.Persistence.Core.Tokens;
+
+namespace HeuristicLab.Persistence.Default.DebugString {
+
+  [EmptyStorableClass]
+  public class Bool2DebugStringFormatter : ValueType2DebugStringFormatterBase<bool> { }
+
+}
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/DateTime2DebugStringFormatter.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/DateTime2DebugStringFormatter.cs	(revision 1567)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/DateTime2DebugStringFormatter.cs	(revision 1567)
@@ -0,0 +1,14 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Text;
+using HeuristicLab.Persistence.Interfaces;
+using HeuristicLab.Persistence.Default.Xml;
+using HeuristicLab.Persistence.Core;
+using HeuristicLab.Persistence.Core.Tokens;
+
+namespace HeuristicLab.Persistence.Default.DebugString {
+
+  [EmptyStorableClass]
+  public class DateTime2DebugStringFormatter : ValueType2DebugStringFormatterBase<DateTime> { }
+
+}
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/DebugString.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/DebugString.cs	(revision 1567)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/DebugString.cs	(revision 1567)
@@ -0,0 +1,18 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Text;
+using HeuristicLab.Persistence.Interfaces;
+using HeuristicLab.Persistence.Default.Xml;
+using HeuristicLab.Persistence.Core;
+using HeuristicLab.Persistence.Core.Tokens;
+
+namespace HeuristicLab.Persistence.Default.DebugString {
+
+  public class DebugString : ISerialData {
+    public string Data { get; set; }
+    public DebugString(string s) {
+      Data = s;
+    }
+  }
+
+}
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/DebugStringFormat.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/DebugStringFormat.cs	(revision 1567)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/DebugStringFormat.cs	(revision 1567)
@@ -0,0 +1,15 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Text;
+using HeuristicLab.Persistence.Interfaces;
+using HeuristicLab.Persistence.Default.Xml;
+using HeuristicLab.Persistence.Core;
+using HeuristicLab.Persistence.Core.Tokens;
+
+namespace HeuristicLab.Persistence.Default.DebugString {
+
+  public class DebugStringFormat : FormatBase<DebugString> {
+    public override string Name { get { return "ViewOnly"; } }
+  }
+
+}
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/DebugStringGenerator.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/DebugStringGenerator.cs	(revision 1567)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/DebugStringGenerator.cs	(revision 1567)
@@ -0,0 +1,113 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Text;
+using HeuristicLab.Persistence.Interfaces;
+using HeuristicLab.Persistence.Default.Xml;
+using HeuristicLab.Persistence.Core;
+using HeuristicLab.Persistence.Core.Tokens;
+
+namespace HeuristicLab.Persistence.Default.DebugString {
+
+  public class DebugStringGenerator : GeneratorBase<string> {
+
+    private bool isSepReq;
+    private readonly bool showRefs;
+
+    public DebugStringGenerator() : this(false) { }
+
+    public DebugStringGenerator(bool showRefs) {
+      isSepReq = false;
+      this.showRefs = showRefs;
+    }
+
+    protected override string Format(BeginToken beginToken) {
+      StringBuilder sb = new StringBuilder();
+      if (isSepReq)
+        sb.Append(", ");
+      if (!string.IsNullOrEmpty(beginToken.Name)) {
+        sb.Append(beginToken.Name);
+        if (beginToken.Id != null && showRefs) {
+          sb.Append('[');
+          sb.Append(beginToken.Id);
+          sb.Append(']');
+        }
+      }
+      sb.Append("(");
+      isSepReq = false;
+      return sb.ToString();
+    }
+
+    protected override string Format(EndToken endToken) {
+      isSepReq = true;
+      return ")";
+    }
+
+    protected override string Format(PrimitiveToken primitiveToken) {
+      StringBuilder sb = new StringBuilder();
+      if (isSepReq)
+        sb.Append(", ");
+      if (!string.IsNullOrEmpty(primitiveToken.Name)) {
+        sb.Append(primitiveToken.Name);
+        if (primitiveToken.Id != null && showRefs) {
+          sb.Append('[');
+          sb.Append(primitiveToken.Id);
+          sb.Append(']');
+        }
+        sb.Append('=');
+      }
+      sb.Append(((DebugString)primitiveToken.SerialData).Data);
+      isSepReq = true;
+      return sb.ToString();
+    }
+
+    protected override string Format(ReferenceToken referenceToken) {
+      StringBuilder sb = new StringBuilder();
+      if (isSepReq)
+        sb.Append(", ");
+      if (!string.IsNullOrEmpty(referenceToken.Name)) {
+        sb.Append(referenceToken.Name);
+        sb.Append('=');
+      }
+      sb.Append('{');
+      sb.Append(referenceToken.Id);
+      sb.Append('}');
+      isSepReq = true;
+      return sb.ToString();
+    }
+
+    protected override string Format(NullReferenceToken nullReferenceToken) {
+      StringBuilder sb = new StringBuilder();
+      if (isSepReq)
+        sb.Append(", ");
+      if (!string.IsNullOrEmpty(nullReferenceToken.Name)) {
+        sb.Append(nullReferenceToken.Name);
+        sb.Append('=');
+      }
+      sb.Append("<null>");
+      isSepReq = true;
+      return sb.ToString();
+    }
+
+    protected override string Format(MetaInfoBeginToken metaInfoBeginToken) {
+      return "[";
+    }
+
+    protected override string Format(MetaInfoEndToken metaInfoEndToken) {
+      return "]";
+    }
+
+    public static string Serialize(object o) {
+      return Serialize(o, ConfigurationService.Instance.GetDefaultConfig(new DebugStringFormat()));
+    }
+
+    public static string Serialize(object o, Configuration configuration) {
+      Serializer s = new Serializer(o, configuration);
+      DebugStringGenerator generator = new DebugStringGenerator();
+      StringBuilder sb = new StringBuilder();
+      foreach (ISerializationToken token in s) {
+        sb.Append(generator.Format(token));
+      }
+      return sb.ToString();
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/Doubld2DebugStringFormatter.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/Doubld2DebugStringFormatter.cs	(revision 1567)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/Doubld2DebugStringFormatter.cs	(revision 1567)
@@ -0,0 +1,14 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Text;
+using HeuristicLab.Persistence.Interfaces;
+using HeuristicLab.Persistence.Default.Xml;
+using HeuristicLab.Persistence.Core;
+using HeuristicLab.Persistence.Core.Tokens;
+
+namespace HeuristicLab.Persistence.Default.DebugString {
+
+  [EmptyStorableClass]
+  public class Double2DebugStringFormatter : ValueType2DebugStringFormatterBase<double> { }
+
+}
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/Float2DebugStringFormatter.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/Float2DebugStringFormatter.cs	(revision 1567)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/Float2DebugStringFormatter.cs	(revision 1567)
@@ -0,0 +1,14 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Text;
+using HeuristicLab.Persistence.Interfaces;
+using HeuristicLab.Persistence.Default.Xml;
+using HeuristicLab.Persistence.Core;
+using HeuristicLab.Persistence.Core.Tokens;
+
+namespace HeuristicLab.Persistence.Default.DebugString {
+
+  [EmptyStorableClass]
+  public class Float2DebugStringFormatter : ValueType2DebugStringFormatterBase<float> { }
+
+}
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/Int2DebugStringFormatter.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/Int2DebugStringFormatter.cs	(revision 1567)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/Int2DebugStringFormatter.cs	(revision 1567)
@@ -0,0 +1,14 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Text;
+using HeuristicLab.Persistence.Interfaces;
+using HeuristicLab.Persistence.Default.Xml;
+using HeuristicLab.Persistence.Core;
+using HeuristicLab.Persistence.Core.Tokens;
+
+namespace HeuristicLab.Persistence.Default.DebugString {
+
+  [EmptyStorableClass]
+  public class Int2DebugStringFormatter : ValueType2DebugStringFormatterBase<int> { }
+
+}
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/String2DebugStringFormatter.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/String2DebugStringFormatter.cs	(revision 1567)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/String2DebugStringFormatter.cs	(revision 1567)
@@ -0,0 +1,14 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Text;
+using HeuristicLab.Persistence.Interfaces;
+using HeuristicLab.Persistence.Default.Xml;
+using HeuristicLab.Persistence.Core;
+using HeuristicLab.Persistence.Core.Tokens;
+
+namespace HeuristicLab.Persistence.Default.DebugString {
+
+  [EmptyStorableClass]
+  public class String2DebugStringFormatter : ValueType2DebugStringFormatterBase<string> { }
+
+}
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/Type2DebugStringFormatter.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/Type2DebugStringFormatter.cs	(revision 1567)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/Type2DebugStringFormatter.cs	(revision 1567)
@@ -0,0 +1,14 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Text;
+using HeuristicLab.Persistence.Interfaces;
+using HeuristicLab.Persistence.Default.Xml;
+using HeuristicLab.Persistence.Core;
+using HeuristicLab.Persistence.Core.Tokens;
+
+namespace HeuristicLab.Persistence.Default.DebugString {
+
+  [EmptyStorableClass]
+  public class Type2DebugStringFormatter : ValueType2DebugStringFormatterBase<Type> { }
+
+}
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/ValueType2DebugStringFormatterBase.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/ValueType2DebugStringFormatterBase.cs	(revision 1567)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/DebugString/ValueType2DebugStringFormatterBase.cs	(revision 1567)
@@ -0,0 +1,17 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Text;
+using HeuristicLab.Persistence.Interfaces;
+using HeuristicLab.Persistence.Default.Xml;
+using HeuristicLab.Persistence.Core;
+using HeuristicLab.Persistence.Core.Tokens;
+
+namespace HeuristicLab.Persistence.Default.DebugString {
+
+  public abstract class ValueType2DebugStringFormatterBase<T> : FormatterBase<T, DebugString> {
+    public override DebugString Format(T o) { return new DebugString(o.ToString()); }
+    public override T Parse(DebugString s) {
+      throw new NotImplementedException();
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/Decomposers/CompactNumberArray2StringDecomposer.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/Decomposers/CompactNumberArray2StringDecomposer.cs	(revision 1567)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/Decomposers/CompactNumberArray2StringDecomposer.cs	(revision 1567)
@@ -0,0 +1,104 @@
+﻿using System;
+using HeuristicLab.Persistence.Interfaces;
+using HeuristicLab.Persistence.Core;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Globalization;
+using System.Text;
+
+namespace HeuristicLab.Persistence.Default.Decomposers {
+
+  [EmptyStorableClass]
+  public class CompactNumberArray2StringDecomposer : IDecomposer {
+
+    public int Priority {
+      get { return 200; }
+    }
+
+    private static readonly Number2StringConverter numberConverter =
+      new Number2StringConverter();
+
+    public bool CanDecompose(Type type) {
+      return
+        (type.IsArray || type == typeof(Array)) &&
+        numberConverter.CanDecompose(type.GetElementType());
+    }
+
+    public IEnumerable<Tag> CreateMetaInfo(object obj) {
+      Array a = (Array)obj;
+      int[] lengths = new int[a.Rank];
+      int[] lowerBounds = new int[a.Rank];
+      StringBuilder sb = new StringBuilder();
+      sb.Append(a.Rank).Append(';');
+      for (int i = 0; i < a.Rank; i++) {
+        sb.Append(a.GetLength(i)).Append(';');
+        lengths[i] = a.GetLength(i);
+      }
+      for (int i = 0; i < a.Rank; i++) {
+        sb.Append(a.GetLowerBound(i)).Append(';');
+        lowerBounds[i] = a.GetLowerBound(i);
+      }
+      int[] positions = (int[])lowerBounds.Clone();
+      while (positions[a.Rank - 1] < lengths[a.Rank - 1] + lowerBounds[a.Rank - 1]) {
+        sb.Append(numberConverter.Format(a.GetValue(positions))).Append(';');
+        positions[0] += 1;
+        for (int i = 0; i < a.Rank - 1; i++) {
+          if (positions[i] >= lengths[i] + lowerBounds[i]) {
+            positions[i] = lowerBounds[i];
+            positions[i + 1] += 1;
+          } else {
+            break;
+          }
+        }
+      }
+      yield return new Tag("compact array", sb.ToString());
+    }
+
+    public IEnumerable<Tag> Decompose(object obj) {
+      return new Tag[] { };
+    }
+
+    public object CreateInstance(Type type, IEnumerable<Tag> metaInfo) {
+      var tagIter = metaInfo.GetEnumerator();
+      tagIter.MoveNext();
+      var valueIter = ((string)tagIter.Current.Value)
+        .Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
+        .GetEnumerator();
+      valueIter.MoveNext();
+      int rank = int.Parse((string)valueIter.Current);
+      int[] lengths = new int[rank];
+      int[] lowerBounds = new int[rank];
+      for (int i = 0; i < rank; i++) {
+        valueIter.MoveNext();
+        lengths[i] = int.Parse((string)valueIter.Current);
+      }
+      for (int i = 0; i < rank; i++) {
+        valueIter.MoveNext();
+        lowerBounds[i] = int.Parse((string)valueIter.Current);
+      }
+      Type elementType = type.GetElementType();
+      Array a = Array.CreateInstance(elementType, lengths, lowerBounds);
+      int[] positions = (int[])lowerBounds.Clone();
+      while (valueIter.MoveNext()) {
+        a.SetValue(
+          numberConverter.Parse((string)valueIter.Current, elementType),
+          positions);
+        positions[0] += 1;
+        for (int i = 0; i < rank - 1; i++) {
+          if (positions[i] >= lengths[i] + lowerBounds[i]) {
+            positions[i + 1] += 1;
+            positions[i] = lowerBounds[i];
+          } else {
+            break;
+          }
+        }
+      }
+      return a;
+    }
+
+    public void Populate(object instance, IEnumerable<Tag> tags, Type type) {
+    }
+
+  }
+
+}
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/Decomposers/Number2StringConverter.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/Decomposers/Number2StringConverter.cs	(revision 1567)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/Decomposers/Number2StringConverter.cs	(revision 1567)
@@ -0,0 +1,63 @@
+﻿using System;
+using HeuristicLab.Persistence.Interfaces;
+using HeuristicLab.Persistence.Core;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Globalization;
+using System.Text;
+
+namespace HeuristicLab.Persistence.Default.Decomposers {
+
+  public class Number2StringConverter {
+
+    private static readonly List<Type> numberTypes =
+      new List<Type> {
+        typeof(bool),
+        typeof(byte),
+        typeof(sbyte),
+        typeof(short),
+        typeof(ushort),
+        typeof(int),
+        typeof(uint),
+        typeof(long),
+        typeof(ulong),
+        typeof(float),
+        typeof(double),
+        typeof(decimal),
+      };
+
+    private static readonly Dictionary<Type, MethodInfo> numberParsers;
+
+    static Number2StringConverter() {
+      numberParsers = new Dictionary<Type, MethodInfo>();
+      foreach (var type in numberTypes) {
+        numberParsers[type] = type
+          .GetMethod("Parse", BindingFlags.Static | BindingFlags.Public,
+                     null, new[] { typeof(string) }, null);
+      }
+    }
+
+    public bool CanDecompose(Type type) {
+      return numberParsers.ContainsKey(type);
+    }
+
+    public string Format(object obj) {
+      if (obj.GetType() == typeof(float))
+        return ((float)obj).ToString("r", CultureInfo.InvariantCulture);
+      if (obj.GetType() == typeof(double))
+        return ((double)obj).ToString("r", CultureInfo.InvariantCulture);
+      if (obj.GetType() == typeof(decimal))
+        return ((decimal)obj).ToString("r", CultureInfo.InvariantCulture);
+      return obj.ToString();
+    }
+
+    public object Parse(string stringValue, Type type) {
+      return numberParsers[type]
+        .Invoke(null,
+            BindingFlags.Static | BindingFlags.PutRefDispProperty,
+                  null, new[] { stringValue }, CultureInfo.InvariantCulture);
+    }
+
+  }
+
+}
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/Decomposers/NumberEnumerable2StringDecomposer.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/Decomposers/NumberEnumerable2StringDecomposer.cs	(revision 1567)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/Decomposers/NumberEnumerable2StringDecomposer.cs	(revision 1567)
@@ -0,0 +1,101 @@
+﻿using System;
+using HeuristicLab.Persistence.Interfaces;
+using HeuristicLab.Persistence.Core;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Globalization;
+using System.Text;
+
+namespace HeuristicLab.Persistence.Default.Decomposers {
+
+  [EmptyStorableClass]
+  public class NumberEnumerable2StringDecomposer : IDecomposer {
+
+    public int Priority {
+      get { return 200; }
+    }
+
+    private static readonly Number2StringConverter numberConverter =
+      new Number2StringConverter();
+
+    private static readonly Dictionary<Type, Type> interfaceCache = new Dictionary<Type, Type>();
+
+    public Type GetGenericEnumerableInterface(Type type) {
+      if (interfaceCache.ContainsKey(type))
+        return interfaceCache[type];
+      foreach (Type iface in type.GetInterfaces()) {
+        if (iface.IsGenericType &&
+          iface.GetGenericTypeDefinition() == typeof(IEnumerable<>) &&
+          numberConverter.CanDecompose(iface.GetGenericArguments()[0])) {
+          interfaceCache.Add(type, iface);
+          return iface;
+        }
+      }
+      interfaceCache.Add(type, null);
+      return null;
+    }
+
+    public bool ImplementsGenericEnumerable(Type type) {
+      return GetGenericEnumerableInterface(type) != null;
+    }
+
+    public bool HasAddMethod(Type type) {
+      return
+        type.GetMethod("Add") != null &&
+        type.GetMethod("Add").GetParameters().Length == 1 &&
+        type.GetConstructor(
+          BindingFlags.Public |
+          BindingFlags.NonPublic |
+          BindingFlags.Instance,
+          null, Type.EmptyTypes, null) != null;
+    }
+
+    public bool CanDecompose(Type type) {
+      return
+        ImplementsGenericEnumerable(type) &&
+        HasAddMethod(type);
+    }
+
+    public IEnumerable<Tag> CreateMetaInfo(object o) {
+      return new Tag[] { };
+    }
+
+    public IEnumerable<Tag> Decompose(object obj) {
+      Type type = obj.GetType();
+      Type enumerable = GetGenericEnumerableInterface(type);
+      InterfaceMapping iMap = obj.GetType().GetInterfaceMap(enumerable);
+      MethodInfo getEnumeratorMethod =
+        iMap.TargetMethods[
+        Array.IndexOf(
+          iMap.InterfaceMethods,
+          enumerable.GetMethod("GetEnumerator"))];
+      object[] empty = new object[] { };
+      object genericEnumerator = getEnumeratorMethod.Invoke(obj, empty);
+      MethodInfo moveNextMethod = genericEnumerator.GetType().GetMethod("MoveNext");
+      PropertyInfo currentProperty = genericEnumerator.GetType().GetProperty("Current");
+      StringBuilder sb = new StringBuilder();
+      while ((bool)moveNextMethod.Invoke(genericEnumerator, empty))
+        sb.Append(
+          numberConverter.Format(
+            currentProperty.GetValue(genericEnumerator, null))).Append(';');
+      yield return new Tag("compact enumerable", sb.ToString());
+    }
+
+    public object CreateInstance(Type type, IEnumerable<Tag> metaInfo) {
+      return Activator.CreateInstance(type, true);
+    }
+
+    public void Populate(object instance, IEnumerable<Tag> tags, Type type) {
+      Type enumerable = GetGenericEnumerableInterface(type);
+      Type elementType = enumerable.GetGenericArguments()[0];
+      MethodInfo addMethod = type.GetMethod("Add");
+      var tagEnumerator = tags.GetEnumerator();
+      tagEnumerator.MoveNext();
+      string[] stringValues = ((string)tagEnumerator.Current.Value)
+        .Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
+      foreach (var value in stringValues) {
+        addMethod.Invoke(instance, new[] { numberConverter.Parse(value, elementType) });
+      }
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Persistence/3.3/HeuristicLab.Persistence-3.3.csproj
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/HeuristicLab.Persistence-3.3.csproj	(revision 1566)
+++ trunk/sources/HeuristicLab.Persistence/3.3/HeuristicLab.Persistence-3.3.csproj	(revision 1567)
@@ -101,5 +101,18 @@
     <Compile Include="Core\TypeStringBuilder.cs" />
     <Compile Include="Core\GeneratorBase.cs" />
+    <Compile Include="Default\DebugString\DebugString.cs" />
+    <Compile Include="Default\DebugString\DebugStringFormat.cs" />
+    <Compile Include="Default\DebugString\ValueType2DebugStringFormatterBase.cs" />
+    <Compile Include="Default\DebugString\String2DebugStringFormatter.cs" />
+    <Compile Include="Default\DebugString\Bool2DebugStringFormatter.cs" />
+    <Compile Include="Default\DebugString\Int2DebugStringFormatter.cs" />
+    <Compile Include="Default\DebugString\Doubld2DebugStringFormatter.cs" />
+    <Compile Include="Default\DebugString\DateTime2DebugStringFormatter.cs" />
+    <Compile Include="Default\DebugString\Type2DebugStringFormatter.cs" />
+    <Compile Include="Default\DebugString\Float2DebugStringFormatter.cs" />
+    <Compile Include="Default\DebugString\DebugStringGenerator.cs" />
     <Compile Include="Default\Decomposers\ArrayDecomposer.cs" />
+    <Compile Include="Default\Decomposers\Number2StringConverter.cs" />
+    <Compile Include="Default\Decomposers\CompactNumberArray2StringDecomposer.cs" />
     <Compile Include="Default\Decomposers\EnumerableDecomposer.cs" />
     <Compile Include="Default\Decomposers\EnumDecomposer.cs" />
@@ -108,8 +121,5 @@
     <Compile Include="Default\Decomposers\StorableDecomposer.cs" />
     <Compile Include="Default\Decomposers\TypeDecomposer.cs" />
-    <Compile Include="Default\Decomposers\X2StringDecomposer.cs" />
-    <Compile Include="Default\ViewOnly\ViewOnlyFormat.cs">
-      <SubType>Code</SubType>
-    </Compile>
+    <Compile Include="Default\Decomposers\NumberEnumerable2StringDecomposer.cs" />
     <Compile Include="Default\Xml\Compact\IntArray2XmlFormatters.cs" />
     <Compile Include="Default\Xml\Compact\DoubleArray2XmlFormatters.cs" />
