Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/CompactNumberArray2StringSerializer.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/CompactNumberArray2StringSerializer.cs	(revision 4068)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/CompactNumberArray2StringSerializer.cs	(revision 4132)
@@ -21,4 +21,5 @@
 
 using System;
+using System.Collections;
 using System.Collections.Generic;
 using System.Text;
@@ -32,4 +33,51 @@
   [StorableClass]
   public sealed class CompactNumberArray2StringSerializer : ICompositeSerializer {
+
+    private class ElementEnumerator : IEnumerator<string> {
+
+      private IEnumerator<Tag> tagIt;
+      private IEnumerator<string> valIt;
+
+      public ElementEnumerator(IEnumerable<Tag> tags) {
+        tagIt = tags.GetEnumerator();
+      }
+
+      public string Current {
+        get {
+          if (valIt == null)
+            throw new InvalidOperationException("no current value");
+          return valIt.Current;
+        }
+      }
+
+      public void Dispose() {
+        valIt.Dispose();
+        valIt = null;
+        tagIt.Dispose();
+      }
+
+      object IEnumerator.Current {
+        get { return this.Current; }
+      }
+
+      public bool MoveNext() {
+        if (valIt != null && valIt.MoveNext())
+          return true;
+        if (tagIt.MoveNext()) {
+          if (valIt != null)
+            valIt.Dispose();
+          valIt = ((string)tagIt.Current.Value).GetSplitEnumerator(';');
+          return MoveNext();
+        }
+        valIt.Dispose();
+        valIt = null;
+        return false;
+      }
+
+      public void Reset() {
+        valIt.Dispose();
+        tagIt.Reset();
+      }
+    }
 
     public const int SPLIT_THRESHOLD = 1024 * 1024;
@@ -69,5 +117,4 @@
         lowerBounds[i] = a.GetLowerBound(i);
       }
-      yield return new Tag(sb.ToString());
       int nElements = 1;
       for (int i = 0; i < a.Rank; i++) {
@@ -76,5 +123,5 @@
         nElements *= lengths[i];
       }
-      sb = new StringBuilder(Math.Min(nElements * 3, SPLIT_THRESHOLD));
+      sb.Capacity += Math.Min(nElements * 3, SPLIT_THRESHOLD);
       int[] positions = (int[])lowerBounds.Clone();
       while (positions[a.Rank - 1] < lengths[a.Rank - 1] + lowerBounds[a.Rank - 1]) {
@@ -105,7 +152,5 @@
     public object CreateInstance(Type type, IEnumerable<Tag> metaInfo) {
       try {
-        var tagIter = metaInfo.GetEnumerator();
-        tagIter.MoveNext();
-        var valueIter = ((string)tagIter.Current.Value).GetSplitEnumerator(';');
+        var valueIter = new ElementEnumerator(metaInfo);
         valueIter.MoveNext();
         int rank = int.Parse(valueIter.Current);
@@ -124,25 +169,21 @@
         if (a == null) throw new PersistenceException("invalid instance data type, expected array");
         int[] positions = (int[])lowerBounds.Clone();
-        while (tagIter.MoveNext()) {
-          valueIter = ((string)tagIter.Current.Value).GetSplitEnumerator(';');
-          while (valueIter.MoveNext()) {
-            a.SetValue(numberConverter.Parse(valueIter.Current, elementType), positions);
-            positions[0] += 1;
-            for (int i = 0; i < a.Rank - 1; i++) {
-              if (positions[i] >= lengths[i] + lowerBounds[i]) {
-                positions[i + 1] += 1;
-                positions[i] = lowerBounds[i];
-              } else {
-                break;
-              }
+
+        while (valueIter.MoveNext()) {
+          a.SetValue(numberConverter.Parse(valueIter.Current, elementType), positions);
+          positions[0] += 1;
+          for (int i = 0; i < a.Rank - 1; i++) {
+            if (positions[i] >= lengths[i] + lowerBounds[i]) {
+              positions[i + 1] += 1;
+              positions[i] = lowerBounds[i];
+            } else {
+              break;
             }
           }
         }
         return a;
-      }
-      catch (InvalidOperationException e) {
+      } catch (InvalidOperationException e) {
         throw new PersistenceException("Insuffictient data to deserialize compact array", e);
-      }
-      catch (InvalidCastException e) {
+      } catch (InvalidCastException e) {
         throw new PersistenceException("Invalid element data during compact array deserialization", e);
       }
