diff --git a/common/source/java/ch/systemsx/cisd/common/array/MDByteArray.java b/common/source/java/ch/systemsx/cisd/common/array/MDByteArray.java
index afa089134115e584668b8e338d7acd32f542720e..04b9ff6fef242bf4b503046b33b5156fc784140b 100644
--- a/common/source/java/ch/systemsx/cisd/common/array/MDByteArray.java
+++ b/common/source/java/ch/systemsx/cisd/common/array/MDByteArray.java
@@ -69,6 +69,36 @@ public final class MDByteArray extends MDAbstractArray<Byte>
         this.flattenedArray = flattenedArray;
     }
 
+    public MDByteArray(byte[][] matrix)
+    {
+        this(matrix, getDimensions(matrix));
+    }
+    
+    public MDByteArray(byte[][] matrix, int[] dimensions)
+    {
+        super(dimensions);
+
+        final int sizeX = dimensions[0];
+        final int sizeY = dimensions[1];
+        int size = 1;
+        for (int i = 0; i < dimensions.length; ++i)
+        {
+            size *= dimensions[i];
+        }
+        this.flattenedArray = new byte[size];
+        for (int i = 0; i < sizeX; ++i)
+        {
+            System.arraycopy(matrix[i], 0, flattenedArray, i * sizeY, sizeY);
+        }
+    }
+
+    private static int[] getDimensions(byte[][] matrix)
+    {
+        assert matrix != null;
+        
+        return new int[] { matrix.length, matrix.length == 0 ? 0 : matrix[0].length };
+    }
+
     @Override
     public int size()
     {
@@ -177,6 +207,23 @@ public final class MDByteArray extends MDAbstractArray<Byte>
         flattenedArray[computeIndex(indexX, indexY, indexZ)] = value;
     }
 
+    /**
+     * Creates and returns a matrix from a two-dimensional array.
+     * <p>
+     * <b>Do not call for arrays other than two-dimensional!</b>
+     */
+    public byte[][] toMatrix()
+    {
+        final int sizeX = dimensions[0];
+        final int sizeY = dimensions[1];
+        final byte[][] result = new byte[sizeX][sizeY];
+        for (int i = 0; i < sizeX; ++i)
+        {
+            System.arraycopy(flattenedArray, i * sizeY, result[i], 0, sizeY);
+        }
+        return result;
+    }
+    
     //
     // Object
     //
diff --git a/common/source/java/ch/systemsx/cisd/common/array/MDDoubleArray.java b/common/source/java/ch/systemsx/cisd/common/array/MDDoubleArray.java
index 38a849547cd255806de22fbeec1dfc362cae73a0..bbdabe9001b65895d3868830e167322ea300dd97 100644
--- a/common/source/java/ch/systemsx/cisd/common/array/MDDoubleArray.java
+++ b/common/source/java/ch/systemsx/cisd/common/array/MDDoubleArray.java
@@ -69,6 +69,36 @@ public final class MDDoubleArray extends MDAbstractArray<Double>
         this.flattenedArray = flattenedArray;
     }
 
+    public MDDoubleArray(double[][] matrix)
+    {
+        this(matrix, getDimensions(matrix));
+    }
+    
+    public MDDoubleArray(double[][] matrix, int[] dimensions)
+    {
+        super(dimensions);
+
+        final int sizeX = dimensions[0];
+        final int sizeY = dimensions[1];
+        int size = 1;
+        for (int i = 0; i < dimensions.length; ++i)
+        {
+            size *= dimensions[i];
+        }
+        this.flattenedArray = new double[size];
+        for (int i = 0; i < sizeX; ++i)
+        {
+            System.arraycopy(matrix[i], 0, flattenedArray, i * sizeY, sizeY);
+        }
+    }
+
+    private static int[] getDimensions(double[][] matrix)
+    {
+        assert matrix != null;
+        
+        return new int[] { matrix.length, matrix.length == 0 ? 0 : matrix[0].length };
+    }
+
     @Override
     public int size()
     {
@@ -177,6 +207,23 @@ public final class MDDoubleArray extends MDAbstractArray<Double>
         flattenedArray[computeIndex(indexX, indexY, indexZ)] = value;
     }
 
+    /**
+     * Creates and returns a matrix from a two-dimensional array.
+     * <p>
+     * <b>Do not call for arrays other than two-dimensional!</b>
+     */
+    public double[][] toMatrix()
+    {
+        final int sizeX = dimensions[0];
+        final int sizeY = dimensions[1];
+        final double[][] result = new double[sizeX][sizeY];
+        for (int i = 0; i < sizeX; ++i)
+        {
+            System.arraycopy(flattenedArray, i * sizeY, result[i], 0, sizeY);
+        }
+        return result;
+    }
+    
     //
     // Object
     //
