Index: /trunk/sources/HeuristicLab.Persistence.Test/NewSerializationTest.cs
===================================================================
--- /trunk/sources/HeuristicLab.Persistence.Test/NewSerializationTest.cs	(revision 1517)
+++ /trunk/sources/HeuristicLab.Persistence.Test/NewSerializationTest.cs	(revision 1518)
@@ -243,10 +243,13 @@
     }
 
-    public class Base {
-      [Storable] private int baseInt = 3;      
-    }
-
-    public class Derived: Base {
-      [Storable] private int derivedInt = 5;
+    public static void Test6() {
+      string[,] mDimString = new string[,] {
+        {"ora", "et", "labora"},
+        {"Beten", "und", "Arbeiten"}
+      };
+      XmlGenerator.Serialize(mDimString, "test6.zip");
+      object o = XmlParser.DeSerialize("test6.zip");
+      Console.WriteLine(ViewOnlyGenerator.Serialize(mDimString));
+      Console.WriteLine(ViewOnlyGenerator.Serialize(o));
     }
 
@@ -259,4 +262,5 @@
       Test4();
       Test5();
+      Test6();
       //SpeedTest();
       //SpeedTest2();
Index: /trunk/sources/HeuristicLab.Persistence/Default/Decomposers/ArrayDecomposer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Persistence/Default/Decomposers/ArrayDecomposer.cs	(revision 1517)
+++ /trunk/sources/HeuristicLab.Persistence/Default/Decomposers/ArrayDecomposer.cs	(revision 1518)
@@ -15,12 +15,26 @@
       Array a = (Array)array;      
       yield return new Tag("rank", a.Rank);
+      int[] lengths = new int[a.Rank];
+      int[] lowerBounds = new int[a.Rank];
       for (int i = 0; i < a.Rank; i++) {
+        lengths[i] = a.GetLength(i);
         yield return new Tag("length_" + i, a.GetLength(i));
       }
       for (int i = 0; i < a.Rank; i++) {
+        lowerBounds[i] = a.GetLowerBound(i);
         yield return new Tag("lowerBound_" + i, a.GetLowerBound(i));
       }
-      foreach (object o in (Array)array) {
-        yield return new Tag(null, o);
+      int[] positions = (int[])lowerBounds.Clone();
+      while (positions[a.Rank - 1] < lengths[a.Rank - 1] + lowerBounds[a.Rank - 1]) {
+        yield return new Tag(a.GetValue(positions));
+        positions[0] += 1;
+        for (int i = 0; i < a.Rank - 1; i++) {
+          if (positions[i] >= lowerBounds[i] + lengths[i]) {
+            positions[i] = lowerBounds[i];
+            positions[i + 1] += 1;
+          } else {
+            break;
+          }
+        }
       }
     }
Index: /trunk/sources/HeuristicLab.Persistence/Default/Decomposers/X2StringDecomposer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Persistence/Default/Decomposers/X2StringDecomposer.cs	(revision 1517)
+++ /trunk/sources/HeuristicLab.Persistence/Default/Decomposers/X2StringDecomposer.cs	(revision 1518)
@@ -111,12 +111,28 @@
     public IEnumerable<Tag> DeCompose(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.Rank).Append(';');
+      for (int i = 0; i < a.Rank; i++) {
         sb.Append(a.GetLength(i)).Append(';');
-      for ( int i = 0; i<a.Rank; i++)
+        lengths[i] = a.GetLength(i);
+      }
+      for (int i = 0; i < a.Rank; i++) {
         sb.Append(a.GetLowerBound(i)).Append(';');
-      foreach (var number in a) {        
-        sb.Append(numberDecomposer.Format(number)).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(numberDecomposer.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());
Index: /trunk/sources/HeuristicLab.Persistence/Default/Xml/Compact/NumberArray2XmlFormatters.cs
===================================================================
--- /trunk/sources/HeuristicLab.Persistence/Default/Xml/Compact/NumberArray2XmlFormatters.cs	(revision 1517)
+++ /trunk/sources/HeuristicLab.Persistence/Default/Xml/Compact/NumberArray2XmlFormatters.cs	(revision 1518)
@@ -3,4 +3,5 @@
 using HeuristicLab.Persistence.Interfaces;
 using System;
+using HeuristicLab.Persistence.Default.ViewOnly;
 
 namespace HeuristicLab.Persistence.Default.Xml.Compact {
@@ -16,4 +17,6 @@
     public object DoFormat(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);
@@ -21,13 +24,26 @@
         sb.Append(Separator);
         sb.Append(a.GetLength(i));
+        lengths[i] = a.GetLength(i);
       }
       for (int i = 0; i < a.Rank; i++) {
         sb.Append(Separator);
         sb.Append(a.GetLowerBound(i));
+        lowerBounds[i] = a.GetLowerBound(i);
       }
-      foreach (object o in a) {
+      int[] positions = (int[])lowerBounds.Clone();
+      while (positions[a.Rank - 1] < lengths[a.Rank - 1] + lowerBounds[a.Rank - 1]) {
+        Console.WriteLine(ViewOnlyGenerator.Serialize(positions));
         sb.Append(Separator);
-        sb.Append(formatValue(o));
-      }
+        sb.Append(formatValue(a.GetValue(positions)));
+        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;
+          }
+        }
+      }      
       return sb.ToString();
     }
