diff --git a/base/source/java/ch/systemsx/cisd/base/mdarray/MDAbstractArray.java b/base/source/java/ch/systemsx/cisd/base/mdarray/MDAbstractArray.java
index a41c97dd6604cf5cc31a1cf8bc79c83d4aac0eb0..65f47010f9653f9337b4cb0c1316454349b6bf33 100644
--- a/base/source/java/ch/systemsx/cisd/base/mdarray/MDAbstractArray.java
+++ b/base/source/java/ch/systemsx/cisd/base/mdarray/MDAbstractArray.java
@@ -24,6 +24,9 @@ import org.apache.commons.lang.ClassUtils;
 /**
  * Base class of a multi-dimensional array. The <var>dimensions</var> of an array are provided
  * separately from the data as a <code>int[]</code>.
+ * <p>
+ * The array can grow or shrink in the first dimension (<var>dimensions[0]</var>). Dimensions
+ * <code>1...n</code> are static. They are said to form a <i>hyper-row</i>.
  * 
  * @author Bernd Rinn
  */
@@ -31,14 +34,44 @@ public abstract class MDAbstractArray<T> implements Serializable
 {
 
     private static final long serialVersionUID = 1L;
-    
+
     protected final int[] dimensions;
 
-    protected MDAbstractArray(int[] dimensions)
+    protected int hyperRowLength;
+
+    protected int capacityHyperRows;
+
+    protected MDAbstractArray(int[] dimensions, int arrayLength, int capacityHyperRows)
     {
         assert dimensions != null;
 
         this.dimensions = dimensions;
+        this.hyperRowLength = computeHyperRowLength(dimensions);
+        if (hyperRowLength == 0)
+        {
+            this.capacityHyperRows = 0;
+        } else
+        {
+            if (arrayLength % hyperRowLength != 0)
+            {
+                throw new IllegalArgumentException("Actual array length " + arrayLength
+                        + " does not match hyper-row length " + hyperRowLength + ".");
+            }
+            this.capacityHyperRows =
+                    (capacityHyperRows > 0) ? capacityHyperRows : Math.max(dimensions[0], arrayLength
+                            / hyperRowLength);
+        }
+    }
+
+    protected int computeHyperRowLength(@SuppressWarnings("hiding")
+    int[] dimensions)
+    {
+        int hyperRowLen = 1;
+        for (int i = 1; i < dimensions.length; ++i)
+        {
+            hyperRowLen *= dimensions[i];
+        }
+        return hyperRowLen;
     }
 
     /**
@@ -103,6 +136,35 @@ public abstract class MDAbstractArray<T> implements Serializable
      */
     public abstract Object getAsFlatArray();
 
+    /**
+     * Returns a copy of the array in flattened form. Changes to the returned object will <i>not</i>
+     * change the multi-dimensional array directly.
+     */
+    public abstract Object getCopyAsFlatArray();
+
+    protected abstract void adaptCapacityHyperRows();
+
+    /**
+     * Increase the number of hyper-rows by <var>count</var>. Doubles the capacity if needed.
+     */
+    public void incNumberOfHyperRows(int count)
+    {
+        dimensions[0] += count;
+        if (dimensions[0] > capacityHyperRows)
+        {
+            capacityHyperRows *= 2;
+            adaptCapacityHyperRows();
+        }
+    }
+
+    /**
+     * Decrease the number of hyper-rows by <var>count</var>.
+     */
+    public void decNumberOfHyperRows(int count)
+    {
+        dimensions[0] -= count;
+    }
+
     /**
      * Computes the linear index for the multi-dimensional <var>indices</var> provided.
      */
@@ -182,6 +244,18 @@ public abstract class MDAbstractArray<T> implements Serializable
      * @throws IllegalArgumentException If <var>dimensions</var> overflow the <code>int</code> type.
      */
     public static int getLength(final int[] dimensions)
+    {
+        return getLength(dimensions, 0);
+    }
+
+    /**
+     * Returns the one-dimensional length of the multi-dimensional array defined by
+     * <var>dimensions</var>. If <code>capacityHyperRows > dimensions[0]</code>, then it will
+     * replace <var>dimensions[0]</var> by <var>capacityHyperRows</var>
+     * 
+     * @throws IllegalArgumentException If <var>dimensions</var> overflow the <code>int</code> type.
+     */
+    public static int getLength(final int[] dimensions, int capacityHyperRows)
     {
         assert dimensions != null;
 
@@ -189,7 +263,7 @@ public abstract class MDAbstractArray<T> implements Serializable
         {
             return 0;
         }
-        long length = dimensions[0];
+        long length = Math.max(capacityHyperRows, dimensions[0]);
         for (int i = 1; i < dimensions.length; ++i)
         {
             length *= dimensions[i];
@@ -209,6 +283,18 @@ public abstract class MDAbstractArray<T> implements Serializable
      * @throws IllegalArgumentException If <var>dimensions</var> overflow the <code>int</code> type.
      */
     public static int getLength(final long[] dimensions)
+    {
+        return getLength(dimensions, 0);
+    }
+
+    /**
+     * Returns the one-dimensional length of the multi-dimensional array defined by
+     * <var>dimensions</var>. If <code>capacityHyperRows > dimensions[0]</code>, then it will
+     * replace <var>dimensions[0]</var> by <var>capacityHyperRows</var>
+     * 
+     * @throws IllegalArgumentException If <var>dimensions</var> overflow the <code>int</code> type.
+     */
+    public static int getLength(final long[] dimensions, long capacityHyperRows)
     {
         assert dimensions != null;
 
@@ -216,7 +302,7 @@ public abstract class MDAbstractArray<T> implements Serializable
         {
             return 0;
         }
-        long length = dimensions[0];
+        long length = Math.max(capacityHyperRows, dimensions[0]);
         for (int i = 1; i < dimensions.length; ++i)
         {
             length *= dimensions[i];
@@ -232,11 +318,11 @@ public abstract class MDAbstractArray<T> implements Serializable
     //
     // Object
     //
-    
+
     @Override
     public String toString()
     {
-        final int length = getLength(dimensions);
+        final int length = getLength(dimensions, 0);
         final StringBuilder b = new StringBuilder();
         b.append(ClassUtils.getShortCanonicalName(this.getClass()));
         b.append('(');
@@ -245,7 +331,13 @@ public abstract class MDAbstractArray<T> implements Serializable
         if (length <= 100)
         {
             b.append(": ");
-            b.append(ArrayUtils.toString(getAsFlatArray()));
+            if (dimensions[0] < capacityHyperRows)
+            {
+                b.append(ArrayUtils.toString(getCopyAsFlatArray()));
+            } else
+            {
+                b.append(ArrayUtils.toString(getAsFlatArray()));
+            }
         }
         return b.toString();
     }
diff --git a/base/source/java/ch/systemsx/cisd/base/mdarray/MDArray.java b/base/source/java/ch/systemsx/cisd/base/mdarray/MDArray.java
index c5649af2b87c5b0088f78a6f28f634d7482abf4d..5daa2fb8d91ebdfa2a2d89fd7c31da8b2276d240 100644
--- a/base/source/java/ch/systemsx/cisd/base/mdarray/MDArray.java
+++ b/base/source/java/ch/systemsx/cisd/base/mdarray/MDArray.java
@@ -16,8 +16,12 @@
 
 package ch.systemsx.cisd.base.mdarray;
 
+import java.io.IOException;
+import java.io.ObjectInputStream;
 import java.util.Arrays;
 
+import org.apache.commons.lang.ArrayUtils;
+
 /**
  * A multi-dimensional array of generic type <code>T</code>.
  * 
@@ -25,19 +29,29 @@ import java.util.Arrays;
  */
 public class MDArray<T> extends MDAbstractArray<T>
 {
-
     private static final long serialVersionUID = 1L;
 
-    private final T[] flattenedArray;
+    private T[] flattenedArray;
 
     /**
-     * Creates an empty {@link MDArray} with the given <var>componentClass</var> and
-     * <var>dimensions</var>. Convenience method if <var>dimensions</var> are available as {@code
-     * long[]}.
+     * Creates an empty {@link MDArray} with the <var>dimensions</var>. Convenience method if
+     * <var>dimensions</var> are available as {@code long[]}.
      */
     public MDArray(Class<T> componentClass, long[] dimensions)
     {
-        this(createArray(componentClass, getLength(dimensions)), toInt(dimensions), false);
+        this(createArray(componentClass, getLength(dimensions, 0)), toInt(dimensions), false);
+    }
+
+    /**
+     * Creates an empty {@link MDArray} with the <var>dimensions</var>. If
+     * <code>capacityHyperRows > dimensions[0]</code>, then it will create an array with a capacity
+     * of <var>capacityHyperRows</var> hyper-rows. Convenience method if <var>dimensions</var> are
+     * available as {@code long[]}.
+     */
+    public MDArray(Class<T> componentClass, long[] dimensions, long capacityHyperRows)
+    {
+        this(createArray(componentClass, getLength(dimensions, capacityHyperRows)),
+                toInt(dimensions), false);
     }
 
     /**
@@ -61,12 +75,22 @@ public class MDArray<T> extends MDAbstractArray<T>
     }
 
     /**
-     * Creates an empty {@link MDArray} with the given <var>componentClass</var> and
-     * <var>dimensions</var>.
+     * Creates an empty {@link MDArray} with the <var>dimensions</var>.
      */
     public MDArray(Class<T> componentClass, int[] dimensions)
     {
-        this(createArray(componentClass, getLength(dimensions)), dimensions, false);
+        this(createArray(componentClass, getLength(dimensions, 0)), dimensions, false);
+    }
+
+    /**
+     * Creates an empty {@link MDArray} with the <var>dimensions</var>. If
+     * <code>capacityHyperRows > dimensions[0]</code>, then it will create an array with a capacity
+     * of <var>capacityHyperRows</var> hyper-rows.
+     */
+    public MDArray(Class<T> componentClass, int[] dimensions, int capacityHyperRows)
+    {
+        this(createArray(componentClass, getLength(dimensions, capacityHyperRows)), dimensions,
+                false);
     }
 
     /**
@@ -85,12 +109,12 @@ public class MDArray<T> extends MDAbstractArray<T>
      */
     public MDArray(T[] flattenedArray, int[] dimensions, boolean checkdimensions)
     {
-        super(dimensions);
+        super(dimensions, flattenedArray.length, 0);
         assert flattenedArray != null;
 
         if (checkdimensions)
         {
-            final int expectedLength = getLength(dimensions);
+            final int expectedLength = getLength(dimensions, 0);
             if (flattenedArray.length != expectedLength)
             {
                 throw new IllegalArgumentException("Actual array length " + flattenedArray.length
@@ -107,6 +131,12 @@ public class MDArray<T> extends MDAbstractArray<T>
         return value;
     }
 
+    @Override
+    public int size()
+    {
+        return flattenedArray.length;
+    }
+
     @Override
     public T getAsObject(int... indices)
     {
@@ -116,23 +146,36 @@ public class MDArray<T> extends MDAbstractArray<T>
     @Override
     public void setToObject(T value, int... indices)
     {
-        set(indices, value);
+        set(value, indices);
     }
 
     @Override
-    public int size()
+    public T[] getAsFlatArray()
     {
-        return flattenedArray.length;
+        return flattenedArray;
     }
 
-    /**
-     * Returns the array in flattened form. Changes to the returned object will change the
-     * multi-dimensional array directly.
-     */
     @Override
-    public T[] getAsFlatArray()
+    public T[] getCopyAsFlatArray()
     {
-        return flattenedArray;
+        return toTArray(ArrayUtils.subarray(flattenedArray, 0, dimensions[0] * hyperRowLength));
+    }
+
+    @Override
+    protected void adaptCapacityHyperRows()
+    {
+        final T[] oldArray = this.flattenedArray;
+        this.flattenedArray =
+                toTArray(createArray(oldArray.getClass().getComponentType(), capacityHyperRows
+                        * hyperRowLength));
+        System.arraycopy(oldArray, 0, flattenedArray, 0,
+                Math.min(oldArray.length, flattenedArray.length));
+    }
+
+    @SuppressWarnings("unchecked")
+    private T[] toTArray(Object obj)
+    {
+        return (T[]) obj;
     }
 
     /**
@@ -178,7 +221,7 @@ public class MDArray<T> extends MDAbstractArray<T>
     /**
      * Sets the <var>value</var> of array at the position defined by <var>indices</var>.
      */
-    public void set(int[] indices, T value)
+    public void set(T value, int... indices)
     {
         flattenedArray[computeIndex(indices)] = value;
     }
@@ -234,7 +277,7 @@ public class MDArray<T> extends MDAbstractArray<T>
     {
         final int prime = 31;
         int result = 1;
-        result = prime * result + Arrays.hashCode(flattenedArray);
+        result = prime * result + Arrays.hashCode(getValuesAsFlatArray());
         result = prime * result + Arrays.hashCode(dimensions);
         return result;
     }
@@ -255,7 +298,7 @@ public class MDArray<T> extends MDAbstractArray<T>
             return false;
         }
         final MDArray<T> other = toMDArray(obj);
-        if (Arrays.equals(flattenedArray, other.flattenedArray) == false)
+        if (Arrays.equals(getValuesAsFlatArray(), other.getValuesAsFlatArray()) == false)
         {
             return false;
         }
@@ -266,10 +309,28 @@ public class MDArray<T> extends MDAbstractArray<T>
         return true;
     }
 
+    private T[] getValuesAsFlatArray()
+    {
+        return (dimensions[0] < capacityHyperRows) ? getCopyAsFlatArray() : getAsFlatArray(); 
+    }
+    
     @SuppressWarnings("unchecked")
     private MDArray<T> toMDArray(Object obj)
     {
         return (MDArray<T>) obj;
     }
 
+    private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException
+    {
+        stream.defaultReadObject();
+        if (hyperRowLength == 0)
+        {
+            this.hyperRowLength = computeHyperRowLength(dimensions);
+        }
+        if (capacityHyperRows == 0)
+        {
+            this.capacityHyperRows = dimensions[0];
+        }
+    }
+
 }
diff --git a/base/source/java/ch/systemsx/cisd/base/mdarray/MDByteArray.java b/base/source/java/ch/systemsx/cisd/base/mdarray/MDByteArray.java
index b216d269d3a2bcb558c731a970c4a9931a109641..0a74be19af6573cafed024f71c22b62fb1e0c3e6 100644
--- a/base/source/java/ch/systemsx/cisd/base/mdarray/MDByteArray.java
+++ b/base/source/java/ch/systemsx/cisd/base/mdarray/MDByteArray.java
@@ -16,8 +16,12 @@
 
 package ch.systemsx.cisd.base.mdarray;
 
+import java.io.IOException;
+import java.io.ObjectInputStream;
 import java.util.Arrays;
 
+import org.apache.commons.lang.ArrayUtils;
+
 /**
  * A multi-dimensional <code>byte</code> array.
  * 
@@ -26,22 +30,33 @@ import java.util.Arrays;
 public final class MDByteArray extends MDAbstractArray<Byte>
 {
     private static final long serialVersionUID = 1L;
-    
-    private final byte[] flattenedArray;
+
+    private byte[] flattenedArray;
 
     /**
-     * Creates an empty {@link MDByteArray} with the <var>dimensions</var>. Convenience method if
+     * Creates an empty {@link MDIntArray} with the <var>dimensions</var>. Convenience method if
      * <var>dimensions</var> are available as {@code long[]}.
      */
     public MDByteArray(long[] dimensions)
     {
-        this(new byte[getLength(dimensions)], toInt(dimensions), false);
+        this(new byte[getLength(dimensions, 0)], toInt(dimensions), false);
     }
 
     /**
-     * Creates a {@link MDByteArray} from the given {@code flattenedArray} and {@code dimensions}.
-     * It is checked that the arguments are compatible. Convenience method if <var>dimensions</var>
-     * are available as {@code long[]}.
+     * Creates an empty {@link MDByteArray} with the <var>dimensions</var>. If
+     * <code>capacityHyperRows > dimensions[0]</code>, then it will create an array with a capacity
+     * of <var>capacityHyperRows</var> hyper-rows. Convenience method if <var>dimensions</var> are
+     * available as {@code long[]}.
+     */
+    public MDByteArray(long[] dimensions, long capacityHyperRows)
+    {
+        this(new byte[getLength(dimensions, capacityHyperRows)], toInt(dimensions), false);
+    }
+
+    /**
+     * Creates a {@link MDByteArray} from the given {@code flattenedArray} and {@code dimensions}. It
+     * is checked that the arguments are compatible. Convenience method if <var>dimensions</var> are
+     * available as {@code long[]}.
      */
     public MDByteArray(byte[] flattenedArray, long[] dimensions)
     {
@@ -64,12 +79,22 @@ public final class MDByteArray extends MDAbstractArray<Byte>
      */
     public MDByteArray(int[] dimensions)
     {
-        this(new byte[getLength(dimensions)], dimensions, false);
+        this(new byte[getLength(dimensions, 0)], dimensions, false);
+    }
+
+    /**
+     * Creates an empty {@link MDByteArray} with the <var>dimensions</var>. If
+     * <code>capacityHyperRows > dimensions[0]</code>, then it will create an array with a capacity
+     * of <var>capacityHyperRows</var> hyper-rows.
+     */
+    public MDByteArray(int[] dimensions, int capacityHyperRows)
+    {
+        this(new byte[getLength(dimensions, capacityHyperRows)], dimensions, false);
     }
 
     /**
-     * Creates a {@link MDByteArray} from the given {@code flattenedArray} and {@code dimensions}.
-     * It is checked that the arguments are compatible.
+     * Creates a {@link MDByteArray} from the given {@code flattenedArray} and {@code dimensions}. It
+     * is checked that the arguments are compatible.
      */
     public MDByteArray(byte[] flattenedArray, int[] dimensions)
     {
@@ -83,12 +108,12 @@ public final class MDByteArray extends MDAbstractArray<Byte>
      */
     public MDByteArray(byte[] flattenedArray, int[] dimensions, boolean checkdimensions)
     {
-        super(dimensions);
+        super(dimensions, flattenedArray.length, 0);
         assert flattenedArray != null;
 
         if (checkdimensions)
         {
-            final int expectedLength = getLength(dimensions);
+            final int expectedLength = getLength(dimensions, 0);
             if (flattenedArray.length != expectedLength)
             {
                 throw new IllegalArgumentException("Actual array length " + flattenedArray.length
@@ -99,8 +124,8 @@ public final class MDByteArray extends MDAbstractArray<Byte>
     }
 
     /**
-     * Creates a {@link MDByteArray} from the given <var>matrix</var> of rank 2. Note that the
-     * values in <var>matrix</var> will be copied and thus the created {@link MDByteArray} will be
+     * Creates a {@link MDByteArray} from the given <var>matrix</var> of rank 2. Note that the values
+     * in <var>matrix</var> will be copied and thus the created {@link MDIntArray} will be
      * independent from <var>matrix</var> after construction.
      */
     public MDByteArray(byte[][] matrix)
@@ -111,20 +136,16 @@ public final class MDByteArray extends MDAbstractArray<Byte>
     /**
      * Creates a {@link MDByteArray} from the given <var>matrix</var> of rank 2 and the
      * <var>dimension</var> which need to be less or equal the dimensions of <var>matrix</var>. Note
-     * that the values in <var>matrix</var> will be copied and thus the created
-     * {@link MDByteArray} will be independent from <var>matrix</var> after construction.
+     * that the values in <var>matrix</var> will be copied and thus the created {@link MDIntArray}
+     * will be independent from <var>matrix</var> after construction.
      */
     public MDByteArray(byte[][] matrix, int[] dimensions)
     {
-        super(dimensions);
+        super(dimensions, 0, matrix.length);
 
         final int sizeX = dimensions[0];
         final int sizeY = dimensions[1];
-        int size = 1;
-        for (int i = 0; i < dimensions.length; ++i)
-        {
-            size *= dimensions[i];
-        }
+        int size = getLength(dimensions, 0);
         this.flattenedArray = new byte[size];
         for (int i = 0; i < sizeX; ++i)
         {
@@ -158,16 +179,27 @@ public final class MDByteArray extends MDAbstractArray<Byte>
         set(value, indices);
     }
 
-    /**
-     * Returns the array in flattened form. Changes to the returned object will change the
-     * multi-dimensional array directly.
-     */
     @Override
     public byte[] getAsFlatArray()
     {
         return flattenedArray;
     }
 
+    @Override
+    public byte[] getCopyAsFlatArray()
+    {
+        return ArrayUtils.subarray(flattenedArray, 0, dimensions[0] * hyperRowLength);
+    }
+
+    @Override
+    protected void adaptCapacityHyperRows()
+    {
+        final byte[] oldArray = this.flattenedArray;
+        this.flattenedArray = new byte[capacityHyperRows * hyperRowLength];
+        System.arraycopy(oldArray, 0, flattenedArray, 0,
+                Math.min(oldArray.length, flattenedArray.length));
+    }
+
     /**
      * Returns the value of array at the position defined by <var>indices</var>.
      */
@@ -275,7 +307,7 @@ public final class MDByteArray extends MDAbstractArray<Byte>
     {
         final int prime = 31;
         int result = 1;
-        result = prime * result + Arrays.hashCode(flattenedArray);
+        result = prime * result + Arrays.hashCode(getValuesAsFlatArray());
         result = prime * result + Arrays.hashCode(dimensions);
         return result;
     }
@@ -296,7 +328,7 @@ public final class MDByteArray extends MDAbstractArray<Byte>
             return false;
         }
         MDByteArray other = (MDByteArray) obj;
-        if (Arrays.equals(flattenedArray, other.flattenedArray) == false)
+        if (Arrays.equals(getValuesAsFlatArray(), other.getValuesAsFlatArray()) == false)
         {
             return false;
         }
@@ -307,4 +339,22 @@ public final class MDByteArray extends MDAbstractArray<Byte>
         return true;
     }
 
+    private byte[] getValuesAsFlatArray()
+    {
+        return (dimensions[0] < capacityHyperRows) ? getCopyAsFlatArray() : getAsFlatArray(); 
+    }
+    
+    private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException
+    {
+        stream.defaultReadObject();
+        if (hyperRowLength == 0)
+        {
+            this.hyperRowLength = computeHyperRowLength(dimensions);
+        }
+        if (capacityHyperRows == 0)
+        {
+            this.capacityHyperRows = dimensions[0];
+        }
+    }
+
 }
diff --git a/base/source/java/ch/systemsx/cisd/base/mdarray/MDDoubleArray.java b/base/source/java/ch/systemsx/cisd/base/mdarray/MDDoubleArray.java
index 606af1e20a7c1659f39c6b3409daef8bf182bc64..833f9eeb04a5e636bdba3bfd32dfcfd87d58e59d 100644
--- a/base/source/java/ch/systemsx/cisd/base/mdarray/MDDoubleArray.java
+++ b/base/source/java/ch/systemsx/cisd/base/mdarray/MDDoubleArray.java
@@ -16,8 +16,12 @@
 
 package ch.systemsx.cisd.base.mdarray;
 
+import java.io.IOException;
+import java.io.ObjectInputStream;
 import java.util.Arrays;
 
+import org.apache.commons.lang.ArrayUtils;
+
 /**
  * A multi-dimensional <code>double</code> array.
  * 
@@ -26,22 +30,33 @@ import java.util.Arrays;
 public final class MDDoubleArray extends MDAbstractArray<Double>
 {
     private static final long serialVersionUID = 1L;
-    
-    private final double[] flattenedArray;
+
+    private double[] flattenedArray;
 
     /**
-     * Creates an empty {@link MDDoubleArray} with the <var>dimensions</var>. Convenience method if
+     * Creates an empty {@link MDIntArray} with the <var>dimensions</var>. Convenience method if
      * <var>dimensions</var> are available as {@code long[]}.
      */
     public MDDoubleArray(long[] dimensions)
     {
-        this(new double[getLength(dimensions)], toInt(dimensions), false);
+        this(new double[getLength(dimensions, 0)], toInt(dimensions), false);
     }
 
     /**
-     * Creates a {@link MDDoubleArray} from the given {@code flattenedArray} and {@code dimensions}.
-     * It is checked that the arguments are compatible. Convenience method if <var>dimensions</var>
-     * are available as {@code long[]}.
+     * Creates an empty {@link MDDoubleArray} with the <var>dimensions</var>. If
+     * <code>capacityHyperRows > dimensions[0]</code>, then it will create an array with a capacity
+     * of <var>capacityHyperRows</var> hyper-rows. Convenience method if <var>dimensions</var> are
+     * available as {@code long[]}.
+     */
+    public MDDoubleArray(long[] dimensions, long capacityHyperRows)
+    {
+        this(new double[getLength(dimensions, capacityHyperRows)], toInt(dimensions), false);
+    }
+
+    /**
+     * Creates a {@link MDDoubleArray} from the given {@code flattenedArray} and {@code dimensions}. It
+     * is checked that the arguments are compatible. Convenience method if <var>dimensions</var> are
+     * available as {@code long[]}.
      */
     public MDDoubleArray(double[] flattenedArray, long[] dimensions)
     {
@@ -64,12 +79,22 @@ public final class MDDoubleArray extends MDAbstractArray<Double>
      */
     public MDDoubleArray(int[] dimensions)
     {
-        this(new double[getLength(dimensions)], dimensions, false);
+        this(new double[getLength(dimensions, 0)], dimensions, false);
+    }
+
+    /**
+     * Creates an empty {@link MDDoubleArray} with the <var>dimensions</var>. If
+     * <code>capacityHyperRows > dimensions[0]</code>, then it will create an array with a capacity
+     * of <var>capacityHyperRows</var> hyper-rows.
+     */
+    public MDDoubleArray(int[] dimensions, int capacityHyperRows)
+    {
+        this(new double[getLength(dimensions, capacityHyperRows)], dimensions, false);
     }
 
     /**
-     * Creates a {@link MDDoubleArray} from the given {@code flattenedArray} and {@code dimensions}.
-     * It is checked that the arguments are compatible.
+     * Creates a {@link MDDoubleArray} from the given {@code flattenedArray} and {@code dimensions}. It
+     * is checked that the arguments are compatible.
      */
     public MDDoubleArray(double[] flattenedArray, int[] dimensions)
     {
@@ -83,12 +108,12 @@ public final class MDDoubleArray extends MDAbstractArray<Double>
      */
     public MDDoubleArray(double[] flattenedArray, int[] dimensions, boolean checkdimensions)
     {
-        super(dimensions);
+        super(dimensions, flattenedArray.length, 0);
         assert flattenedArray != null;
 
         if (checkdimensions)
         {
-            final int expectedLength = getLength(dimensions);
+            final int expectedLength = getLength(dimensions, 0);
             if (flattenedArray.length != expectedLength)
             {
                 throw new IllegalArgumentException("Actual array length " + flattenedArray.length
@@ -99,8 +124,8 @@ public final class MDDoubleArray extends MDAbstractArray<Double>
     }
 
     /**
-     * Creates a {@link MDDoubleArray} from the given <var>matrix</var> of rank 2. Note that the
-     * values in <var>matrix</var> will be copied and thus the created {@link MDDoubleArray} will be
+     * Creates a {@link MDDoubleArray} from the given <var>matrix</var> of rank 2. Note that the values
+     * in <var>matrix</var> will be copied and thus the created {@link MDIntArray} will be
      * independent from <var>matrix</var> after construction.
      */
     public MDDoubleArray(double[][] matrix)
@@ -111,20 +136,16 @@ public final class MDDoubleArray extends MDAbstractArray<Double>
     /**
      * Creates a {@link MDDoubleArray} from the given <var>matrix</var> of rank 2 and the
      * <var>dimension</var> which need to be less or equal the dimensions of <var>matrix</var>. Note
-     * that the values in <var>matrix</var> will be copied and thus the created
-     * {@link MDDoubleArray} will be independent from <var>matrix</var> after construction.
+     * that the values in <var>matrix</var> will be copied and thus the created {@link MDIntArray}
+     * will be independent from <var>matrix</var> after construction.
      */
     public MDDoubleArray(double[][] matrix, int[] dimensions)
     {
-        super(dimensions);
+        super(dimensions, 0, matrix.length);
 
         final int sizeX = dimensions[0];
         final int sizeY = dimensions[1];
-        int size = 1;
-        for (int i = 0; i < dimensions.length; ++i)
-        {
-            size *= dimensions[i];
-        }
+        int size = getLength(dimensions, 0);
         this.flattenedArray = new double[size];
         for (int i = 0; i < sizeX; ++i)
         {
@@ -158,16 +179,27 @@ public final class MDDoubleArray extends MDAbstractArray<Double>
         set(value, indices);
     }
 
-    /**
-     * Returns the array in flattened form. Changes to the returned object will change the
-     * multi-dimensional array directly.
-     */
     @Override
     public double[] getAsFlatArray()
     {
         return flattenedArray;
     }
 
+    @Override
+    public double[] getCopyAsFlatArray()
+    {
+        return ArrayUtils.subarray(flattenedArray, 0, dimensions[0] * hyperRowLength);
+    }
+
+    @Override
+    protected void adaptCapacityHyperRows()
+    {
+        final double[] oldArray = this.flattenedArray;
+        this.flattenedArray = new double[capacityHyperRows * hyperRowLength];
+        System.arraycopy(oldArray, 0, flattenedArray, 0,
+                Math.min(oldArray.length, flattenedArray.length));
+    }
+
     /**
      * Returns the value of array at the position defined by <var>indices</var>.
      */
@@ -275,7 +307,7 @@ public final class MDDoubleArray extends MDAbstractArray<Double>
     {
         final int prime = 31;
         int result = 1;
-        result = prime * result + Arrays.hashCode(flattenedArray);
+        result = prime * result + Arrays.hashCode(getValuesAsFlatArray());
         result = prime * result + Arrays.hashCode(dimensions);
         return result;
     }
@@ -296,7 +328,7 @@ public final class MDDoubleArray extends MDAbstractArray<Double>
             return false;
         }
         MDDoubleArray other = (MDDoubleArray) obj;
-        if (Arrays.equals(flattenedArray, other.flattenedArray) == false)
+        if (Arrays.equals(getValuesAsFlatArray(), other.getValuesAsFlatArray()) == false)
         {
             return false;
         }
@@ -307,4 +339,22 @@ public final class MDDoubleArray extends MDAbstractArray<Double>
         return true;
     }
 
+    private double[] getValuesAsFlatArray()
+    {
+        return (dimensions[0] < capacityHyperRows) ? getCopyAsFlatArray() : getAsFlatArray(); 
+    }
+    
+    private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException
+    {
+        stream.defaultReadObject();
+        if (hyperRowLength == 0)
+        {
+            this.hyperRowLength = computeHyperRowLength(dimensions);
+        }
+        if (capacityHyperRows == 0)
+        {
+            this.capacityHyperRows = dimensions[0];
+        }
+    }
+
 }
diff --git a/base/source/java/ch/systemsx/cisd/base/mdarray/MDFloatArray.java b/base/source/java/ch/systemsx/cisd/base/mdarray/MDFloatArray.java
index bf99f2ee5bb5d86eae74adcb4ed26bbaa07765ac..f7e28dbcf8fc572c0f41d45962901641ea72d684 100644
--- a/base/source/java/ch/systemsx/cisd/base/mdarray/MDFloatArray.java
+++ b/base/source/java/ch/systemsx/cisd/base/mdarray/MDFloatArray.java
@@ -16,8 +16,12 @@
 
 package ch.systemsx.cisd.base.mdarray;
 
+import java.io.IOException;
+import java.io.ObjectInputStream;
 import java.util.Arrays;
 
+import org.apache.commons.lang.ArrayUtils;
+
 /**
  * A multi-dimensional <code>float</code> array.
  * 
@@ -26,22 +30,33 @@ import java.util.Arrays;
 public final class MDFloatArray extends MDAbstractArray<Float>
 {
     private static final long serialVersionUID = 1L;
-    
-    private final float[] flattenedArray;
+
+    private float[] flattenedArray;
 
     /**
-     * Creates an empty {@link MDDoubleArray} with the <var>dimensions</var>. Convenience method if
+     * Creates an empty {@link MDIntArray} with the <var>dimensions</var>. Convenience method if
      * <var>dimensions</var> are available as {@code long[]}.
      */
     public MDFloatArray(long[] dimensions)
     {
-        this(new float[getLength(dimensions)], toInt(dimensions), false);
+        this(new float[getLength(dimensions, 0)], toInt(dimensions), false);
     }
 
     /**
-     * Creates a {@link MDDoubleArray} from the given {@code flattenedArray} and {@code dimensions}.
-     * It is checked that the arguments are compatible. Convenience method if <var>dimensions</var>
-     * are available as {@code long[]}.
+     * Creates an empty {@link MDFloatArray} with the <var>dimensions</var>. If
+     * <code>capacityHyperRows > dimensions[0]</code>, then it will create an array with a capacity
+     * of <var>capacityHyperRows</var> hyper-rows. Convenience method if <var>dimensions</var> are
+     * available as {@code long[]}.
+     */
+    public MDFloatArray(long[] dimensions, long capacityHyperRows)
+    {
+        this(new float[getLength(dimensions, capacityHyperRows)], toInt(dimensions), false);
+    }
+
+    /**
+     * Creates a {@link MDFloatArray} from the given {@code flattenedArray} and {@code dimensions}. It
+     * is checked that the arguments are compatible. Convenience method if <var>dimensions</var> are
+     * available as {@code long[]}.
      */
     public MDFloatArray(float[] flattenedArray, long[] dimensions)
     {
@@ -49,7 +64,7 @@ public final class MDFloatArray extends MDAbstractArray<Float>
     }
 
     /**
-     * Creates a {@link MDDoubleArray} from the given <var>flattenedArray</var> and
+     * Creates a {@link MDFloatArray} from the given <var>flattenedArray</var> and
      * <var>dimensions</var>. If <var>checkDimensions</var> is {@code true}, it is checked that the
      * arguments are compatible. Convenience method if <var>dimensions</var> are available as
      * {@code long[]}.
@@ -60,16 +75,26 @@ public final class MDFloatArray extends MDAbstractArray<Float>
     }
 
     /**
-     * Creates an empty {@link MDDoubleArray} with the <var>dimensions</var>.
+     * Creates an empty {@link MDFloatArray} with the <var>dimensions</var>.
      */
     public MDFloatArray(int[] dimensions)
     {
-        this(new float[getLength(dimensions)], dimensions, false);
+        this(new float[getLength(dimensions, 0)], dimensions, false);
+    }
+
+    /**
+     * Creates an empty {@link MDFloatArray} with the <var>dimensions</var>. If
+     * <code>capacityHyperRows > dimensions[0]</code>, then it will create an array with a capacity
+     * of <var>capacityHyperRows</var> hyper-rows.
+     */
+    public MDFloatArray(int[] dimensions, int capacityHyperRows)
+    {
+        this(new float[getLength(dimensions, capacityHyperRows)], dimensions, false);
     }
 
     /**
-     * Creates a {@link MDDoubleArray} from the given {@code flattenedArray} and {@code dimensions}.
-     * It is checked that the arguments are compatible.
+     * Creates a {@link MDFloatArray} from the given {@code flattenedArray} and {@code dimensions}. It
+     * is checked that the arguments are compatible.
      */
     public MDFloatArray(float[] flattenedArray, int[] dimensions)
     {
@@ -77,18 +102,18 @@ public final class MDFloatArray extends MDAbstractArray<Float>
     }
 
     /**
-     * Creates a {@link MDDoubleArray} from the given <var>flattenedArray</var> and
+     * Creates a {@link MDFloatArray} from the given <var>flattenedArray</var> and
      * <var>dimensions</var>. If <var>checkDimensions</var> is {@code true}, it is checked that the
      * arguments are compatible.
      */
     public MDFloatArray(float[] flattenedArray, int[] dimensions, boolean checkdimensions)
     {
-        super(dimensions);
+        super(dimensions, flattenedArray.length, 0);
         assert flattenedArray != null;
 
         if (checkdimensions)
         {
-            final int expectedLength = getLength(dimensions);
+            final int expectedLength = getLength(dimensions, 0);
             if (flattenedArray.length != expectedLength)
             {
                 throw new IllegalArgumentException("Actual array length " + flattenedArray.length
@@ -99,32 +124,28 @@ public final class MDFloatArray extends MDAbstractArray<Float>
     }
 
     /**
-     * Creates a {@link MDFloatArray} from the given <var>matrix</var> of rank 2. Note that the
-     * values in <var>matrix</var> will be copied and thus the created {@link MDFloatArray} will be
+     * Creates a {@link MDFloatArray} from the given <var>matrix</var> of rank 2. Note that the values
+     * in <var>matrix</var> will be copied and thus the created {@link MDIntArray} will be
      * independent from <var>matrix</var> after construction.
      */
     public MDFloatArray(float[][] matrix)
     {
         this(matrix, getDimensions(matrix));
     }
-    
+
     /**
      * Creates a {@link MDFloatArray} from the given <var>matrix</var> of rank 2 and the
      * <var>dimension</var> which need to be less or equal the dimensions of <var>matrix</var>. Note
-     * that the values in <var>matrix</var> will be copied and thus the created
-     * {@link MDFloatArray} will be independent from <var>matrix</var> after construction.
+     * that the values in <var>matrix</var> will be copied and thus the created {@link MDIntArray}
+     * will be independent from <var>matrix</var> after construction.
      */
     public MDFloatArray(float[][] matrix, int[] dimensions)
     {
-        super(dimensions);
+        super(dimensions, 0, matrix.length);
 
         final int sizeX = dimensions[0];
         final int sizeY = dimensions[1];
-        int size = 1;
-        for (int i = 0; i < dimensions.length; ++i)
-        {
-            size *= dimensions[i];
-        }
+        int size = getLength(dimensions, 0);
         this.flattenedArray = new float[size];
         for (int i = 0; i < sizeX; ++i)
         {
@@ -135,8 +156,9 @@ public final class MDFloatArray extends MDAbstractArray<Float>
     private static int[] getDimensions(float[][] matrix)
     {
         assert matrix != null;
-        
-        return new int[] { matrix.length, matrix.length == 0 ? 0 : matrix[0].length };
+
+        return new int[]
+            { matrix.length, matrix.length == 0 ? 0 : matrix[0].length };
     }
 
     @Override
@@ -157,16 +179,27 @@ public final class MDFloatArray extends MDAbstractArray<Float>
         set(value, indices);
     }
 
-    /**
-     * Returns the array in flattened form. Changes to the returned object will change the
-     * multi-dimensional array directly.
-     */
     @Override
     public float[] getAsFlatArray()
     {
         return flattenedArray;
     }
 
+    @Override
+    public float[] getCopyAsFlatArray()
+    {
+        return ArrayUtils.subarray(flattenedArray, 0, dimensions[0] * hyperRowLength);
+    }
+
+    @Override
+    protected void adaptCapacityHyperRows()
+    {
+        final float[] oldArray = this.flattenedArray;
+        this.flattenedArray = new float[capacityHyperRows * hyperRowLength];
+        System.arraycopy(oldArray, 0, flattenedArray, 0,
+                Math.min(oldArray.length, flattenedArray.length));
+    }
+
     /**
      * Returns the value of array at the position defined by <var>indices</var>.
      */
@@ -174,7 +207,7 @@ public final class MDFloatArray extends MDAbstractArray<Float>
     {
         return flattenedArray[computeIndex(indices)];
     }
-    
+
     /**
      * Returns the value of a one-dimensional array at the position defined by <var>index</var>.
      * <p>
@@ -264,17 +297,17 @@ public final class MDFloatArray extends MDAbstractArray<Float>
         }
         return result;
     }
-    
+
     //
     // Object
     //
-    
+
     @Override
     public int hashCode()
     {
         final int prime = 31;
         int result = 1;
-        result = prime * result + Arrays.hashCode(flattenedArray);
+        result = prime * result + Arrays.hashCode(getValuesAsFlatArray());
         result = prime * result + Arrays.hashCode(dimensions);
         return result;
     }
@@ -295,7 +328,7 @@ public final class MDFloatArray extends MDAbstractArray<Float>
             return false;
         }
         MDFloatArray other = (MDFloatArray) obj;
-        if (Arrays.equals(flattenedArray, other.flattenedArray) == false)
+        if (Arrays.equals(getValuesAsFlatArray(), other.getValuesAsFlatArray()) == false)
         {
             return false;
         }
@@ -306,4 +339,22 @@ public final class MDFloatArray extends MDAbstractArray<Float>
         return true;
     }
 
+    private float[] getValuesAsFlatArray()
+    {
+        return (dimensions[0] < capacityHyperRows) ? getCopyAsFlatArray() : getAsFlatArray(); 
+    }
+    
+    private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException
+    {
+        stream.defaultReadObject();
+        if (hyperRowLength == 0)
+        {
+            this.hyperRowLength = computeHyperRowLength(dimensions);
+        }
+        if (capacityHyperRows == 0)
+        {
+            this.capacityHyperRows = dimensions[0];
+        }
+    }
+
 }
diff --git a/base/source/java/ch/systemsx/cisd/base/mdarray/MDIntArray.java b/base/source/java/ch/systemsx/cisd/base/mdarray/MDIntArray.java
index 4a1b929295cc1184c1baf7f47bd73c7c80c33844..77cb172a3702bbe74cb7d9780e9f767e4ba5cfce 100644
--- a/base/source/java/ch/systemsx/cisd/base/mdarray/MDIntArray.java
+++ b/base/source/java/ch/systemsx/cisd/base/mdarray/MDIntArray.java
@@ -16,8 +16,12 @@
 
 package ch.systemsx.cisd.base.mdarray;
 
+import java.io.IOException;
+import java.io.ObjectInputStream;
 import java.util.Arrays;
 
+import org.apache.commons.lang.ArrayUtils;
+
 /**
  * A multi-dimensional <code>int</code> array.
  * 
@@ -26,8 +30,8 @@ import java.util.Arrays;
 public final class MDIntArray extends MDAbstractArray<Integer>
 {
     private static final long serialVersionUID = 1L;
-    
-    private final int[] flattenedArray;
+
+    private int[] flattenedArray;
 
     /**
      * Creates an empty {@link MDIntArray} with the <var>dimensions</var>. Convenience method if
@@ -35,13 +39,24 @@ public final class MDIntArray extends MDAbstractArray<Integer>
      */
     public MDIntArray(long[] dimensions)
     {
-        this(new int[getLength(dimensions)], toInt(dimensions), false);
+        this(new int[getLength(dimensions, 0)], toInt(dimensions), false);
     }
 
     /**
-     * Creates a {@link MDIntArray} from the given {@code flattenedArray} and {@code dimensions}.
-     * It is checked that the arguments are compatible. Convenience method if <var>dimensions</var>
-     * are available as {@code long[]}.
+     * Creates an empty {@link MDIntArray} with the <var>dimensions</var>. If
+     * <code>capacityHyperRows > dimensions[0]</code>, then it will create an array with a capacity
+     * of <var>capacityHyperRows</var> hyper-rows. Convenience method if <var>dimensions</var> are
+     * available as {@code long[]}.
+     */
+    public MDIntArray(long[] dimensions, long capacityHyperRows)
+    {
+        this(new int[getLength(dimensions, capacityHyperRows)], toInt(dimensions), false);
+    }
+
+    /**
+     * Creates a {@link MDIntArray} from the given {@code flattenedArray} and {@code dimensions}. It
+     * is checked that the arguments are compatible. Convenience method if <var>dimensions</var> are
+     * available as {@code long[]}.
      */
     public MDIntArray(int[] flattenedArray, long[] dimensions)
     {
@@ -64,12 +79,22 @@ public final class MDIntArray extends MDAbstractArray<Integer>
      */
     public MDIntArray(int[] dimensions)
     {
-        this(new int[getLength(dimensions)], dimensions, false);
+        this(new int[getLength(dimensions, 0)], dimensions, false);
+    }
+
+    /**
+     * Creates an empty {@link MDIntArray} with the <var>dimensions</var>. If
+     * <code>capacityHyperRows > dimensions[0]</code>, then it will create an array with a capacity
+     * of <var>capacityHyperRows</var> hyper-rows.
+     */
+    public MDIntArray(int[] dimensions, int capacityHyperRows)
+    {
+        this(new int[getLength(dimensions, capacityHyperRows)], dimensions, false);
     }
 
     /**
-     * Creates a {@link MDIntArray} from the given {@code flattenedArray} and {@code dimensions}.
-     * It is checked that the arguments are compatible.
+     * Creates a {@link MDIntArray} from the given {@code flattenedArray} and {@code dimensions}. It
+     * is checked that the arguments are compatible.
      */
     public MDIntArray(int[] flattenedArray, int[] dimensions)
     {
@@ -83,12 +108,12 @@ public final class MDIntArray extends MDAbstractArray<Integer>
      */
     public MDIntArray(int[] flattenedArray, int[] dimensions, boolean checkdimensions)
     {
-        super(dimensions);
+        super(dimensions, flattenedArray.length, 0);
         assert flattenedArray != null;
 
         if (checkdimensions)
         {
-            final int expectedLength = getLength(dimensions);
+            final int expectedLength = getLength(dimensions, 0);
             if (flattenedArray.length != expectedLength)
             {
                 throw new IllegalArgumentException("Actual array length " + flattenedArray.length
@@ -99,32 +124,28 @@ public final class MDIntArray extends MDAbstractArray<Integer>
     }
 
     /**
-     * Creates a {@link MDIntArray} from the given <var>matrix</var> of rank 2. Note that the
-     * values in <var>matrix</var> will be copied and thus the created {@link MDIntArray} will be
+     * Creates a {@link MDIntArray} from the given <var>matrix</var> of rank 2. Note that the values
+     * in <var>matrix</var> will be copied and thus the created {@link MDIntArray} will be
      * independent from <var>matrix</var> after construction.
      */
     public MDIntArray(int[][] matrix)
     {
         this(matrix, getDimensions(matrix));
     }
-    
+
     /**
      * Creates a {@link MDIntArray} from the given <var>matrix</var> of rank 2 and the
      * <var>dimension</var> which need to be less or equal the dimensions of <var>matrix</var>. Note
-     * that the values in <var>matrix</var> will be copied and thus the created
-     * {@link MDIntArray} will be independent from <var>matrix</var> after construction.
+     * that the values in <var>matrix</var> will be copied and thus the created {@link MDIntArray}
+     * will be independent from <var>matrix</var> after construction.
      */
     public MDIntArray(int[][] matrix, int[] dimensions)
     {
-        super(dimensions);
+        super(dimensions, 0, matrix.length);
 
         final int sizeX = dimensions[0];
         final int sizeY = dimensions[1];
-        int size = 1;
-        for (int i = 0; i < dimensions.length; ++i)
-        {
-            size *= dimensions[i];
-        }
+        int size = getLength(dimensions, 0);
         this.flattenedArray = new int[size];
         for (int i = 0; i < sizeX; ++i)
         {
@@ -135,8 +156,9 @@ public final class MDIntArray extends MDAbstractArray<Integer>
     private static int[] getDimensions(int[][] matrix)
     {
         assert matrix != null;
-        
-        return new int[] { matrix.length, matrix.length == 0 ? 0 : matrix[0].length };
+
+        return new int[]
+            { matrix.length, matrix.length == 0 ? 0 : matrix[0].length };
     }
 
     @Override
@@ -157,16 +179,27 @@ public final class MDIntArray extends MDAbstractArray<Integer>
         set(value, indices);
     }
 
-    /**
-     * Returns the array in flattened form. Changes to the returned object will change the
-     * multi-dimensional array directly.
-     */
     @Override
     public int[] getAsFlatArray()
     {
         return flattenedArray;
     }
 
+    @Override
+    public int[] getCopyAsFlatArray()
+    {
+        return ArrayUtils.subarray(flattenedArray, 0, dimensions[0] * hyperRowLength);
+    }
+
+    @Override
+    protected void adaptCapacityHyperRows()
+    {
+        final int[] oldArray = this.flattenedArray;
+        this.flattenedArray = new int[capacityHyperRows * hyperRowLength];
+        System.arraycopy(oldArray, 0, flattenedArray, 0,
+                Math.min(oldArray.length, flattenedArray.length));
+    }
+
     /**
      * Returns the value of array at the position defined by <var>indices</var>.
      */
@@ -174,7 +207,7 @@ public final class MDIntArray extends MDAbstractArray<Integer>
     {
         return flattenedArray[computeIndex(indices)];
     }
-    
+
     /**
      * Returns the value of a one-dimensional array at the position defined by <var>index</var>.
      * <p>
@@ -264,17 +297,17 @@ public final class MDIntArray extends MDAbstractArray<Integer>
         }
         return result;
     }
-    
+
     //
     // Object
     //
-    
+
     @Override
     public int hashCode()
     {
         final int prime = 31;
         int result = 1;
-        result = prime * result + Arrays.hashCode(flattenedArray);
+        result = prime * result + Arrays.hashCode(getValuesAsFlatArray());
         result = prime * result + Arrays.hashCode(dimensions);
         return result;
     }
@@ -295,7 +328,7 @@ public final class MDIntArray extends MDAbstractArray<Integer>
             return false;
         }
         MDIntArray other = (MDIntArray) obj;
-        if (Arrays.equals(flattenedArray, other.flattenedArray) == false)
+        if (Arrays.equals(getValuesAsFlatArray(), other.getValuesAsFlatArray()) == false)
         {
             return false;
         }
@@ -306,4 +339,22 @@ public final class MDIntArray extends MDAbstractArray<Integer>
         return true;
     }
 
+    private int[] getValuesAsFlatArray()
+    {
+        return (dimensions[0] < capacityHyperRows) ? getCopyAsFlatArray() : getAsFlatArray(); 
+    }
+    
+    private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException
+    {
+        stream.defaultReadObject();
+        if (hyperRowLength == 0)
+        {
+            this.hyperRowLength = computeHyperRowLength(dimensions);
+        }
+        if (capacityHyperRows == 0)
+        {
+            this.capacityHyperRows = dimensions[0];
+        }
+    }
+
 }
diff --git a/base/source/java/ch/systemsx/cisd/base/mdarray/MDLongArray.java b/base/source/java/ch/systemsx/cisd/base/mdarray/MDLongArray.java
index 41e86440c6f0bb666b10f85edfebafb03943e4ef..0f100293eafc79e6eb59d26a9d076105f5caa625 100644
--- a/base/source/java/ch/systemsx/cisd/base/mdarray/MDLongArray.java
+++ b/base/source/java/ch/systemsx/cisd/base/mdarray/MDLongArray.java
@@ -16,8 +16,12 @@
 
 package ch.systemsx.cisd.base.mdarray;
 
+import java.io.IOException;
+import java.io.ObjectInputStream;
 import java.util.Arrays;
 
+import org.apache.commons.lang.ArrayUtils;
+
 /**
  * A multi-dimensional <code>long</code> array.
  * 
@@ -26,22 +30,33 @@ import java.util.Arrays;
 public final class MDLongArray extends MDAbstractArray<Long>
 {
     private static final long serialVersionUID = 1L;
-    
-    private final long[] flattenedArray;
+
+    private long[] flattenedArray;
 
     /**
-     * Creates an empty {@link MDLongArray} with the <var>dimensions</var>. Convenience method if
+     * Creates an empty {@link MDIntArray} with the <var>dimensions</var>. Convenience method if
      * <var>dimensions</var> are available as {@code long[]}.
      */
     public MDLongArray(long[] dimensions)
     {
-        this(new long[getLength(dimensions)], toInt(dimensions), false);
+        this(new long[getLength(dimensions, 0)], toInt(dimensions), false);
+    }
+
+    /**
+     * Creates an empty {@link MDLongArray} with the <var>dimensions</var>. If
+     * <code>capacityHyperRows > dimensions[0]</code>, then it will create an array with a capacity
+     * of <var>capacityHyperRows</var> hyper-rows. Convenience method if <var>dimensions</var> are
+     * available as {@code long[]}.
+     */
+    public MDLongArray(long[] dimensions, long capacityHyperRows)
+    {
+        this(new long[getLength(dimensions, capacityHyperRows)], toInt(dimensions), false);
     }
 
     /**
-     * Creates a {@link MDLongArray} from the given {@code flattenedArray} and {@code dimensions}.
-     * It is checked that the arguments are compatible. Convenience method if <var>dimensions</var>
-     * are available as {@code long[]}.
+     * Creates a {@link MDLongArray} from the given {@code flattenedArray} and {@code dimensions}. It
+     * is checked that the arguments are compatible. Convenience method if <var>dimensions</var> are
+     * available as {@code long[]}.
      */
     public MDLongArray(long[] flattenedArray, long[] dimensions)
     {
@@ -64,12 +79,22 @@ public final class MDLongArray extends MDAbstractArray<Long>
      */
     public MDLongArray(int[] dimensions)
     {
-        this(new long[getLength(dimensions)], dimensions, false);
+        this(new long[getLength(dimensions, 0)], dimensions, false);
+    }
+
+    /**
+     * Creates an empty {@link MDLongArray} with the <var>dimensions</var>. If
+     * <code>capacityHyperRows > dimensions[0]</code>, then it will create an array with a capacity
+     * of <var>capacityHyperRows</var> hyper-rows.
+     */
+    public MDLongArray(int[] dimensions, int capacityHyperRows)
+    {
+        this(new long[getLength(dimensions, capacityHyperRows)], dimensions, false);
     }
 
     /**
-     * Creates a {@link MDLongArray} from the given {@code flattenedArray} and {@code dimensions}.
-     * It is checked that the arguments are compatible.
+     * Creates a {@link MDLongArray} from the given {@code flattenedArray} and {@code dimensions}. It
+     * is checked that the arguments are compatible.
      */
     public MDLongArray(long[] flattenedArray, int[] dimensions)
     {
@@ -83,12 +108,12 @@ public final class MDLongArray extends MDAbstractArray<Long>
      */
     public MDLongArray(long[] flattenedArray, int[] dimensions, boolean checkdimensions)
     {
-        super(dimensions);
+        super(dimensions, flattenedArray.length, 0);
         assert flattenedArray != null;
 
         if (checkdimensions)
         {
-            final int expectedLength = getLength(dimensions);
+            final int expectedLength = getLength(dimensions, 0);
             if (flattenedArray.length != expectedLength)
             {
                 throw new IllegalArgumentException("Actual array length " + flattenedArray.length
@@ -99,32 +124,28 @@ public final class MDLongArray extends MDAbstractArray<Long>
     }
 
     /**
-     * Creates a {@link MDLongArray} from the given <var>matrix</var> of rank 2. Note that the
-     * values in <var>matrix</var> will be copied and thus the created {@link MDLongArray} will be
+     * Creates a {@link MDLongArray} from the given <var>matrix</var> of rank 2. Note that the values
+     * in <var>matrix</var> will be copied and thus the created {@link MDIntArray} will be
      * independent from <var>matrix</var> after construction.
      */
     public MDLongArray(long[][] matrix)
     {
         this(matrix, getDimensions(matrix));
     }
-    
+
     /**
      * Creates a {@link MDLongArray} from the given <var>matrix</var> of rank 2 and the
      * <var>dimension</var> which need to be less or equal the dimensions of <var>matrix</var>. Note
-     * that the values in <var>matrix</var> will be copied and thus the created
-     * {@link MDLongArray} will be independent from <var>matrix</var> after construction.
+     * that the values in <var>matrix</var> will be copied and thus the created {@link MDIntArray}
+     * will be independent from <var>matrix</var> after construction.
      */
     public MDLongArray(long[][] matrix, int[] dimensions)
     {
-        super(dimensions);
+        super(dimensions, 0, matrix.length);
 
         final int sizeX = dimensions[0];
         final int sizeY = dimensions[1];
-        int size = 1;
-        for (int i = 0; i < dimensions.length; ++i)
-        {
-            size *= dimensions[i];
-        }
+        int size = getLength(dimensions, 0);
         this.flattenedArray = new long[size];
         for (int i = 0; i < sizeX; ++i)
         {
@@ -135,8 +156,9 @@ public final class MDLongArray extends MDAbstractArray<Long>
     private static int[] getDimensions(long[][] matrix)
     {
         assert matrix != null;
-        
-        return new int[] { matrix.length, matrix.length == 0 ? 0 : matrix[0].length };
+
+        return new int[]
+            { matrix.length, matrix.length == 0 ? 0 : matrix[0].length };
     }
 
     @Override
@@ -157,16 +179,27 @@ public final class MDLongArray extends MDAbstractArray<Long>
         set(value, indices);
     }
 
-    /**
-     * Returns the array in flattened form. Changes to the returned object will change the
-     * multi-dimensional array directly.
-     */
     @Override
     public long[] getAsFlatArray()
     {
         return flattenedArray;
     }
 
+    @Override
+    public long[] getCopyAsFlatArray()
+    {
+        return ArrayUtils.subarray(flattenedArray, 0, dimensions[0] * hyperRowLength);
+    }
+
+    @Override
+    protected void adaptCapacityHyperRows()
+    {
+        final long[] oldArray = this.flattenedArray;
+        this.flattenedArray = new long[capacityHyperRows * hyperRowLength];
+        System.arraycopy(oldArray, 0, flattenedArray, 0,
+                Math.min(oldArray.length, flattenedArray.length));
+    }
+
     /**
      * Returns the value of array at the position defined by <var>indices</var>.
      */
@@ -264,7 +297,7 @@ public final class MDLongArray extends MDAbstractArray<Long>
         }
         return result;
     }
-    
+
     //
     // Object
     //
@@ -274,7 +307,7 @@ public final class MDLongArray extends MDAbstractArray<Long>
     {
         final int prime = 31;
         int result = 1;
-        result = prime * result + Arrays.hashCode(flattenedArray);
+        result = prime * result + Arrays.hashCode(getValuesAsFlatArray());
         result = prime * result + Arrays.hashCode(dimensions);
         return result;
     }
@@ -295,7 +328,7 @@ public final class MDLongArray extends MDAbstractArray<Long>
             return false;
         }
         MDLongArray other = (MDLongArray) obj;
-        if (Arrays.equals(flattenedArray, other.flattenedArray) == false)
+        if (Arrays.equals(getValuesAsFlatArray(), other.getValuesAsFlatArray()) == false)
         {
             return false;
         }
@@ -306,4 +339,22 @@ public final class MDLongArray extends MDAbstractArray<Long>
         return true;
     }
 
+    private long[] getValuesAsFlatArray()
+    {
+        return (dimensions[0] < capacityHyperRows) ? getCopyAsFlatArray() : getAsFlatArray(); 
+    }
+    
+    private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException
+    {
+        stream.defaultReadObject();
+        if (hyperRowLength == 0)
+        {
+            this.hyperRowLength = computeHyperRowLength(dimensions);
+        }
+        if (capacityHyperRows == 0)
+        {
+            this.capacityHyperRows = dimensions[0];
+        }
+    }
+
 }
diff --git a/base/source/java/ch/systemsx/cisd/base/mdarray/MDShortArray.java b/base/source/java/ch/systemsx/cisd/base/mdarray/MDShortArray.java
index 336a6a09c827d9dd1b9c250d0aaf05199db3d010..d9d36eea28c4d7ec7937015f86021d1a7b615486 100644
--- a/base/source/java/ch/systemsx/cisd/base/mdarray/MDShortArray.java
+++ b/base/source/java/ch/systemsx/cisd/base/mdarray/MDShortArray.java
@@ -16,8 +16,12 @@
 
 package ch.systemsx.cisd.base.mdarray;
 
+import java.io.IOException;
+import java.io.ObjectInputStream;
 import java.util.Arrays;
 
+import org.apache.commons.lang.ArrayUtils;
+
 /**
  * A multi-dimensional <code>short</code> array.
  * 
@@ -26,22 +30,33 @@ import java.util.Arrays;
 public final class MDShortArray extends MDAbstractArray<Short>
 {
     private static final long serialVersionUID = 1L;
-    
-    private final short[] flattenedArray;
+
+    private short[] flattenedArray;
 
     /**
-     * Creates an empty {@link MDShortArray} with the <var>dimensions</var>. Convenience method if
+     * Creates an empty {@link MDIntArray} with the <var>dimensions</var>. Convenience method if
      * <var>dimensions</var> are available as {@code long[]}.
      */
     public MDShortArray(long[] dimensions)
     {
-        this(new short[getLength(dimensions)], toInt(dimensions), false);
+        this(new short[getLength(dimensions, 0)], toInt(dimensions), false);
     }
 
     /**
-     * Creates a {@link MDShortArray} from the given {@code flattenedArray} and {@code dimensions}.
-     * It is checked that the arguments are compatible. Convenience method if <var>dimensions</var>
-     * are available as {@code long[]}.
+     * Creates an empty {@link MDShortArray} with the <var>dimensions</var>. If
+     * <code>capacityHyperRows > dimensions[0]</code>, then it will create an array with a capacity
+     * of <var>capacityHyperRows</var> hyper-rows. Convenience method if <var>dimensions</var> are
+     * available as {@code long[]}.
+     */
+    public MDShortArray(long[] dimensions, long capacityHyperRows)
+    {
+        this(new short[getLength(dimensions, capacityHyperRows)], toInt(dimensions), false);
+    }
+
+    /**
+     * Creates a {@link MDShortArray} from the given {@code flattenedArray} and {@code dimensions}. It
+     * is checked that the arguments are compatible. Convenience method if <var>dimensions</var> are
+     * available as {@code long[]}.
      */
     public MDShortArray(short[] flattenedArray, long[] dimensions)
     {
@@ -64,12 +79,22 @@ public final class MDShortArray extends MDAbstractArray<Short>
      */
     public MDShortArray(int[] dimensions)
     {
-        this(new short[getLength(dimensions)], dimensions, false);
+        this(new short[getLength(dimensions, 0)], dimensions, false);
+    }
+
+    /**
+     * Creates an empty {@link MDShortArray} with the <var>dimensions</var>. If
+     * <code>capacityHyperRows > dimensions[0]</code>, then it will create an array with a capacity
+     * of <var>capacityHyperRows</var> hyper-rows.
+     */
+    public MDShortArray(int[] dimensions, int capacityHyperRows)
+    {
+        this(new short[getLength(dimensions, capacityHyperRows)], dimensions, false);
     }
 
     /**
-     * Creates a {@link MDShortArray} from the given {@code flattenedArray} and {@code dimensions}.
-     * It is checked that the arguments are compatible.
+     * Creates a {@link MDShortArray} from the given {@code flattenedArray} and {@code dimensions}. It
+     * is checked that the arguments are compatible.
      */
     public MDShortArray(short[] flattenedArray, int[] dimensions)
     {
@@ -83,12 +108,12 @@ public final class MDShortArray extends MDAbstractArray<Short>
      */
     public MDShortArray(short[] flattenedArray, int[] dimensions, boolean checkdimensions)
     {
-        super(dimensions);
+        super(dimensions, flattenedArray.length, 0);
         assert flattenedArray != null;
 
         if (checkdimensions)
         {
-            final int expectedLength = getLength(dimensions);
+            final int expectedLength = getLength(dimensions, 0);
             if (flattenedArray.length != expectedLength)
             {
                 throw new IllegalArgumentException("Actual array length " + flattenedArray.length
@@ -99,32 +124,28 @@ public final class MDShortArray extends MDAbstractArray<Short>
     }
 
     /**
-     * Creates a {@link MDShortArray} from the given <var>matrix</var> of rank 2. Note that the
-     * values in <var>matrix</var> will be copied and thus the created {@link MDShortArray} will be
+     * Creates a {@link MDShortArray} from the given <var>matrix</var> of rank 2. Note that the values
+     * in <var>matrix</var> will be copied and thus the created {@link MDIntArray} will be
      * independent from <var>matrix</var> after construction.
      */
     public MDShortArray(short[][] matrix)
     {
         this(matrix, getDimensions(matrix));
     }
-    
+
     /**
      * Creates a {@link MDShortArray} from the given <var>matrix</var> of rank 2 and the
      * <var>dimension</var> which need to be less or equal the dimensions of <var>matrix</var>. Note
-     * that the values in <var>matrix</var> will be copied and thus the created
-     * {@link MDShortArray} will be independent from <var>matrix</var> after construction.
+     * that the values in <var>matrix</var> will be copied and thus the created {@link MDIntArray}
+     * will be independent from <var>matrix</var> after construction.
      */
     public MDShortArray(short[][] matrix, int[] dimensions)
     {
-        super(dimensions);
+        super(dimensions, 0, matrix.length);
 
         final int sizeX = dimensions[0];
         final int sizeY = dimensions[1];
-        int size = 1;
-        for (int i = 0; i < dimensions.length; ++i)
-        {
-            size *= dimensions[i];
-        }
+        int size = getLength(dimensions, 0);
         this.flattenedArray = new short[size];
         for (int i = 0; i < sizeX; ++i)
         {
@@ -135,8 +156,9 @@ public final class MDShortArray extends MDAbstractArray<Short>
     private static int[] getDimensions(short[][] matrix)
     {
         assert matrix != null;
-        
-        return new int[] { matrix.length, matrix.length == 0 ? 0 : matrix[0].length };
+
+        return new int[]
+            { matrix.length, matrix.length == 0 ? 0 : matrix[0].length };
     }
 
     @Override
@@ -157,16 +179,27 @@ public final class MDShortArray extends MDAbstractArray<Short>
         set(value, indices);
     }
 
-    /**
-     * Returns the array in flattened form. Changes to the returned object will change the
-     * multi-dimensional array directly.
-     */
     @Override
     public short[] getAsFlatArray()
     {
         return flattenedArray;
     }
 
+    @Override
+    public short[] getCopyAsFlatArray()
+    {
+        return ArrayUtils.subarray(flattenedArray, 0, dimensions[0] * hyperRowLength);
+    }
+
+    @Override
+    protected void adaptCapacityHyperRows()
+    {
+        final short[] oldArray = this.flattenedArray;
+        this.flattenedArray = new short[capacityHyperRows * hyperRowLength];
+        System.arraycopy(oldArray, 0, flattenedArray, 0,
+                Math.min(oldArray.length, flattenedArray.length));
+    }
+
     /**
      * Returns the value of array at the position defined by <var>indices</var>.
      */
@@ -174,7 +207,7 @@ public final class MDShortArray extends MDAbstractArray<Short>
     {
         return flattenedArray[computeIndex(indices)];
     }
-    
+
     /**
      * Returns the value of a one-dimensional array at the position defined by <var>index</var>.
      * <p>
@@ -248,10 +281,6 @@ public final class MDShortArray extends MDAbstractArray<Short>
         flattenedArray[computeIndex(indexX, indexY, indexZ)] = value;
     }
 
-    //
-    // Object
-    //
-    
     /**
      * Creates and returns a matrix from a two-dimensional array.
      * <p>
@@ -268,13 +297,17 @@ public final class MDShortArray extends MDAbstractArray<Short>
         }
         return result;
     }
-    
+
+    //
+    // Object
+    //
+
     @Override
     public int hashCode()
     {
         final int prime = 31;
         int result = 1;
-        result = prime * result + Arrays.hashCode(flattenedArray);
+        result = prime * result + Arrays.hashCode(getValuesAsFlatArray());
         result = prime * result + Arrays.hashCode(dimensions);
         return result;
     }
@@ -295,7 +328,7 @@ public final class MDShortArray extends MDAbstractArray<Short>
             return false;
         }
         MDShortArray other = (MDShortArray) obj;
-        if (Arrays.equals(flattenedArray, other.flattenedArray) == false)
+        if (Arrays.equals(getValuesAsFlatArray(), other.getValuesAsFlatArray()) == false)
         {
             return false;
         }
@@ -306,4 +339,22 @@ public final class MDShortArray extends MDAbstractArray<Short>
         return true;
     }
 
+    private short[] getValuesAsFlatArray()
+    {
+        return (dimensions[0] < capacityHyperRows) ? getCopyAsFlatArray() : getAsFlatArray(); 
+    }
+    
+    private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException
+    {
+        stream.defaultReadObject();
+        if (hyperRowLength == 0)
+        {
+            this.hyperRowLength = computeHyperRowLength(dimensions);
+        }
+        if (capacityHyperRows == 0)
+        {
+            this.capacityHyperRows = dimensions[0];
+        }
+    }
+
 }
diff --git a/base/sourceTest/java/ch/systemsx/cisd/base/mdarray/MDArrayTests.java b/base/sourceTest/java/ch/systemsx/cisd/base/mdarray/MDArrayTests.java
index 2a136de59ff64b08939b8cff79966f33373ab934..6bc4d870959e6288bc25f46e9b6432a5645ba02d 100644
--- a/base/sourceTest/java/ch/systemsx/cisd/base/mdarray/MDArrayTests.java
+++ b/base/sourceTest/java/ch/systemsx/cisd/base/mdarray/MDArrayTests.java
@@ -41,7 +41,7 @@ public class MDArrayTests
 
         protected TestMDArray(int[] shape)
         {
-            super(shape);
+            super(shape, 0, 0);
         }
 
         @Override
@@ -66,31 +66,52 @@ public class MDArrayTests
         {
             return null;
         }
+
+        @Override
+        public Object getCopyAsFlatArray()
+        {
+            return null;
+        }
+
+        @Override
+        protected void adaptCapacityHyperRows()
+        {
+        }
     }
 
     @Test
     public void testGetLength()
     {
         assertEquals(0, MDAbstractArray.getLength(new int[]
-            { 0 }));
+            { 0 }, 0));
         assertEquals(1, MDAbstractArray.getLength(new int[]
-            { 1 }));
+            { 1 }, 0));
+        assertEquals(2, MDAbstractArray.getLength(new int[]
+                { 1 }, 2));
+        assertEquals(15, MDAbstractArray.getLength(new int[]
+            { 5, 3 }, 0));
+        assertEquals(21, MDAbstractArray.getLength(new int[]
+                { 5, 3 }, 7));
         assertEquals(15, MDAbstractArray.getLength(new int[]
-            { 5, 3 }));
+                { 5, 3 }, 3));
         assertEquals(1, MDAbstractArray.getLength(new int[]
-            { 1, 1, 1 }));
+            { 1, 1, 1 }, 0));
+        assertEquals(3, MDAbstractArray.getLength(new int[]
+                { 1, 1, 1 }, 3));
         assertEquals(8, MDAbstractArray.getLength(new int[]
-            { 2, 2, 2 }));
+            { 2, 2, 2 }, 0));
+        assertEquals(20, MDAbstractArray.getLength(new int[]
+                { 2, 2, 2 }, 5));
         assertEquals(2, MDAbstractArray.getLength(new int[]
-            { 1, 1, 2 }));
+            { 1, 1, 2 }, 0));
         assertEquals(2, MDAbstractArray.getLength(new int[]
-            { 1, 2, 1 }));
+            { 1, 2, 1 }, 0));
         assertEquals(2, MDAbstractArray.getLength(new int[]
-            { 2, 1, 1 }));
+            { 2, 1, 1 }, 0));
         assertEquals(50, MDAbstractArray.getLength(new int[]
-            { 10, 1, 5 }));
+            { 10, 1, 5 }, 0));
         assertEquals(50, MDAbstractArray.getLength(new long[]
-            { 10, 1, 5 }));
+            { 10, 1, 5 }, 0));
     }
 
     @Test
@@ -156,6 +177,98 @@ public class MDArrayTests
             { 9, 1, 2 }), array.computeIndex(9, 1, 2));
     }
 
+    @Test
+    public void testEmptyMatrix()
+    {
+        final MDFloatArray arr = new MDFloatArray(new float[0][0]);
+        assertEquals(0, arr.dimensions()[0]);
+        assertEquals(0, arr.dimensions()[1]);
+    }
+    
+    @Test
+    public void testChangeHyperRowCountIntArray()
+    {
+        final MDIntArray arr = new MDIntArray(new int[] { 2, 2 }, 3);
+        assertEquals(2, arr.dimensions[0]);
+        assertEquals(2, arr.dimensions[1]);
+        arr.set(1, 0, 0);
+        arr.set(2, 0, 1);
+        arr.set(3, 1, 0);
+        arr.set(4, 1, 1);
+
+        final MDIntArray arr2 = new MDIntArray(arr.getCopyAsFlatArray(), arr.dimensions());
+        assertTrue(arr2.equals(arr));
+        
+        arr.incNumberOfHyperRows(1);
+        assertEquals(3, arr.dimensions[0]);
+        assertEquals(1, arr.get(0, 0));
+        assertEquals(2, arr.get(0, 1));
+        assertEquals(3, arr.get(1, 0));
+        assertEquals(4, arr.get(1, 1));
+        arr.set(5, 2, 0);
+        arr.set(6, 2, 1);
+        arr.incNumberOfHyperRows(2);
+        assertEquals(5, arr.dimensions[0]);
+        assertEquals(1, arr.get(0, 0));
+        assertEquals(2, arr.get(0, 1));
+        assertEquals(3, arr.get(1, 0));
+        assertEquals(4, arr.get(1, 1));
+        assertEquals(5, arr.get(2, 0));
+        assertEquals(6, arr.get(2, 1));
+        arr.set(7, 3, 0);
+        arr.set(8, 3, 1);
+        arr.decNumberOfHyperRows(1);
+        assertEquals(4, arr.dimensions[0]);
+        assertEquals(1, arr.get(0, 0));
+        assertEquals(2, arr.get(0, 1));
+        assertEquals(3, arr.get(1, 0));
+        assertEquals(4, arr.get(1, 1));
+        assertEquals(5, arr.get(2, 0));
+        assertEquals(6, arr.get(2, 1));
+        assertEquals(7, arr.get(3, 0));
+        assertEquals(8, arr.get(3, 1));
+    }
+    
+    @Test
+    public void testChangeHyperRowCountTArray()
+    {
+        final MDArray<Integer> arr = new MDArray<Integer>(Integer.class, new int[] { 2, 2 }, 3);
+        assertEquals(2, arr.dimensions[0]);
+        assertEquals(2, arr.dimensions[1]);
+        arr.set(1, 0, 0);
+        arr.set(2, 0, 1);
+        arr.set(3, 1, 0);
+        arr.set(4, 1, 1);
+        arr.incNumberOfHyperRows(1);
+        assertEquals(3, arr.dimensions[0]);
+        assertEquals(1, (int) arr.get(0, 0));
+        assertEquals(2, (int) arr.get(0, 1));
+        assertEquals(3, (int) arr.get(1, 0));
+        assertEquals(4, (int) arr.get(1, 1));
+        arr.set(5, 2, 0);
+        arr.set(6, 2, 1);
+        arr.incNumberOfHyperRows(2);
+        assertEquals(5, arr.dimensions[0]);
+        assertEquals(1, (int) arr.get(0, 0));
+        assertEquals(2, (int) arr.get(0, 1));
+        assertEquals(3, (int) arr.get(1, 0));
+        assertEquals(4, (int) arr.get(1, 1));
+        assertEquals(5, (int) arr.get(2, 0));
+        assertEquals(6, (int) arr.get(2, 1));
+        arr.set(7, 3, 0);
+        arr.set(8, 3, 1);
+        arr.decNumberOfHyperRows(1);
+        assertEquals(4, arr.dimensions[0]);
+        assertEquals(1, (int) arr.get(0, 0));
+        assertEquals(2, (int) arr.get(0, 1));
+        assertEquals(3, (int) arr.get(1, 0));
+        assertEquals(4, (int) arr.get(1, 1));
+        assertEquals(5, (int) arr.get(2, 0));
+        assertEquals(6, (int) arr.get(2, 1));
+        assertEquals(7, (int) arr.get(3, 0));
+        assertEquals(8, (int) arr.get(3, 1));
+    }
+    
     @Test
     public void testMDFloatArrayMatrix()
     {