diff --git a/common/source/java/ch/systemsx/cisd/common/array/MDFloatArray.java b/common/source/java/ch/systemsx/cisd/common/array/MDFloatArray.java
index 86cfccd078bf2a7af086820ccb8e0eaf806c16e3..40bf011740e03cdd5ffe8394b5aa0e6c8671447c 100644
--- a/common/source/java/ch/systemsx/cisd/common/array/MDFloatArray.java
+++ b/common/source/java/ch/systemsx/cisd/common/array/MDFloatArray.java
@@ -69,6 +69,36 @@ public final class MDFloatArray extends MDAbstractArray<Float>
         this.flattenedArray = flattenedArray;
     }
 
+    public MDFloatArray(float[][] matrix)
+    {
+        this(matrix, getDimensions(matrix));
+    }
+    
+    public MDFloatArray(float[][] matrix, int[] dimensions)
+    {
+        super(dimensions);
+
+        final int sizeX = dimensions[0];
+        final int sizeY = dimensions[1];
+        int size = 1;
+        for (int i = 0; i < dimensions.length; ++i)
+        {
+            size *= dimensions[i];
+        }
+        this.flattenedArray = new float[size];
+        for (int i = 0; i < sizeX; ++i)
+        {
+            System.arraycopy(matrix[i], 0, flattenedArray, i * sizeY, sizeY);
+        }
+    }
+
+    private static int[] getDimensions(float[][] matrix)
+    {
+        assert matrix != null;
+        
+        return new int[] { matrix.length, matrix.length == 0 ? 0 : matrix[0].length };
+    }
+
     @Override
     public int size()
     {
@@ -177,6 +207,23 @@ public final class MDFloatArray extends MDAbstractArray<Float>
         flattenedArray[computeIndex(indexX, indexY, indexZ)] = value;
     }
 
+    /**
+     * Creates and returns a matrix from a two-dimensional array.
+     * <p>
+     * <b>Do not call for arrays other than two-dimensional!</b>
+     */
+    public float[][] toMatrix()
+    {
+        final int sizeX = dimensions[0];
+        final int sizeY = dimensions[1];
+        final float[][] result = new float[sizeX][sizeY];
+        for (int i = 0; i < sizeX; ++i)
+        {
+            System.arraycopy(flattenedArray, i * sizeY, result[i], 0, sizeY);
+        }
+        return result;
+    }
+    
     //
     // Object
     //
diff --git a/common/source/java/ch/systemsx/cisd/common/array/MDIntArray.java b/common/source/java/ch/systemsx/cisd/common/array/MDIntArray.java
index e785d679e64d34025f7692f2d4ea2b21b80b1c03..67c72c99662fe73cab905f69020bdaf14de897a5 100644
--- a/common/source/java/ch/systemsx/cisd/common/array/MDIntArray.java
+++ b/common/source/java/ch/systemsx/cisd/common/array/MDIntArray.java
@@ -69,6 +69,36 @@ public final class MDIntArray extends MDAbstractArray<Integer>
         this.flattenedArray = flattenedArray;
     }
 
+    public MDIntArray(int[][] matrix)
+    {
+        this(matrix, getDimensions(matrix));
+    }
+    
+    public MDIntArray(int[][] matrix, int[] dimensions)
+    {
+        super(dimensions);
+
+        final int sizeX = dimensions[0];
+        final int sizeY = dimensions[1];
+        int size = 1;
+        for (int i = 0; i < dimensions.length; ++i)
+        {
+            size *= dimensions[i];
+        }
+        this.flattenedArray = new int[size];
+        for (int i = 0; i < sizeX; ++i)
+        {
+            System.arraycopy(matrix[i], 0, flattenedArray, i * sizeY, sizeY);
+        }
+    }
+
+    private static int[] getDimensions(int[][] matrix)
+    {
+        assert matrix != null;
+        
+        return new int[] { matrix.length, matrix.length == 0 ? 0 : matrix[0].length };
+    }
+
     @Override
     public int size()
     {
@@ -177,6 +207,23 @@ public final class MDIntArray extends MDAbstractArray<Integer>
         flattenedArray[computeIndex(indexX, indexY, indexZ)] = value;
     }
 
+    /**
+     * Creates and returns a matrix from a two-dimensional array.
+     * <p>
+     * <b>Do not call for arrays other than two-dimensional!</b>
+     */
+    public int[][] toMatrix()
+    {
+        final int sizeX = dimensions[0];
+        final int sizeY = dimensions[1];
+        final int[][] result = new int[sizeX][sizeY];
+        for (int i = 0; i < sizeX; ++i)
+        {
+            System.arraycopy(flattenedArray, i * sizeY, result[i], 0, sizeY);
+        }
+        return result;
+    }
+    
     //
     // Object
     //
diff --git a/common/source/java/ch/systemsx/cisd/common/array/MDLongArray.java b/common/source/java/ch/systemsx/cisd/common/array/MDLongArray.java
index 21178606291c5ac957b9f790e709f3f317b47ebc..09ef27135ba4d79e221af1b83b75545bc6a9a076 100644
--- a/common/source/java/ch/systemsx/cisd/common/array/MDLongArray.java
+++ b/common/source/java/ch/systemsx/cisd/common/array/MDLongArray.java
@@ -69,6 +69,36 @@ public final class MDLongArray extends MDAbstractArray<Long>
         this.flattenedArray = flattenedArray;
     }
 
+    public MDLongArray(long[][] matrix)
+    {
+        this(matrix, getDimensions(matrix));
+    }
+    
+    public MDLongArray(long[][] matrix, int[] dimensions)
+    {
+        super(dimensions);
+
+        final int sizeX = dimensions[0];
+        final int sizeY = dimensions[1];
+        int size = 1;
+        for (int i = 0; i < dimensions.length; ++i)
+        {
+            size *= dimensions[i];
+        }
+        this.flattenedArray = new long[size];
+        for (int i = 0; i < sizeX; ++i)
+        {
+            System.arraycopy(matrix[i], 0, flattenedArray, i * sizeY, sizeY);
+        }
+    }
+
+    private static int[] getDimensions(long[][] matrix)
+    {
+        assert matrix != null;
+        
+        return new int[] { matrix.length, matrix.length == 0 ? 0 : matrix[0].length };
+    }
+
     @Override
     public int size()
     {
@@ -177,6 +207,23 @@ public final class MDLongArray extends MDAbstractArray<Long>
         flattenedArray[computeIndex(indexX, indexY, indexZ)] = value;
     }
 
+    /**
+     * Creates and returns a matrix from a two-dimensional array.
+     * <p>
+     * <b>Do not call for arrays other than two-dimensional!</b>
+     */
+    public long[][] toMatrix()
+    {
+        final int sizeX = dimensions[0];
+        final int sizeY = dimensions[1];
+        final long[][] result = new long[sizeX][sizeY];
+        for (int i = 0; i < sizeX; ++i)
+        {
+            System.arraycopy(flattenedArray, i * sizeY, result[i], 0, sizeY);
+        }
+        return result;
+    }
+    
     //
     // Object
     //
diff --git a/common/source/java/ch/systemsx/cisd/common/array/MDShortArray.java b/common/source/java/ch/systemsx/cisd/common/array/MDShortArray.java
index 9fcb027803c7462c9f6536acf8124d2f9a723985..22b8f94f801a73f08e8c65419b60468abb6077f0 100644
--- a/common/source/java/ch/systemsx/cisd/common/array/MDShortArray.java
+++ b/common/source/java/ch/systemsx/cisd/common/array/MDShortArray.java
@@ -69,6 +69,36 @@ public final class MDShortArray extends MDAbstractArray<Short>
         this.flattenedArray = flattenedArray;
     }
 
+    public MDShortArray(short[][] matrix)
+    {
+        this(matrix, getDimensions(matrix));
+    }
+    
+    public MDShortArray(short[][] matrix, int[] dimensions)
+    {
+        super(dimensions);
+
+        final int sizeX = dimensions[0];
+        final int sizeY = dimensions[1];
+        int size = 1;
+        for (int i = 0; i < dimensions.length; ++i)
+        {
+            size *= dimensions[i];
+        }
+        this.flattenedArray = new short[size];
+        for (int i = 0; i < sizeX; ++i)
+        {
+            System.arraycopy(matrix[i], 0, flattenedArray, i * sizeY, sizeY);
+        }
+    }
+
+    private static int[] getDimensions(short[][] matrix)
+    {
+        assert matrix != null;
+        
+        return new int[] { matrix.length, matrix.length == 0 ? 0 : matrix[0].length };
+    }
+
     @Override
     public int size()
     {
@@ -181,6 +211,23 @@ public final class MDShortArray extends MDAbstractArray<Short>
     // Object
     //
     
+    /**
+     * Creates and returns a matrix from a two-dimensional array.
+     * <p>
+     * <b>Do not call for arrays other than two-dimensional!</b>
+     */
+    public short[][] toMatrix()
+    {
+        final int sizeX = dimensions[0];
+        final int sizeY = dimensions[1];
+        final short[][] result = new short[sizeX][sizeY];
+        for (int i = 0; i < sizeX; ++i)
+        {
+            System.arraycopy(flattenedArray, i * sizeY, result[i], 0, sizeY);
+        }
+        return result;
+    }
+    
     @Override
     public int hashCode()
     {
diff --git a/common/sourceTest/java/ch/systemsx/cisd/common/array/MDArraytest.java b/common/sourceTest/java/ch/systemsx/cisd/common/array/MDArraytest.java
index eaf663a1d4fa9fd71f64ed19625a2b2975514b04..424c82c41bad1d43fc4c3e4a160d521a66644303 100644
--- a/common/sourceTest/java/ch/systemsx/cisd/common/array/MDArraytest.java
+++ b/common/sourceTest/java/ch/systemsx/cisd/common/array/MDArraytest.java
@@ -24,12 +24,12 @@ import static org.testng.AssertJUnit.*;
 
 /**
  * Test cases for {@link MDAbstractArray}.
- *
+ * 
  * @author Bernd Rinn
  */
 public class MDArraytest
 {
-    
+
     static class TestMDArray extends MDAbstractArray<Void>
     {
         protected TestMDArray(int[] shape)
@@ -58,58 +58,110 @@ public class MDArraytest
     @Test
     public void testGetLength()
     {
-        assertEquals(0, MDAbstractArray.getLength(new int[] { 0 }));
-        assertEquals(1, MDAbstractArray.getLength(new int[] { 1 }));
-        assertEquals(15, MDAbstractArray.getLength(new int[] { 5, 3 }));
-        assertEquals(1, MDAbstractArray.getLength(new int[] { 1, 1, 1 }));
-        assertEquals(8, MDAbstractArray.getLength(new int[] { 2, 2, 2 }));
-        assertEquals(2, MDAbstractArray.getLength(new int[] { 1, 1, 2 }));
-        assertEquals(2, MDAbstractArray.getLength(new int[] { 1, 2, 1 }));
-        assertEquals(2, MDAbstractArray.getLength(new int[] { 2, 1, 1 }));
-        assertEquals(50, MDAbstractArray.getLength(new int[] { 10, 1, 5 }));
-        assertEquals(50, MDAbstractArray.getLength(new long[] { 10, 1, 5 }));
+        assertEquals(0, MDAbstractArray.getLength(new int[]
+            { 0 }));
+        assertEquals(1, MDAbstractArray.getLength(new int[]
+            { 1 }));
+        assertEquals(15, MDAbstractArray.getLength(new int[]
+            { 5, 3 }));
+        assertEquals(1, MDAbstractArray.getLength(new int[]
+            { 1, 1, 1 }));
+        assertEquals(8, MDAbstractArray.getLength(new int[]
+            { 2, 2, 2 }));
+        assertEquals(2, MDAbstractArray.getLength(new int[]
+            { 1, 1, 2 }));
+        assertEquals(2, MDAbstractArray.getLength(new int[]
+            { 1, 2, 1 }));
+        assertEquals(2, MDAbstractArray.getLength(new int[]
+            { 2, 1, 1 }));
+        assertEquals(50, MDAbstractArray.getLength(new int[]
+            { 10, 1, 5 }));
+        assertEquals(50, MDAbstractArray.getLength(new long[]
+            { 10, 1, 5 }));
     }
-    
+
     @Test
     public void testToInt()
     {
-        assertTrue(Arrays.equals(new int[] { 1, 2, 3 }, MDAbstractArray.toInt(new long[] { 1, 2, 3 })));
-        assertTrue(Arrays.equals(new int[] { }, MDAbstractArray.toInt(new long[] { })));
+        assertTrue(Arrays.equals(new int[]
+            { 1, 2, 3 }, MDAbstractArray.toInt(new long[]
+            { 1, 2, 3 })));
+        assertTrue(Arrays.equals(new int[] {}, MDAbstractArray.toInt(new long[] {})));
     }
-    
+
     @Test
     public void testComputeIndex()
     {
         TestMDArray array;
-        array = new TestMDArray(new int[] { 33 });
-        assertEquals(17, array.computeIndex(new int[] { 17 }));
-        array = new TestMDArray(new int[] { 100, 10 });
-        assertEquals(10 * 42 + 17, array.computeIndex(new int[] { 42, 17 }));
-        array = new TestMDArray(new int[] { 2, 7, 3 });
-        assertEquals(3 * 7 * 1 + 3 * 2 + 3, array.computeIndex(new int[] { 1, 2, 3 }));
+        array = new TestMDArray(new int[]
+            { 33 });
+        assertEquals(17, array.computeIndex(new int[]
+            { 17 }));
+        array = new TestMDArray(new int[]
+            { 100, 10 });
+        assertEquals(10 * 42 + 17, array.computeIndex(new int[]
+            { 42, 17 }));
+        array = new TestMDArray(new int[]
+            { 2, 7, 3 });
+        assertEquals(3 * 7 * 1 + 3 * 2 + 3, array.computeIndex(new int[]
+            { 1, 2, 3 }));
     }
 
     @Test
     public void testComputeIndex2D()
     {
         TestMDArray array;
-        array = new TestMDArray(new int[] { 100, 10 });
-        assertEquals(array.computeIndex(new int[] { 5, 8, }), array.computeIndex(5, 8));
-        assertEquals(array.computeIndex(new int[] { 9, 1, }), array.computeIndex(9, 1));
-        array = new TestMDArray(new int[] { 101, 11 });
-        assertEquals(array.computeIndex(new int[] { 5, 8, }), array.computeIndex(5, 8));
-        assertEquals(array.computeIndex(new int[] { 9, 1, }), array.computeIndex(9, 1));
+        array = new TestMDArray(new int[]
+            { 100, 10 });
+        assertEquals(array.computeIndex(new int[]
+            { 5, 8, }), array.computeIndex(5, 8));
+        assertEquals(array.computeIndex(new int[]
+            { 9, 1, }), array.computeIndex(9, 1));
+        array = new TestMDArray(new int[]
+            { 101, 11 });
+        assertEquals(array.computeIndex(new int[]
+            { 5, 8, }), array.computeIndex(5, 8));
+        assertEquals(array.computeIndex(new int[]
+            { 9, 1, }), array.computeIndex(9, 1));
     }
 
     @Test
     public void testComputeIndex3()
     {
         TestMDArray array;
-        array = new TestMDArray(new int[] { 100, 10, 17 });
-        assertEquals(array.computeIndex(new int[] { 5, 8, 16 }), array.computeIndex(5, 8, 16));
-        assertEquals(array.computeIndex(new int[] { 9, 1, 5 }), array.computeIndex(9, 1, 5));
-        array = new TestMDArray(new int[] { 101, 11, 3 });
-        assertEquals(array.computeIndex(new int[] { 5, 8, 0 }), array.computeIndex(5, 8, 0));
-        assertEquals(array.computeIndex(new int[] { 9, 1, 2 }), array.computeIndex(9, 1, 2));
+        array = new TestMDArray(new int[]
+            { 100, 10, 17 });
+        assertEquals(array.computeIndex(new int[]
+            { 5, 8, 16 }), array.computeIndex(5, 8, 16));
+        assertEquals(array.computeIndex(new int[]
+            { 9, 1, 5 }), array.computeIndex(9, 1, 5));
+        array = new TestMDArray(new int[]
+            { 101, 11, 3 });
+        assertEquals(array.computeIndex(new int[]
+            { 5, 8, 0 }), array.computeIndex(5, 8, 0));
+        assertEquals(array.computeIndex(new int[]
+            { 9, 1, 2 }), array.computeIndex(9, 1, 2));
+    }
+
+    @Test
+    public void testMDFloatArrayMatrix()
+    {
+        final float[][] matrix1 = new float[][]
+            {
+                { 1f, 2f, 3f, 4f },
+                { 5f, 6f, 7f, 8f },
+                { 9f, 10f, 11f, 12f } };
+        final MDFloatArray array = new MDFloatArray(matrix1);
+        assertEquals(2, array.rank());
+        assertEquals(12, array.size());
+        assertEquals(3, array.size(0));
+        assertEquals(4, array.size(1));
+        assertEquals(7f, array.get(1, 2));
+        final float[][] matrix2 = array.toMatrix();
+        assertEquals(matrix1.length, matrix2.length);
+        for (int i = 0; i < matrix1.length; ++i)
+        {
+            assertTrue(Arrays.equals(matrix1[i], matrix2[i]));
+        }
     }
 }