diff --git a/.travis.yml b/.travis.yml
index 52b7c46..41d1c6b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,6 +1,8 @@
 sudo: false
 language: java
 jdk:
-  - oraclejdk7
   - oraclejdk8
-  - openjdk7
\ No newline at end of file
+  - oraclejdk10
+  - openjdk7
+  - openjdk8
+  - openjdk10
diff --git a/debian/changelog b/debian/changelog
index 52b7547..f7260a5 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+libla4j-java (0.6.0+git20181127.2.dd1b917-1) UNRELEASED; urgency=low
+
+  * New upstream snapshot.
+  * New upstream snapshot.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Thu, 08 Sep 2022 02:51:06 -0000
+
 libla4j-java (0.6.0-3) unstable; urgency=medium
 
   * Fix watchfile to detect new versions on github
diff --git a/src/main/java/org/la4j/LinearAlgebra.java b/src/main/java/org/la4j/LinearAlgebra.java
index 987c9e9..782883a 100644
--- a/src/main/java/org/la4j/LinearAlgebra.java
+++ b/src/main/java/org/la4j/LinearAlgebra.java
@@ -94,79 +94,6 @@ public final class LinearAlgebra {
      */
     public static final int ROUND_FACTOR;
 
-    // Determine the machine epsilon
-    // Tolerance is 10e1
-    static {
-        int roundFactor = 0;
-        double eps = 1.0;
-        while (1 + eps > 1) {
-            eps = eps / 2;
-            roundFactor++;
-        }
-        EPS = eps * 10e1;
-        ROUND_FACTOR = roundFactor - 1;
-    }
-
-    public static enum SolverFactory {
-        GAUSSIAN {
-            @Override
-            public LinearSystemSolver create(Matrix matrix) {
-                return new GaussianSolver(matrix);
-            }
-        },
-        JACOBI {
-            @Override
-            public LinearSystemSolver create(Matrix matrix) {
-                return new JacobiSolver(matrix);
-            }
-        },
-        SEIDEL {
-            @Override
-            public LinearSystemSolver create(Matrix matrix) {
-                return new SeidelSolver(matrix);
-            }
-        },
-        FORWARD_BACK_SUBSTITUTION {
-            @Override
-            public LinearSystemSolver create(Matrix matrix) {
-                return new ForwardBackSubstitutionSolver(matrix);
-            }
-        },
-        LEAST_SQUARES {
-            @Override
-            public LinearSystemSolver create(Matrix matrix) {
-                return new LeastSquaresSolver(matrix);
-            }
-        },
-        SQUARE_ROOT {
-            @Override
-            public LinearSystemSolver create(Matrix matrix) {
-                return new SquareRootSolver(matrix);
-            }
-        },
-        SWEEP {
-            @Override
-            public LinearSystemSolver create(Matrix matrix) {
-                return new SweepSolver(matrix);
-            }
-        },
-        SMART {
-            @Override
-            public LinearSystemSolver create(Matrix matrix) {
-                // TODO: We can do it smarter in future
-                if (matrix.rows() == matrix.columns()) {
-                    return new ForwardBackSubstitutionSolver(matrix);
-                } else if (matrix.rows() > matrix.columns()) {
-                    return new LeastSquaresSolver(matrix);
-                }
-
-                throw new IllegalArgumentException("Underdetermined system of linear equations can not be solved.");
-            }
-        };
-
-        public abstract LinearSystemSolver create(Matrix matrix);
-    }
-
     /**
      * References to the Gaussian solver factory.
      */
@@ -207,29 +134,6 @@ public final class LinearAlgebra {
      */
     public static final SolverFactory SWEEP = SolverFactory.SWEEP;
 
-    public static enum InverterFactory {
-        GAUSS_JORDAN {
-            @Override
-            public MatrixInverter create(Matrix matrix) {
-                return new GaussJordanInverter(matrix);
-            }
-        },
-        NO_PIVOT_GAUSS {
-            @Override
-            public MatrixInverter create(Matrix matrix) {
-                return new NoPivotGaussInverter(matrix);
-            }
-        },
-        SMART {
-            @Override
-            public MatrixInverter create(Matrix matrix) {
-                return new GaussJordanInverter(matrix);
-            }
-        };
-
-        public abstract MatrixInverter create(Matrix matrix);
-    }
-
     /**
      * Reference to an inverter factory solving n linear systems.
      */
@@ -237,65 +141,18 @@ public final class LinearAlgebra {
 
     /**
      * Reference to the Gauss elimination method-based inverter factory.
-     * 
+     *
      * Note: this version of the Gauss elimination method does not use a
      * pivot and does not swap either columns or rows. As a result, it will fail
      * if there is a zero on the diagonal.
      */
     public static final InverterFactory NO_PIVOT_GAUSS = InverterFactory.NO_PIVOT_GAUSS;
-    
+
     /**
      * Reference to the Smart inverter factory.
      */
     public static final InverterFactory INVERTER = InverterFactory.SMART;
 
-    public static enum DecompositorFactory {
-          CHOLESKY {
-              @Override
-              public MatrixDecompositor create(Matrix matrix) {
-                  return new CholeskyDecompositor(matrix);
-              }
-          },
-          EIGEN {
-              @Override
-              public MatrixDecompositor create(Matrix matrix) {
-                  return new EigenDecompositor(matrix);
-              }
-          },
-          RAW_LU {
-              @Override
-              public MatrixDecompositor create(Matrix matrix) {
-                  return new RawLUDecompositor(matrix);
-              }
-          },
-          LU {
-              @Override
-              public MatrixDecompositor create(Matrix matrix) {
-                  return new LUDecompositor(matrix);
-              }
-          },
-          RAW_QR {
-              @Override
-              public MatrixDecompositor create(Matrix matrix) {
-                  return new RawQRDecompositor(matrix);
-              }
-          },
-          QR {
-              @Override
-              public MatrixDecompositor create(Matrix matrix) {
-                  return new QRDecompositor(matrix);
-              }
-          },
-          SVD {
-              @Override
-              public MatrixDecompositor create(Matrix matrix) {
-                  return new SingularValueDecompositor(matrix);
-              }
-          };
-
-        public abstract MatrixDecompositor create(Matrix matrix);
-    }
-
     /**
      * Reference to Cholesky decompositor factory.
      */
@@ -372,4 +229,149 @@ public final class LinearAlgebra {
 
     public final static MatrixMatrixOperation<Matrix> OO_PLACE_MATRICES_MULTIPLICATION =
         new OoPlaceMatricesMultiplication();
+
+    private LinearAlgebra() {}
+
+    // Determine the machine epsilon
+    // Tolerance is 10e1
+    static {
+        int roundFactor = 0;
+        double eps = 1.0;
+        while (1 + eps > 1) {
+            eps = eps / 2;
+            roundFactor++;
+        }
+        EPS = eps * 10e1;
+        ROUND_FACTOR = roundFactor - 1;
+    }
+
+    public static enum SolverFactory {
+        GAUSSIAN {
+            @Override
+            public LinearSystemSolver create(Matrix matrix) {
+                return new GaussianSolver(matrix);
+            }
+        },
+        JACOBI {
+            @Override
+            public LinearSystemSolver create(Matrix matrix) {
+                return new JacobiSolver(matrix);
+            }
+        },
+        SEIDEL {
+            @Override
+            public LinearSystemSolver create(Matrix matrix) {
+                return new SeidelSolver(matrix);
+            }
+        },
+        FORWARD_BACK_SUBSTITUTION {
+            @Override
+            public LinearSystemSolver create(Matrix matrix) {
+                return new ForwardBackSubstitutionSolver(matrix);
+            }
+        },
+        LEAST_SQUARES {
+            @Override
+            public LinearSystemSolver create(Matrix matrix) {
+                return new LeastSquaresSolver(matrix);
+            }
+        },
+        SQUARE_ROOT {
+            @Override
+            public LinearSystemSolver create(Matrix matrix) {
+                return new SquareRootSolver(matrix);
+            }
+        },
+        SWEEP {
+            @Override
+            public LinearSystemSolver create(Matrix matrix) {
+                return new SweepSolver(matrix);
+            }
+        },
+        SMART {
+            @Override
+            public LinearSystemSolver create(Matrix matrix) {
+                // TODO: We can do it smarter in future
+                if (matrix.rows() == matrix.columns()) {
+                    return new ForwardBackSubstitutionSolver(matrix);
+                } else if (matrix.rows() > matrix.columns()) {
+                    return new LeastSquaresSolver(matrix);
+                }
+
+                throw new IllegalArgumentException("Underdetermined system of linear equations can not be solved.");
+            }
+        };
+
+        public abstract LinearSystemSolver create(Matrix matrix);
+    }
+
+    public static enum InverterFactory {
+        GAUSS_JORDAN {
+            @Override
+            public MatrixInverter create(Matrix matrix) {
+                return new GaussJordanInverter(matrix);
+            }
+        },
+        NO_PIVOT_GAUSS {
+            @Override
+            public MatrixInverter create(Matrix matrix) {
+                return new NoPivotGaussInverter(matrix);
+            }
+        },
+        SMART {
+            @Override
+            public MatrixInverter create(Matrix matrix) {
+                return new GaussJordanInverter(matrix);
+            }
+        };
+
+        public abstract MatrixInverter create(Matrix matrix);
+    }
+
+    public static enum DecompositorFactory {
+        CHOLESKY {
+            @Override
+            public MatrixDecompositor create(Matrix matrix) {
+                return new CholeskyDecompositor(matrix);
+            }
+        },
+        EIGEN {
+            @Override
+            public MatrixDecompositor create(Matrix matrix) {
+                return new EigenDecompositor(matrix);
+            }
+        },
+        RAW_LU {
+            @Override
+            public MatrixDecompositor create(Matrix matrix) {
+                return new RawLUDecompositor(matrix);
+            }
+        },
+        LU {
+            @Override
+            public MatrixDecompositor create(Matrix matrix) {
+                return new LUDecompositor(matrix);
+            }
+        },
+        RAW_QR {
+            @Override
+            public MatrixDecompositor create(Matrix matrix) {
+                return new RawQRDecompositor(matrix);
+            }
+        },
+        QR {
+            @Override
+            public MatrixDecompositor create(Matrix matrix) {
+                return new QRDecompositor(matrix);
+            }
+        },
+        SVD {
+            @Override
+            public MatrixDecompositor create(Matrix matrix) {
+                return new SingularValueDecompositor(matrix);
+            }
+        };
+
+        public abstract MatrixDecompositor create(Matrix matrix);
+    }
 }
diff --git a/src/main/java/org/la4j/Matrices.java b/src/main/java/org/la4j/Matrices.java
index d8984ca..45457f9 100644
--- a/src/main/java/org/la4j/Matrices.java
+++ b/src/main/java/org/la4j/Matrices.java
@@ -218,80 +218,6 @@ public final class Matrices {
         }
     };
 
-    private static class SymmetricMatrixPredicate
-            implements AdvancedMatrixPredicate {
-
-        @Override
-        public boolean test(Matrix matrix) {
-            if (matrix.rows() != matrix.columns()) {
-                return false;
-            }
-
-            for (int i = 0; i < matrix.rows(); i++) {
-                for (int j = i + 1; j < matrix.columns(); j++) {
-                    double a = matrix.get(i, j);
-                    double b = matrix.get(j, i);
-                    double diff = Math.abs(a - b);
-                    if (diff / Math.max(Math.abs(a), Math.abs(b)) > EPS) {
-                        return false;
-                    }
-                }
-            }
-
-            return true;
-        }
-    }
-
-    private static class DiagonallyDominantPredicate
-            implements AdvancedMatrixPredicate {
-
-        @Override
-        public boolean test(Matrix matrix) {
-            if (matrix.rows() != matrix.columns()) {
-                return false;
-            }
-
-            for (int i = 0; i < matrix.rows(); i++) {
-                double sum = 0;
-                for (int j = 0; j < matrix.columns(); j++) {
-                    if (i != j) {
-                        sum += Math.abs(matrix.get(i, j));
-                    }
-                }
-                if (sum > Math.abs(matrix.get(i, i)) - EPS) {
-                    return false;
-                }
-            }
-
-            return true;
-        }
-    }
-
-    private static class PositiveDefiniteMatrixPredicate implements AdvancedMatrixPredicate {
-
-        @Override
-        public boolean test(Matrix matrix) {
-            if (matrix.rows() != matrix.columns()) {
-                return false;
-            }
-
-            int size = matrix.columns();
-            int currentSize = 1;
-
-            while (currentSize <= size) {
-                Matrix topLeftMatrix = matrix.sliceTopLeft(currentSize, currentSize);
-
-                if (topLeftMatrix.determinant() < 0) {
-                    return false;
-                }
-
-                currentSize++;
-            }
-
-            return true;
-        }
-    }
-
     /**
      * Checks whether the matrix is a
      * <a href="http://mathworld.wolfram.com/SymmetricMatrix.html">symmetric
@@ -317,23 +243,23 @@ public final class Matrices {
      * A matrix factory that produces zero {@link Basic2DMatrix}.
      */
     public static final MatrixFactory<Basic2DMatrix> BASIC_2D =
-        new MatrixFactory<Basic2DMatrix>() {
-            @Override
-            public Basic2DMatrix apply(int rows, int columns) {
-                return Basic2DMatrix.zero(rows, columns);
-            }
-        };
+            new MatrixFactory<Basic2DMatrix>() {
+                @Override
+                public Basic2DMatrix apply(int rows, int columns) {
+                    return Basic2DMatrix.zero(rows, columns);
+                }
+            };
 
     /**
      * A matrix factory that produces zero {@link Basic1DMatrix}.
      */
     public static final MatrixFactory<Basic1DMatrix> BASIC_1D =
-        new MatrixFactory<Basic1DMatrix>() {
-            @Override
-            public Basic1DMatrix apply(int rows, int columns) {
-                return Basic1DMatrix.zero(rows, columns);
-            }
-        };
+            new MatrixFactory<Basic1DMatrix>() {
+                @Override
+                public Basic1DMatrix apply(int rows, int columns) {
+                    return Basic1DMatrix.zero(rows, columns);
+                }
+            };
 
     /**
      * A default matrix factory for dense matrices.
@@ -344,23 +270,23 @@ public final class Matrices {
      * A matrix factory that produces zero {@link CCSMatrix}.
      */
     public static final MatrixFactory<CCSMatrix> CCS =
-        new MatrixFactory<CCSMatrix>() {
-            @Override
-            public CCSMatrix apply(int rows, int columns) {
-                return CCSMatrix.zero(rows, columns);
-            }
-        };
+            new MatrixFactory<CCSMatrix>() {
+                @Override
+                public CCSMatrix apply(int rows, int columns) {
+                    return CCSMatrix.zero(rows, columns);
+                }
+            };
 
     /**
      * A matrix factory that produces zero {@link CRSMatrix}.
      */
     public static final MatrixFactory<CRSMatrix> CRS =
-        new MatrixFactory<CRSMatrix>() {
-            @Override
-            public CRSMatrix apply(int rows, int columns) {
-                return CRSMatrix.zero(rows, columns);
-            }
-        };
+            new MatrixFactory<CRSMatrix>() {
+                @Override
+                public CRSMatrix apply(int rows, int columns) {
+                    return CRSMatrix.zero(rows, columns);
+                }
+            };
 
     /**
      * A default factory for sparse matrices.
@@ -411,6 +337,82 @@ public final class Matrices {
         }
     };
 
+    private Matrices() {}
+
+    private static class SymmetricMatrixPredicate
+            implements AdvancedMatrixPredicate {
+
+        @Override
+        public boolean test(Matrix matrix) {
+            if (matrix.rows() != matrix.columns()) {
+                return false;
+            }
+
+            for (int i = 0; i < matrix.rows(); i++) {
+                for (int j = i + 1; j < matrix.columns(); j++) {
+                    double a = matrix.get(i, j);
+                    double b = matrix.get(j, i);
+                    double diff = Math.abs(a - b);
+                    if (diff / Math.max(Math.abs(a), Math.abs(b)) > EPS) {
+                        return false;
+                    }
+                }
+            }
+
+            return true;
+        }
+    }
+
+    private static class DiagonallyDominantPredicate
+            implements AdvancedMatrixPredicate {
+
+        @Override
+        public boolean test(Matrix matrix) {
+            if (matrix.rows() != matrix.columns()) {
+                return false;
+            }
+
+            for (int i = 0; i < matrix.rows(); i++) {
+                double sum = 0;
+                for (int j = 0; j < matrix.columns(); j++) {
+                    if (i != j) {
+                        sum += Math.abs(matrix.get(i, j));
+                    }
+                }
+                if (sum > Math.abs(matrix.get(i, i)) - EPS) {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+    }
+
+    private static class PositiveDefiniteMatrixPredicate implements AdvancedMatrixPredicate {
+
+        @Override
+        public boolean test(Matrix matrix) {
+            if (matrix.rows() != matrix.columns()) {
+                return false;
+            }
+
+            int size = matrix.columns();
+            int currentSize = 1;
+
+            while (currentSize <= size) {
+                Matrix topLeftMatrix = matrix.sliceTopLeft(currentSize, currentSize);
+
+                if (topLeftMatrix.determinant() < 0) {
+                    return false;
+                }
+
+                currentSize++;
+            }
+
+            return true;
+        }
+    }
+
     /**
      * Creates a const function that evaluates it's argument to given {@code value}.
      *
@@ -555,24 +557,24 @@ public final class Matrices {
     
     /**
      * Makes an Euclidean norm accumulator that allows to use
-     * {@link org.la4j.Matrix#fold(org.la4j.vector.functor.MatrixAccumulator)}
+     * {@link org.la4j.Matrix#fold(org.la4j.matrix.functor.MatrixAccumulator)}
      * method for norm calculation.
      *
      * @return an Euclidean norm accumulator
      */
     public static MatrixAccumulator mkEuclideanNormAccumulator() {
         return new MatrixAccumulator() {
-            private BigDecimal result = new BigDecimal(0.0);
+            private BigDecimal result = BigDecimal.valueOf(0.0);
 
             @Override
             public void update(int i, int j, double value) {
-                result = result.add(new BigDecimal(value * value));
+                result = result.add(BigDecimal.valueOf(value * value));
             }
 
             @Override
             public double accumulate() {
                 double value = result.setScale(Matrices.ROUND_FACTOR, RoundingMode.CEILING).doubleValue();
-                result = new BigDecimal(0.0);
+                result = BigDecimal.valueOf(0.0);
                 return Math.sqrt(value);
             }
         };
@@ -580,7 +582,7 @@ public final class Matrices {
     
     /**
      * Makes an Manhattan norm accumulator that allows to use
-     * {@link org.la4j.Matrix#fold(org.la4j.vector.functor.MatrixAccumulator)}
+     * {@link org.la4j.Matrix#fold(org.la4j.matrix.functor.MatrixAccumulator)}
      * method for norm calculation.
      *
      * @return a Manhattan norm accumulator
@@ -605,7 +607,7 @@ public final class Matrices {
     
     /**
      * Makes an Infinity norm accumulator that allows to use
-     * {@link org.la4j.Matrix#fold(org.la4j.vector.functor.MatrixAccumulator)}
+     * {@link org.la4j.Matrix#fold(org.la4j.matrix.functor.MatrixAccumulator)}
      * method for norm calculation.
      *
      * @return an Infinity norm accumulator
@@ -637,17 +639,17 @@ public final class Matrices {
      */
     public static MatrixAccumulator asSumAccumulator(final double neutral) {
         return new MatrixAccumulator() {
-            private BigDecimal result = new BigDecimal(neutral);
+            private BigDecimal result = BigDecimal.valueOf(neutral);
 
             @Override
             public void update(int i, int j, double value) {
-                result = result.add(new BigDecimal(value));
+                result = result.add(BigDecimal.valueOf(value));
             }
 
             @Override
             public double accumulate() {
                 double value = result.setScale(Matrices.ROUND_FACTOR, RoundingMode.CEILING).doubleValue();
-                result = new BigDecimal(neutral);
+                result = BigDecimal.valueOf(neutral);
                 return value;
             }
         };
@@ -662,17 +664,17 @@ public final class Matrices {
      */
     public static MatrixAccumulator asProductAccumulator(final double neutral) {
         return new MatrixAccumulator() {
-            private BigDecimal result = new BigDecimal(neutral);
+            private BigDecimal result = BigDecimal.valueOf(neutral);
 
             @Override
             public void update(int i, int j, double value) {
-                result = result.multiply(new BigDecimal(value));
+                result = result.multiply(BigDecimal.valueOf(value));
             }
 
             @Override
             public double accumulate() {
                 double value = result.setScale(Matrices.ROUND_FACTOR, RoundingMode.CEILING).doubleValue();
-                result = new BigDecimal(neutral);
+                result = BigDecimal.valueOf(neutral);
                 return value;
             }
         };
diff --git a/src/main/java/org/la4j/Matrix.java b/src/main/java/org/la4j/Matrix.java
index 37b47ed..6cfea5b 100644
--- a/src/main/java/org/la4j/Matrix.java
+++ b/src/main/java/org/la4j/Matrix.java
@@ -50,10 +50,15 @@ import org.la4j.vector.functor.VectorAccumulator;
 import org.la4j.vector.functor.VectorFunction;
 import org.la4j.vector.functor.VectorProcedure;
 
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.text.DecimalFormat;
 import java.text.NumberFormat;
+import java.util.NoSuchElementException;
 import java.util.Random;
 import java.util.StringTokenizer;
 
@@ -82,6 +87,25 @@ public abstract class Matrix implements Iterable<Double> {
             "          "
     };
 
+    protected int rows;
+    protected int columns;
+
+    /**
+     * Creates a zero-shape matrix.
+     */
+    public Matrix() {
+        this(0, 0);
+    }
+
+    /**
+     * Creates a matrix of given shape {@code rows} x {@code columns};
+     */
+    public Matrix(int rows, int columns) {
+        ensureDimensionsAreCorrect(rows, columns);
+        this.rows = rows;
+        this.columns = columns;
+    }
+
     /**
      * Creates a zero {@link Matrix} of the given shape:
      * {@code rows} x {@code columns}.
@@ -170,7 +194,8 @@ public abstract class Matrix implements Iterable<Double> {
     public static Matrix fromCSV(String csv) {
         StringTokenizer lines = new StringTokenizer(csv, "\n");
         Matrix result = DenseMatrix.zero(10, 10);
-        int rows = 0, columns = 0;
+        int rows = 0;
+        int columns = 0;
 
         while (lines.hasMoreTokens()) {
             if (result.rows() == rows) {
@@ -184,7 +209,7 @@ public abstract class Matrix implements Iterable<Double> {
                     result = result.copyOfColumns((j * 3) / 2 + 1);
                 }
 
-                double x = Double.valueOf(elements.nextToken());
+                double x = Double.parseDouble(elements.nextToken());
                 result.set(rows, j++, x);
             }
 
@@ -198,14 +223,15 @@ public abstract class Matrix implements Iterable<Double> {
     /**
      * Parses {@link Matrix} from the given Matrix Market string.
      *
-     * @param mm the string in Matrix Market format
+     * @param is the input stream in Matrix Market format
      *
      * @return a parsed matrix
+     * @exception  IOException  if an I/O error occurs.
      */
-    public static Matrix fromMatrixMarket(String mm) {
-        StringTokenizer body = new StringTokenizer(mm, "\n");
+    public static Matrix fromMatrixMarket(InputStream is) throws IOException {
+        BufferedReader body = new BufferedReader(new InputStreamReader(is));
 
-        String headerString = body.nextToken();
+        String headerString = body.readLine();
         StringTokenizer header = new StringTokenizer(headerString);
 
         if (!"%%MatrixMarket".equals(header.nextToken())) {
@@ -234,24 +260,24 @@ public abstract class Matrix implements Iterable<Double> {
 
         String majority = (header.hasMoreTokens()) ? header.nextToken() : "row-major";
 
-        String nextToken = body.nextToken();
+        String nextToken = body.readLine();
         while (nextToken.startsWith("%")) {
-            nextToken = body.nextToken();
+            nextToken = body.readLine();
         }
 
         if ("coordinate".equals(format)) {
             StringTokenizer lines = new StringTokenizer(nextToken);
 
-            int rows = Integer.valueOf(lines.nextToken());
-            int columns = Integer.valueOf(lines.nextToken());
-            int cardinality = Integer.valueOf(lines.nextToken());
+            int rows = Integer.parseInt(lines.nextToken());
+            int columns = Integer.parseInt(lines.nextToken());
+            int cardinality = Integer.parseInt(lines.nextToken());
 
             Matrix result = "row-major".equals(majority) ?
                     RowMajorSparseMatrix.zero(rows, columns, cardinality) :
                     ColumnMajorSparseMatrix.zero(rows, columns, cardinality);
 
             for (int k = 0; k < cardinality; k++) {
-                lines = new StringTokenizer(body.nextToken());
+                lines = new StringTokenizer(body.readLine());
 
                 int i = Integer.valueOf(lines.nextToken());
                 int j = Integer.valueOf(lines.nextToken());
@@ -269,7 +295,7 @@ public abstract class Matrix implements Iterable<Double> {
 
             for (int i = 0; i < rows; i++) {
                 for (int j = 0; j < columns; j++) {
-                    result.set(i, j, Double.valueOf(body.nextToken()));
+                    result.set(i, j, Double.valueOf(body.readLine()));
                 }
             }
 
@@ -277,25 +303,6 @@ public abstract class Matrix implements Iterable<Double> {
         }
     }
 
-    protected int rows;
-    protected int columns;
-
-    /**
-     * Creates a zero-shape matrix.
-     */
-    public Matrix() {
-        this(0, 0);
-    }
-
-    /**
-     * Creates a matrix of given shape {@code rows} x {@code columns};
-     */
-    public Matrix(int rows, int columns) {
-        ensureDimensionsAreCorrect(rows, columns);
-        this.rows = rows;
-        this.columns = columns;
-    }
-
     //
     // ============ ABSTRACT METHODS ============
     //
@@ -932,7 +939,7 @@ public abstract class Matrix implements Iterable<Double> {
         }
 
         MatrixDecompositor decompositor = withDecompositor(LinearAlgebra.LU);
-        Matrix lup[] = decompositor.decompose();
+        Matrix[] lup = decompositor.decompose();
         // TODO: Why Java doesn't support pattern matching?
         Matrix u = lup[1];
         Matrix p = lup[2];
@@ -941,7 +948,7 @@ public abstract class Matrix implements Iterable<Double> {
 
         // TODO: we can do that in O(n log n)
         //       just google: "counting inversions divide and conqueror"
-        int permutations[] = new int[p.rows()];
+        int[] permutations = new int[p.rows()];
         for (int i = 0; i < p.rows(); i++) {
             for (int j = 0; j < p.columns(); j++) {
                 if (p.get(i, j) > 0.0) {
@@ -983,7 +990,7 @@ public abstract class Matrix implements Iterable<Double> {
         // matrices without SVD
 
         MatrixDecompositor decompositor = withDecompositor(LinearAlgebra.SVD);
-        Matrix usv[] = decompositor.decompose();
+        Matrix[] usv = decompositor.decompose();
         // TODO: Where is my pattern matching?
         Matrix s = usv[1];
         double tolerance = Math.max(rows, columns) * s.get(0, 0) * Matrices.EPS;
@@ -1036,11 +1043,16 @@ public abstract class Matrix implements Iterable<Double> {
      * @return matrix with row.
      */
     public Matrix insertRow(int i, Vector row) {
-        if (i >= rows || i < 0) {
-            throw new IndexOutOfBoundsException("Illegal row number, must be 0.." + (rows - 1));
+        if (i > rows || i < 0) {
+            throw new IndexOutOfBoundsException("Illegal row number, must be 0.." + rows);
         }
 
-        Matrix result = blankOfShape(rows + 1, columns);
+        Matrix result;
+        if (columns == 0) {
+            result = blankOfShape(rows + 1, row.length());
+        } else {
+            result = blankOfShape(rows + 1, columns);
+        }
 
         for (int ii = 0; ii < i; ii++) {
             result.setRow(ii, getRow(ii));
@@ -1061,11 +1073,16 @@ public abstract class Matrix implements Iterable<Double> {
      * @return matrix with column.
      */
     public Matrix insertColumn(int j, Vector column) {
-        if (j >= columns || j < 0) {
-            throw new IndexOutOfBoundsException("Illegal row number, must be 0.." + (columns - 1));
+        if (j > columns || j < 0) {
+            throw new IndexOutOfBoundsException("Illegal column number, must be 0.." + columns);
         }
 
-        Matrix result = blankOfShape(rows, columns + 1);
+        Matrix result;
+        if (rows == 0) {
+            result = blankOfShape(column.length(), columns + 1);
+        } else {
+            result = blankOfShape(rows, columns + 1);
+        }
 
         for (int jj = 0; jj < j; jj++) {
             result.setColumn(jj, getColumn(jj));
@@ -1110,7 +1127,7 @@ public abstract class Matrix implements Iterable<Double> {
      */
     public Matrix removeColumn(int j) {
         if (j >= columns || j < 0) {
-            throw new IndexOutOfBoundsException("Illegal row number, must be 0.." + (columns - 1));
+            throw new IndexOutOfBoundsException("Illegal column number, must be 0.." + (columns - 1));
         }
 
         Matrix result = blankOfShape(rows, columns - 1);
@@ -1262,6 +1279,9 @@ public abstract class Matrix implements Iterable<Double> {
      * @return the sub-matrix of this matrix
      */
     public Matrix slice(int fromRow, int fromColumn, int untilRow, int untilColumn) {
+        ensureIndexArgumentsAreInBounds(fromRow, fromColumn);
+        ensureIndexArgumentsAreInBounds(untilRow - 1, untilColumn - 1);
+
         if (untilRow - fromRow < 0 || untilColumn - fromColumn < 0) {
             fail("Wrong slice range: [" + fromRow + ".." + untilRow + "][" + fromColumn + ".." + untilColumn + "].");
         }
@@ -1812,7 +1832,7 @@ public abstract class Matrix implements Iterable<Double> {
      */
     public String mkString(NumberFormat formatter, String rowsDelimiter, String columnsDelimiter) {
         // TODO: rewrite using iterators
-        int formats[] = new int[columns];
+        int[] formats = new int[columns];
 
         for (int i = 0; i < rows; i++) {
             for (int j = 0; j < columns; j++) {
@@ -1900,6 +1920,10 @@ public abstract class Matrix implements Iterable<Double> {
 
             @Override
             public Double next() {
+                if(!hasNext()) {
+                    throw new NoSuchElementException();
+                }
+
                 i++;
                 return get();
             }
@@ -1943,6 +1967,9 @@ public abstract class Matrix implements Iterable<Double> {
 
             @Override
             public Double next() {
+                if(!hasNext()) {
+                    throw new NoSuchElementException();
+                }
                 i++;
                 return get();
             }
@@ -1981,6 +2008,9 @@ public abstract class Matrix implements Iterable<Double> {
 
             @Override
             public Double next() {
+                if(!hasNext()) {
+                    throw new NoSuchElementException();
+                }
                 j++;
                 return get();
             }
@@ -2018,6 +2048,9 @@ public abstract class Matrix implements Iterable<Double> {
 
              @Override
              public Double next() {
+                 if(!hasNext()) {
+                     throw new NoSuchElementException();
+                 }
                  i++;
                  return get();
              }
@@ -2144,6 +2177,16 @@ public abstract class Matrix implements Iterable<Double> {
         }
     }
 
+    protected void ensureIndexArgumentsAreInBounds(int i, int j) {
+        if (i < 0 || i >= rows) {
+            fail(String.format("Bad row argument %d; out of bounds", i));
+        }
+
+        if (j < 0 || j >= columns) {
+            fail(String.format("Bad column argument %d; out of bounds", j));
+        }
+    }
+
     protected void ensureIndexesAreInBounds(int i, int j) {
         if (i < 0 || i >= rows) {
             throw new IndexOutOfBoundsException("Row '" + i + "' is invalid.");
diff --git a/src/main/java/org/la4j/Vector.java b/src/main/java/org/la4j/Vector.java
index 0defc71..e66c026 100644
--- a/src/main/java/org/la4j/Vector.java
+++ b/src/main/java/org/la4j/Vector.java
@@ -25,12 +25,10 @@
 
 package org.la4j;
 
+import java.io.*;
 import java.text.DecimalFormat;
 import java.text.NumberFormat;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Random;
-import java.util.StringTokenizer;
+import java.util.*;
 
 import org.la4j.iterator.VectorIterator;
 import org.la4j.vector.VectorFactory;
@@ -52,6 +50,28 @@ public abstract class Vector implements Iterable<Double> {
     private static final String DEFAULT_DELIMITER = " ";
     private static final NumberFormat DEFAULT_FORMATTER = new DecimalFormat("0.000");
 
+    /**
+     * Length of this vector.
+     */
+    protected int length;
+
+    /**
+     * Creates a vector of zero length.
+     */
+    public Vector() {
+        this(0);
+    }
+
+    /**
+     * Creates a vector of given {@code length}.
+     *
+     * @param length the length of the vector
+     */
+    public Vector(int length) {
+        ensureLengthIsCorrect(length);
+        this.length = length;
+    }
+
     /**
      * Creates a zero {@link Vector} of the given {@code length}.
      */
@@ -109,7 +129,7 @@ public abstract class Vector implements Iterable<Double> {
                 result = result.copyOfLength((i * 3) / 2 + 1);
             }
 
-            double x = Double.valueOf(tokenizer.nextToken());
+            double x = Double.parseDouble(tokenizer.nextToken());
             result.set(i++, x);
         }
 
@@ -118,42 +138,53 @@ public abstract class Vector implements Iterable<Double> {
 
 
     /**
-     * Parses {@link Vector} from the given Matrix Market string.
+     * Parses {@link Vector} from the given Matrix Market.
      *
-     * @param mm the string in Matrix Market format
+     * @param is the input stream in Matrix Market format
      *
      * @return a parsed vector
+     * @exception  IOException  if an I/O error occurs.
      */
-    public static Vector fromMatrixMarket(String mm) {
-        StringTokenizer body = new StringTokenizer(mm);
+    public static Vector fromMatrixMarket(InputStream is) throws IOException {
+
+        StreamTokenizer tokenizer = new StreamTokenizer(new BufferedReader(new InputStreamReader(is)));
+        tokenizer.wordChars('%', '%');
 
-        if (!"%%MatrixMarket".equals(body.nextToken())) {
+        tokenizer.nextToken();
+        if (!"%%MatrixMarket".equals(tokenizer.sval)) {
             throw new IllegalArgumentException("Wrong input file format: can not read header '%%MatrixMarket'.");
         }
 
-        String object = body.nextToken();
+        tokenizer.nextToken();
+        String object = tokenizer.sval;
         if (!"vector".equals(object)) {
             throw new IllegalArgumentException("Unexpected object: " + object + ".");
         }
 
-        String format = body.nextToken();
+        tokenizer.nextToken();
+        String format = tokenizer.sval;
         if (!"coordinate".equals(format) && !"array".equals(format)) {
             throw new IllegalArgumentException("Unknown format: " + format + ".");
         }
 
-        String field = body.nextToken();
+        tokenizer.nextToken();
+        String field = tokenizer.sval;
         if (!"real".equals(field)) {
             throw new IllegalArgumentException("Unknown field type: " + field + ".");
         }
 
-        int length = Integer.valueOf(body.nextToken());
+        tokenizer.nextToken();
+        int length = (int) Math.round(tokenizer.nval);
         if ("coordinate".equals(format)) {
-            int cardinality = Integer.valueOf(body.nextToken());
+            tokenizer.nextToken();
+            int cardinality = (int) Math.round(tokenizer.nval);
             Vector result = SparseVector.zero(length, cardinality);
 
             for (int k = 0; k < cardinality; k++) {
-                int i = Integer.valueOf(body.nextToken());
-                double x = Double.valueOf(body.nextToken());
+                tokenizer.nextToken();
+                int i = (int) Math.round(tokenizer.nval);
+                tokenizer.nextToken();
+                double x = tokenizer.nval;
                 result.set(i - 1, x);
             }
 
@@ -162,7 +193,8 @@ public abstract class Vector implements Iterable<Double> {
             Vector result = DenseVector.zero(length);
 
             for (int i = 0; i < length; i++) {
-                result.set(i, Double.valueOf(body.nextToken()));
+                tokenizer.nextToken();
+                result.set(i, tokenizer.nval);
             }
 
             return result;
@@ -183,28 +215,6 @@ public abstract class Vector implements Iterable<Double> {
         return SparseVector.fromMap(map, length);
     }
 
-    /**
-     * Length of this vector.
-     */
-    protected int length;
-
-    /**
-     * Creates a vector of zero length.
-     */
-    public Vector() {
-        this(0);
-    }
-
-    /**
-     * Creates a vector of given {@code length}.
-     *
-     * @param length the length of the vector
-     */
-    public Vector(int length) {
-        ensureLengthIsCorrect(length);
-        this.length = length;
-    }
-
     //
     // ============ ABSTRACT METHODS ============
     //
@@ -490,6 +500,17 @@ public abstract class Vector implements Iterable<Double> {
         return apply(LinearAlgebra.OO_PLACE_OUTER_PRODUCT, that);
     }
 
+    /**
+     * Calculates the cosine similarity between this vector and given {@code that}.
+     *
+     * @param that the vector to calculated cosine similarity with
+     *
+     * @return the cosine similarity of the two vectors
+     */
+    public double cosineSimilarity(Vector that) {
+        return this.innerProduct(that) / (this.euclideanNorm() * that.euclideanNorm());
+    }
+
     /**
      * Calculates an Euclidean norm of this vector.
      *
@@ -905,6 +926,9 @@ public abstract class Vector implements Iterable<Double> {
 
             @Override
             public Double next() {
+                if(!hasNext()) {
+                    throw new NoSuchElementException();
+                }
                 i++;
                 return get();
             }
diff --git a/src/main/java/org/la4j/Vectors.java b/src/main/java/org/la4j/Vectors.java
index 66aa41d..6ab5d7a 100644
--- a/src/main/java/org/la4j/Vectors.java
+++ b/src/main/java/org/la4j/Vectors.java
@@ -126,6 +126,8 @@ public final class Vectors {
         }
     };
 
+    private Vectors() {}
+
     /**
      * Creates a const function that evaluates it's argument to given {@code value}.
      *
@@ -231,17 +233,17 @@ public final class Vectors {
      */
     public static VectorAccumulator asSumAccumulator(final double neutral) {
         return new VectorAccumulator() {
-            private BigDecimal result = new BigDecimal(neutral);
+            private BigDecimal result = BigDecimal.valueOf(neutral);
 
             @Override
             public void update(int i, double value) {
-                result = result.add(new BigDecimal(value));
+                result = result.add(BigDecimal.valueOf(value));
             }
 
             @Override
             public double accumulate() {
                 double value = result.setScale(Vectors.ROUND_FACTOR, RoundingMode.CEILING).doubleValue();
-                result = new BigDecimal(neutral);
+                result = BigDecimal.valueOf(neutral);
                 return value;
             }
         };
@@ -256,17 +258,17 @@ public final class Vectors {
      */
     public static VectorAccumulator asProductAccumulator(final double neutral) {
         return new VectorAccumulator() {
-            private BigDecimal result = new BigDecimal(neutral);
+            private BigDecimal result = BigDecimal.valueOf(neutral);
 
             @Override
             public void update(int i, double value) {
-                result = result.multiply(new BigDecimal(value));
+                result = result.multiply(BigDecimal.valueOf(value));
             }
 
             @Override
             public double accumulate() {
                 double value = result.setScale(Vectors.ROUND_FACTOR, RoundingMode.CEILING).doubleValue();
-                result = new BigDecimal(neutral);
+                result = BigDecimal.valueOf(neutral);
                 return value;
             }
         };
@@ -326,17 +328,17 @@ public final class Vectors {
      */
     public static VectorAccumulator mkEuclideanNormAccumulator() {
         return new VectorAccumulator() {
-            private BigDecimal result = new BigDecimal(0.0);
+            private BigDecimal result = BigDecimal.valueOf(0.0);
 
             @Override
             public void update(int i, double value) {
-                result = result.add(new BigDecimal(value * value));
+                result = result.add(BigDecimal.valueOf(value * value));
             }
 
             @Override
             public double accumulate() {
                 double value = result.setScale(Vectors.ROUND_FACTOR, RoundingMode.CEILING).doubleValue();
-                result = new BigDecimal(0.0);
+                result = BigDecimal.valueOf(0.0);
                 return Math.sqrt(value);
             }
         };
diff --git a/src/main/java/org/la4j/decomposition/EigenDecompositor.java b/src/main/java/org/la4j/decomposition/EigenDecompositor.java
index 2b9b20d..169c4f1 100644
--- a/src/main/java/org/la4j/decomposition/EigenDecompositor.java
+++ b/src/main/java/org/la4j/decomposition/EigenDecompositor.java
@@ -94,7 +94,8 @@ public class EigenDecompositor extends AbstractDecompositor implements MatrixDec
         double n = Matrices.EPS;
         double nn = r.fold(normAccumulator);
 
-        int kk = 0, ll = 0;
+        int kk = 0;
+        int ll = 0;
 
         while (Math.abs(n - nn) > Matrices.EPS) {
 
@@ -183,7 +184,8 @@ public class EigenDecompositor extends AbstractDecompositor implements MatrixDec
         u.set(kk, ll, 0.0);
         u.set(ll, kk, 0.0);
 
-        double alpha = 0.0, beta = 0.0;
+        double alpha = 0.0;
+        double beta = 0.0;
 
         if (Math.abs(matrix.get(k, k) - matrix.get(l, l)) < Matrices.EPS) {
             alpha = beta = Math.sqrt(0.5);
@@ -353,7 +355,15 @@ public class EigenDecompositor extends AbstractDecompositor implements MatrixDec
         int high = nn - 1;
         double eps = Math.pow(2.0, -52.0);
         double exshift = 0.0;
-        double p = 0, q = 0, r = 0, s = 0, z = 0, t, w, x, y;
+        double p = 0;
+        double q = 0;
+        double r = 0;
+        double s = 0;
+        double z = 0;
+        double t;
+        double w;
+        double x;
+        double y;
 
         // Store roots isolated by balanc and compute matrix norm
 
@@ -701,7 +711,7 @@ public class EigenDecompositor extends AbstractDecompositor implements MatrixDec
                     H.set(n - 1, n, -(H.get(n, n) - p) 
                                             / H.get(n, n - 1));
                 } else {
-                    double cdiv[] = cdiv(0.0, -H.get(n - 1, n), 
+                    double[] cdiv = cdiv(0.0, -H.get(n - 1, n),
                          H.get(n - 1, n - 1) - p, q);
                     H.set(n - 1, n - 1, cdiv[0]);
                     H.set(n - 1, n, cdiv[1]);
@@ -709,7 +719,10 @@ public class EigenDecompositor extends AbstractDecompositor implements MatrixDec
                 H.set(n, n - 1, 0.0);
                 H.set(n, n, 1.0);
                 for (int i = n - 2; i >= 0; i--) {
-                    double ra, sa, vr, vi;
+                    double ra;
+                    double sa;
+                    double vr;
+                    double vi;
                     ra = 0.0;
                     sa = 0.0;
                     for (int j = l; j <= n; j++) {
@@ -725,7 +738,7 @@ public class EigenDecompositor extends AbstractDecompositor implements MatrixDec
                     } else {
                         l = i;
                         if (e.get(i) == 0) {
-                            double cdiv[] = cdiv(-ra, -sa, w, q);
+                            double[] cdiv = cdiv(-ra, -sa, w, q);
                             H.set(i, n - 1, cdiv[0]);
                             H.set(i, n, cdiv[1]);
                         } else {
@@ -744,7 +757,7 @@ public class EigenDecompositor extends AbstractDecompositor implements MatrixDec
                                                 + Math.abs(x) + Math.abs(y) + Math
                                                     .abs(z));
                             }
-                            double cdiv[] = cdiv(x * r - z * ra + q * sa, 
+                            double[] cdiv = cdiv(x * r - z * ra + q * sa,
                                                  x * s - z * sa - q * ra, vr, vi);
                             H.set(i, n - 1, cdiv[0]);
                             H.set(i, n, cdiv[1]);
@@ -804,8 +817,10 @@ public class EigenDecompositor extends AbstractDecompositor implements MatrixDec
 
 
    private double[] cdiv(double xr, double xi, double yr, double yi) {
-        double cdivr, cdivi;
-        double r, d;
+        double cdivr;
+        double cdivi;
+        double r;
+        double d;
         if (Math.abs(yr) > Math.abs(yi)) {
             r = yi / yr;
             d = yr + r * yi;
diff --git a/src/main/java/org/la4j/decomposition/SingularValueDecompositor.java b/src/main/java/org/la4j/decomposition/SingularValueDecompositor.java
index 2ac3daa..5825ccf 100644
--- a/src/main/java/org/la4j/decomposition/SingularValueDecompositor.java
+++ b/src/main/java/org/la4j/decomposition/SingularValueDecompositor.java
@@ -275,7 +275,8 @@ public class SingularValueDecompositor extends AbstractDecompositor implements M
 
         while (p > 0) {
 
-            int k, kase;
+            int k;
+            int kase;
 
             for (k = p - 2; k >= -1; k--) {
                 if (k == -1)
diff --git a/src/main/java/org/la4j/iterator/CursorIterator.java b/src/main/java/org/la4j/iterator/CursorIterator.java
index 0b08a5e..8a4c667 100644
--- a/src/main/java/org/la4j/iterator/CursorIterator.java
+++ b/src/main/java/org/la4j/iterator/CursorIterator.java
@@ -21,10 +21,7 @@
 
 package org.la4j.iterator;
 
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.Iterator;
+import java.util.*;
 
 abstract class CursorIterator implements Iterator<Double> {
 
@@ -142,8 +139,10 @@ abstract class CursorIterator implements Iterator<Double> {
         final CursorIterator these = this;
         return new CursorIterator() {
             private boolean hasNext;
-            private double prevValue, currValue;
-            private int prevCursor, currCursor;
+            private double prevValue;
+            private double currValue;
+            private int prevCursor;
+            private int currCursor;
 
             {
                 doNext();
@@ -198,6 +197,9 @@ abstract class CursorIterator implements Iterator<Double> {
 
             @Override
             public Double next() {
+                if(!hasNext()) {
+                    throw new NoSuchElementException();
+                }
                 doNext();
                 return get();
             }
diff --git a/src/main/java/org/la4j/iterator/JoinFunction.java b/src/main/java/org/la4j/iterator/JoinFunction.java
index 91f95a1..d8f5aa0 100644
--- a/src/main/java/org/la4j/iterator/JoinFunction.java
+++ b/src/main/java/org/la4j/iterator/JoinFunction.java
@@ -24,8 +24,6 @@ package org.la4j.iterator;
 // TODO: need a better name
 abstract class JoinFunction {
 
-    public abstract double apply(double a, double b);
-
     public static final JoinFunction ADD = new JoinFunction() {
         @Override
         public double apply(double a, double b) {
@@ -60,4 +58,6 @@ abstract class JoinFunction {
             return a % b;
         }
     };
+
+    public abstract double apply(double a, double b);
 }
diff --git a/src/main/java/org/la4j/matrix/ColumnMajorSparseMatrix.java b/src/main/java/org/la4j/matrix/ColumnMajorSparseMatrix.java
index 58e26d0..d5c3996 100644
--- a/src/main/java/org/la4j/matrix/ColumnMajorSparseMatrix.java
+++ b/src/main/java/org/la4j/matrix/ColumnMajorSparseMatrix.java
@@ -31,11 +31,21 @@ import org.la4j.operation.MatrixOperation;
 import org.la4j.operation.MatrixVectorOperation;
 import org.la4j.Vector;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.Iterator;
 import java.util.Random;
 
 public abstract class ColumnMajorSparseMatrix extends SparseMatrix {
 
+    public ColumnMajorSparseMatrix(int rows, int columns) {
+        super(rows, columns);
+    }
+
+    public ColumnMajorSparseMatrix(int rows, int columns, int cardinality) {
+        super(rows, columns, cardinality);
+    }
+
     /**
      * Creates a zero {@link ColumnMajorSparseMatrix} of the given shape:
      * {@code rows} x {@code columns}.
@@ -118,22 +128,15 @@ public abstract class ColumnMajorSparseMatrix extends SparseMatrix {
     }
 
     /**
-     * Parses {@link ColumnMajorSparseMatrix} from the given Matrix Market string.
+     * Parses {@link ColumnMajorSparseMatrix} from the given Matrix Market.
      *
-     * @param mm the string in Matrix Market format
+     * @param is the input stream in Matrix Market format
      *
      * @return a parsed matrix
+     * @exception  IOException  if an I/O error occurs.
      */
-    public static ColumnMajorSparseMatrix fromMatrixMarket(String mm) {
-        return Matrix.fromMatrixMarket(mm).to(Matrices.SPARSE_COLUMN_MAJOR);
-    }
-
-    public ColumnMajorSparseMatrix(int rows, int columns) {
-        super(rows, columns);
-    }
-
-    public ColumnMajorSparseMatrix(int rows, int columns, int cardinality) {
-        super(rows, columns, cardinality);
+    public static ColumnMajorSparseMatrix fromMatrixMarket(InputStream is) throws IOException {
+        return Matrix.fromMatrixMarket(is).to(Matrices.SPARSE_COLUMN_MAJOR);
     }
 
     @Override
diff --git a/src/main/java/org/la4j/matrix/DenseMatrix.java b/src/main/java/org/la4j/matrix/DenseMatrix.java
index a5e6505..68ac90b 100644
--- a/src/main/java/org/la4j/matrix/DenseMatrix.java
+++ b/src/main/java/org/la4j/matrix/DenseMatrix.java
@@ -31,11 +31,17 @@ import org.la4j.operation.MatrixVectorOperation;
 import org.la4j.Vector;
 import org.la4j.vector.DenseVector;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.text.NumberFormat;
 import java.util.Random;
 
 public abstract class DenseMatrix extends Matrix {
 
+    public DenseMatrix(int rows, int columns) {
+        super(rows, columns);
+    }
+
     /**
      * Creates a zero {@link DenseMatrix} of the given shape:
      * {@code rows} x {@code columns}.
@@ -125,18 +131,15 @@ public abstract class DenseMatrix extends Matrix {
     }
 
     /**
-     * Parses {@link DenseMatrix} from the given Matrix Market string.
+     * Parses {@link DenseMatrix} from the given Matrix Market.
      *
-     * @param mm the string in Matrix Market format
+     * @param is the input stream in Matrix Market format
      *
      * @return a parsed matrix
+     * @exception  IOException  if an I/O error occurs.
      */
-    public static DenseMatrix fromMatrixMarket(String mm) {
-        return Matrix.fromMatrixMarket(mm).to(Matrices.DENSE);
-    }
-
-    public DenseMatrix(int rows, int columns) {
-        super(rows, columns);
+    public static DenseMatrix fromMatrixMarket(InputStream is) throws IOException {
+        return Matrix.fromMatrixMarket(is).to(Matrices.DENSE);
     }
 
     /**
diff --git a/src/main/java/org/la4j/matrix/RowMajorSparseMatrix.java b/src/main/java/org/la4j/matrix/RowMajorSparseMatrix.java
index ebfacad..b297547 100644
--- a/src/main/java/org/la4j/matrix/RowMajorSparseMatrix.java
+++ b/src/main/java/org/la4j/matrix/RowMajorSparseMatrix.java
@@ -31,6 +31,8 @@ import org.la4j.operation.MatrixOperation;
 import org.la4j.operation.MatrixVectorOperation;
 import org.la4j.Vector;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
@@ -38,6 +40,14 @@ import java.util.Random;
 
 public abstract class RowMajorSparseMatrix extends SparseMatrix {
 
+    public RowMajorSparseMatrix(int rows, int columns) {
+        super(rows, columns);
+    }
+
+    public RowMajorSparseMatrix(int rows, int columns, int cardinality) {
+        super(rows, columns, cardinality);
+    }
+
     /**
      * Creates a zero {@link RowMajorSparseMatrix} of the given shape:
      * {@code rows} x {@code columns}.
@@ -120,22 +130,15 @@ public abstract class RowMajorSparseMatrix extends SparseMatrix {
     }
 
     /**
-     * Parses {@link RowMajorSparseMatrix} from the given Matrix Market string.
+     * Parses {@link RowMajorSparseMatrix} from the given Matrix Market.
      *
-     * @param mm the string in Matrix Market format
+     * @param is the input stream in Matrix Market format
      *
      * @return a parsed matrix
+     * @exception  IOException  if an I/O error occurs.
      */
-    public static RowMajorSparseMatrix fromMatrixMarket(String mm) {
-        return Matrix.fromMatrixMarket(mm).to(Matrices.SPARSE_ROW_MAJOR);
-    }
-
-    public RowMajorSparseMatrix(int rows, int columns) {
-        super(rows, columns);
-    }
-
-    public RowMajorSparseMatrix(int rows, int columns, int cardinality) {
-        super(rows, columns, cardinality);
+    public static RowMajorSparseMatrix fromMatrixMarket(InputStream is) throws IOException {
+        return Matrix.fromMatrixMarket(is).to(Matrices.SPARSE_ROW_MAJOR);
     }
 
     @Override
diff --git a/src/main/java/org/la4j/matrix/SparseMatrix.java b/src/main/java/org/la4j/matrix/SparseMatrix.java
index 222e2a7..e2f561d 100644
--- a/src/main/java/org/la4j/matrix/SparseMatrix.java
+++ b/src/main/java/org/la4j/matrix/SparseMatrix.java
@@ -37,11 +37,25 @@ import org.la4j.vector.functor.VectorAccumulator;
 import org.la4j.vector.functor.VectorProcedure;
 import org.la4j.vector.SparseVector;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.text.NumberFormat;
+import java.util.NoSuchElementException;
 import java.util.Random;
 
 public abstract class SparseMatrix extends Matrix {
 
+    protected int cardinality;
+
+    public SparseMatrix(int rows, int columns) {
+        this(rows, columns, 0);
+    }
+
+    public SparseMatrix(int rows, int columns, int cardinality) {
+        super(rows, columns);
+        this.cardinality = cardinality;
+    }
+
     /**
      * Creates a zero {@link SparseMatrix} of the given shape:
      * {@code rows} x {@code columns}.
@@ -124,25 +138,15 @@ public abstract class SparseMatrix extends Matrix {
     }
 
     /**
-     * Parses {@link SparseMatrix} from the given Matrix Market string.
+     * Parses {@link SparseMatrix} from the given Matrix Market.
      *
-     * @param mm the string in Matrix Market format
+     * @param is the input stream in Matrix Market format
      *
      * @return a parsed matrix
+     * @exception  IOException  if an I/O error occurs.
      */
-    public static SparseMatrix fromMatrixMarket(String mm) {
-        return Matrix.fromMatrixMarket(mm).to(Matrices.SPARSE);
-    }
-
-    protected int cardinality;
-
-    public SparseMatrix(int rows, int columns) {
-        this(rows, columns, 0);
-    }
-
-    public SparseMatrix(int rows, int columns, int cardinality) {
-        super(rows, columns);
-        this.cardinality = cardinality;
+    public static SparseMatrix fromMatrixMarket(InputStream is) throws IOException {
+        return Matrix.fromMatrixMarket(is).to(Matrices.SPARSE);
     }
 
     @Override
@@ -452,6 +456,9 @@ public abstract class SparseMatrix extends Matrix {
 
             @Override
             public Double next() {
+                if(!hasNext()) {
+                    throw new NoSuchElementException();
+                }
                 i++;
                 return get();
             }
@@ -503,6 +510,9 @@ public abstract class SparseMatrix extends Matrix {
 
             @Override
             public Double next() {
+                if(!hasNext()) {
+                    throw new NoSuchElementException();
+                }
                 i++;
                 return get();
             }
@@ -545,6 +555,9 @@ public abstract class SparseMatrix extends Matrix {
 
             @Override
             public Double next() {
+                if(!hasNext()) {
+                    throw new NoSuchElementException();
+                }
                 j++;
                 return get();
             }
@@ -587,6 +600,9 @@ public abstract class SparseMatrix extends Matrix {
 
             @Override
             public Double next() {
+                if(!hasNext()) {
+                    throw new NoSuchElementException();
+                }
                 i++;
                 return get();
             }
diff --git a/src/main/java/org/la4j/matrix/dense/Basic1DMatrix.java b/src/main/java/org/la4j/matrix/dense/Basic1DMatrix.java
index 1775b53..9027bd1 100644
--- a/src/main/java/org/la4j/matrix/dense/Basic1DMatrix.java
+++ b/src/main/java/org/la4j/matrix/dense/Basic1DMatrix.java
@@ -21,6 +21,8 @@
 
 package org.la4j.matrix.dense;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
 import java.util.Random;
@@ -36,6 +38,21 @@ public class Basic1DMatrix extends DenseMatrix {
 
     private static final byte MATRIX_TAG = (byte) 0x00;
 
+    private double[] self;
+
+    public Basic1DMatrix() {
+        this(0, 0);
+    }
+
+    public Basic1DMatrix(int rows, int columns) {
+        this(rows, columns, new double[rows * columns]);
+    }
+
+    public Basic1DMatrix(int rows, int columns, double[] array) {
+        super(rows, columns);
+        this.self = array;
+    }
+
     /**
      * Creates a zero {@link Basic1DMatrix} of the given shape:
      * {@code rows} x {@code columns}.
@@ -48,7 +65,7 @@ public class Basic1DMatrix extends DenseMatrix {
      * Creates a constant {@link Basic1DMatrix} of the given shape and {@code value}.
      */
     public static Basic1DMatrix constant(int rows, int columns, double constant) {
-        double array[] = new double[rows * columns];
+        double[] array = new double[rows * columns];
         Arrays.fill(array, constant);
 
         return new Basic1DMatrix(rows, columns, array);
@@ -59,7 +76,7 @@ public class Basic1DMatrix extends DenseMatrix {
      * diagonal elements are equal to {@code diagonal}.
      */
     public static Basic1DMatrix diagonal(int size, double diagonal) {
-        double array[] = new double[size * size];
+        double[] array = new double[size * size];
 
         for (int i = 0; i < size; i++) {
             array[i * size + i] = diagonal;
@@ -88,7 +105,7 @@ public class Basic1DMatrix extends DenseMatrix {
      * {@code rows} x {@code columns}.
      */
     public static Basic1DMatrix random(int rows, int columns, Random random) {
-        double array[] = new double[rows * columns];
+        double[] array = new double[rows * columns];
 
         for (int i = 0; i < rows * columns; i++) {
             array[i] = random.nextDouble();
@@ -101,7 +118,7 @@ public class Basic1DMatrix extends DenseMatrix {
      * Creates a random symmetric {@link Basic1DMatrix} of the given {@code size}.
      */
     public static Basic1DMatrix randomSymmetric(int size, Random random) {
-        double array[] = new double[size * size];
+        double[] array = new double[size * size];
 
         for (int i = 0; i < size; i++) {
             for (int j = i; j < size; j++) {
@@ -150,8 +167,9 @@ public class Basic1DMatrix extends DenseMatrix {
             throw new IllegalArgumentException("Sides of blocks are incompatible!");
         }
 
-        int rows = a.rows() + c.rows(), columns = a.columns() + b.columns();
-        double array[] = new double[rows * columns];
+        int rows = a.rows() + c.rows();
+        int columns = a.columns() + b.columns();
+        double[] array = new double[rows * columns];
 
         for (int i = 0; i < rows; i++) {
             for (int j = 0; j < columns; j++) {
@@ -211,29 +229,15 @@ public class Basic1DMatrix extends DenseMatrix {
     }
 
     /**
-     * Parses {@link Basic1DMatrix} from the given Matrix Market string.
+     * Parses {@link Basic1DMatrix} from the given Matrix Market.
      *
-     * @param mm the string in Matrix Market format
+     * @param is the input stream in Matrix Market format
      *
      * @return a parsed matrix
+     * @exception  IOException  if an I/O error occurs.
      */
-    public static Basic1DMatrix fromMatrixMarket(String mm) {
-        return Matrix.fromMatrixMarket(mm).to(Matrices.BASIC_1D);
-    }
-
-    private double self[];
-
-    public Basic1DMatrix() {
-        this(0, 0);
-    }
-
-    public Basic1DMatrix(int rows, int columns) {
-        this(rows, columns, new double[rows * columns]);
-    }
-
-    public Basic1DMatrix(int rows, int columns, double array[]) {
-        super(rows, columns);
-        this.self = array;
+    public static Basic1DMatrix fromMatrixMarket(InputStream is) throws IOException {
+        return Matrix.fromMatrixMarket(is).to(Matrices.BASIC_1D);
     }
 
     @Override
@@ -277,7 +281,7 @@ public class Basic1DMatrix extends DenseMatrix {
 
     @Override
     public Vector getRow(int i) {
-        double result[] = new double[columns];
+        double[] result = new double[columns];
         System.arraycopy(self, i * columns , result, 0, columns);
 
         return new BasicVector(result);
@@ -288,7 +292,7 @@ public class Basic1DMatrix extends DenseMatrix {
         ensureDimensionsAreCorrect(rows, columns);
 
         if (this.rows < rows && this.columns == columns) {
-            double $self[] = new double[rows * columns];
+            double[] $self = new double[rows * columns];
             System.arraycopy(self, 0, $self, 0, this.rows * columns);
 
             return new Basic1DMatrix(rows, columns, $self);
@@ -310,7 +314,7 @@ public class Basic1DMatrix extends DenseMatrix {
     @Override
     public double[][] toArray() {
 
-        double result[][] = new double[rows][columns];
+        double[][] result = new double[rows][columns];
 
         int offset = 0;
         for (int i = 0; i < rows; i++) {
diff --git a/src/main/java/org/la4j/matrix/dense/Basic2DMatrix.java b/src/main/java/org/la4j/matrix/dense/Basic2DMatrix.java
index ff19828..8440cfa 100644
--- a/src/main/java/org/la4j/matrix/dense/Basic2DMatrix.java
+++ b/src/main/java/org/la4j/matrix/dense/Basic2DMatrix.java
@@ -21,6 +21,8 @@
 
 package org.la4j.matrix.dense;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
 import java.util.Random;
@@ -36,6 +38,21 @@ public class Basic2DMatrix extends DenseMatrix {
 
     private static final byte MATRIX_TAG = (byte) 0x10;
 
+    private double[][] self;
+
+    public Basic2DMatrix() {
+        this(0, 0);
+    }
+
+    public Basic2DMatrix(int rows, int columns) {
+        this(new double[rows][columns]);
+    }
+
+    public Basic2DMatrix(double[][] array) {
+        super(array.length, array.length == 0 ? 0: array[0].length);
+        this.self = array;
+    }
+
     /**
      * Creates a zero {@link Basic2DMatrix} of the given shape:
      * {@code rows} x {@code columns}.
@@ -48,7 +65,7 @@ public class Basic2DMatrix extends DenseMatrix {
      * Creates a constant {@link Basic2DMatrix} of the given shape and {@code value}.
      */
     public static Basic2DMatrix constant(int rows, int columns, double constant) {
-        double array[][] = new double[rows][columns];
+        double[][] array = new double[rows][columns];
 
         for (int i = 0; i < rows; i++) {
             Arrays.fill(array[i], constant);
@@ -62,7 +79,7 @@ public class Basic2DMatrix extends DenseMatrix {
      * diagonal elements are equal to {@code diagonal}.
      */
     public static Basic2DMatrix diagonal(int size, double diagonal) {
-        double array[][] = new double[size][size];
+        double[][] array = new double[size][size];
 
         for (int i = 0; i < size; i++) {
             array[i][i] = diagonal;
@@ -91,7 +108,7 @@ public class Basic2DMatrix extends DenseMatrix {
      * {@code rows} x {@code columns}.
      */
     public static Basic2DMatrix random(int rows, int columns, Random random) {
-        double array[][] = new double[rows][columns];
+        double[][] array = new double[rows][columns];
 
         for (int i = 0; i < rows; i++) {
             for (int j = 0; j < columns; j++) {
@@ -106,7 +123,7 @@ public class Basic2DMatrix extends DenseMatrix {
      * Creates a random symmetric {@link Basic2DMatrix} of the given {@code size}.
      */
     public static Basic2DMatrix randomSymmetric(int size, Random random) {
-        double array[][] = new double[size][size];
+        double[][] array = new double[size][size];
 
         for (int i = 0; i < size; i++) {
             for (int j = i; j < size; j++) {
@@ -151,8 +168,9 @@ public class Basic2DMatrix extends DenseMatrix {
             throw new IllegalArgumentException("Sides of blocks are incompatible!");
         }
 
-        int rows = a.rows() + c.rows(), columns = a.columns() + b.columns();
-        double array[][] = new double[rows][columns];
+        int rows = a.rows() + c.rows();
+        int columns = a.columns() + b.columns();
+        double[][] array = new double[rows][columns];
 
         for (int i = 0; i < rows; i++) {
             for (int j = 0; j < columns; j++) {
@@ -213,29 +231,15 @@ public class Basic2DMatrix extends DenseMatrix {
     }
 
     /**
-     * Parses {@link Basic2DMatrix} from the given Matrix Market string.
+     * Parses {@link Basic2DMatrix} from the given Matrix Market.
      *
-     * @param mm the string in Matrix Market format
+     * @param is the input stream in Matrix Market format
      *
      * @return a parsed matrix
+     * @exception  IOException  if an I/O error occurs.
      */
-    public static Basic2DMatrix fromMatrixMarket(String mm) {
-        return Matrix.fromMatrixMarket(mm).to(Matrices.BASIC_2D);
-    }
-
-    private double self[][];
-
-    public Basic2DMatrix() {
-        this(0, 0);
-    }
-
-    public Basic2DMatrix(int rows, int columns) {
-        this(new double[rows][columns]);
-    }
-
-    public Basic2DMatrix(double array[][]) {
-        super(array.length, array.length == 0 ? 0: array[0].length);
-        this.self = array;
+    public static Basic2DMatrix fromMatrixMarket(InputStream is) throws IOException {
+        return Matrix.fromMatrixMarket(is).to(Matrices.BASIC_2D);
     }
 
     @Override
@@ -258,7 +262,7 @@ public class Basic2DMatrix extends DenseMatrix {
     @Override
     public void swapRows(int i, int j) {
         if (i != j) {
-            double tmp[] = self[i];
+            double[] tmp = self[i];
             self[i] = self[j];
             self[j] = tmp;
         }
@@ -277,7 +281,7 @@ public class Basic2DMatrix extends DenseMatrix {
 
     @Override
     public Vector getRow(int i) {
-        double result[] = new double[columns];
+        double[] result = new double[columns];
         System.arraycopy(self[i], 0, result, 0, columns);
 
         return new BasicVector(result);
@@ -287,7 +291,7 @@ public class Basic2DMatrix extends DenseMatrix {
     public Matrix copyOfShape(int rows, int columns) {
         ensureDimensionsAreCorrect(rows, columns);
 
-        double $self[][] = new double[rows][columns];
+        double[][] $self = new double[rows][columns];
         for (int i = 0; i < Math.min(this.rows, rows); i++) {
             System.arraycopy(self[i], 0, $self[i], 0, Math.min(this.columns, columns));
         }
@@ -297,7 +301,7 @@ public class Basic2DMatrix extends DenseMatrix {
 
     @Override
     public double[][] toArray() {
-        double result[][] = new double[rows][columns];
+        double[][] result = new double[rows][columns];
 
         for (int i = 0; i < rows; i++) {
             System.arraycopy(self[i], 0, result[i], 0, columns);
diff --git a/src/main/java/org/la4j/matrix/sparse/CCSMatrix.java b/src/main/java/org/la4j/matrix/sparse/CCSMatrix.java
index ca2847c..f5b84b2 100644
--- a/src/main/java/org/la4j/matrix/sparse/CCSMatrix.java
+++ b/src/main/java/org/la4j/matrix/sparse/CCSMatrix.java
@@ -25,11 +25,11 @@
 
 package org.la4j.matrix.sparse;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.Random;
+import java.util.*;
+
 import org.la4j.iterator.ColumnMajorMatrixIterator;
 import org.la4j.iterator.VectorIterator;
 import org.la4j.Matrices;
@@ -48,6 +48,38 @@ import org.la4j.vector.sparse.CompressedVector;
 public class CCSMatrix extends ColumnMajorSparseMatrix {
 
     private static final byte MATRIX_TAG = (byte) 0x30;
+    private static final int MINIMUM_SIZE = 32;
+
+    private double[] values;
+    private int[] rowIndices;
+    private int[] columnPointers;
+
+    public CCSMatrix() {
+        this(0, 0);
+    }
+
+    public CCSMatrix(int rows, int columns) {
+        this (rows, columns, 0);
+    }
+
+    public CCSMatrix(int rows, int columns, int capacity) {
+        super(rows, columns);
+        ensureCardinalityIsCorrect(rows, columns, capacity);
+
+        int alignedSize = align(capacity);
+        this.values = new double[alignedSize];
+        this.rowIndices = new int[alignedSize];
+        this.columnPointers = new int[columns + 1];
+    }
+
+    public CCSMatrix(int rows, int columns, int cardinality, double[] values, int[] rowIndices, int[] columnPointers) {
+        super(rows, columns, cardinality);
+        ensureCardinalityIsCorrect(rows, columns, cardinality);
+
+        this.values = values;
+        this.rowIndices = rowIndices;
+        this.columnPointers = columnPointers;
+    }
 
     /**
      * Creates a zero {@link CCSMatrix} of the given shape:
@@ -70,9 +102,9 @@ public class CCSMatrix extends ColumnMajorSparseMatrix {
      * diagonal elements are equal to {@code diagonal}.
      */
     public static CCSMatrix diagonal(int size, double diagonal) {
-        double values[] = new double[size];
-        int rowIndices[] = new int[size];
-        int columnPointers[] = new int[size + 1];
+        double[] values = new double[size];
+        int[] rowIndices = new int[size];
+        int[] columnPointers = new int[size + 1];
 
         for (int i = 0; i < size; i++) {
             rowIndices[i] = i;
@@ -103,12 +135,12 @@ public class CCSMatrix extends ColumnMajorSparseMatrix {
 
         int cardinality = Math.max((int)((rows * columns) * density), columns);
 
-        double values[] = new double[cardinality];
-        int rowIndices[] = new int[cardinality];
-        int columnPointers[] = new int[columns + 1];
+        double[] values = new double[cardinality];
+        int[] rowIndices = new int[cardinality];
+        int[] columnPointers = new int[columns + 1];
 
         int kk = cardinality / columns;
-        int indices[] = new int[kk];
+        int[] indices = new int[kk];
 
         int k = 0;
         for (int j = 0; j < columns; j++) {
@@ -215,10 +247,11 @@ public class CCSMatrix extends ColumnMajorSparseMatrix {
             throw new IllegalArgumentException("Sides of blocks are incompatible!");
         }
 
-        int rows = a.rows() + c.rows(), columns = a.columns() + b.columns();
+        int rows = a.rows() + c.rows();
+        int columns = a.columns() + b.columns();
         ArrayList<Double> values = new ArrayList<Double>();
         ArrayList<Integer> rowIndices = new ArrayList<Integer>();
-        int columnPointers[] = new int[rows + 1];
+        int[] columnPointers = new int[rows + 1];
 
         int k = 0;
         columnPointers[0] = 0;
@@ -245,8 +278,8 @@ public class CCSMatrix extends ColumnMajorSparseMatrix {
             }
             columnPointers[i + 1] = k;
         }
-        double valuesArray[] = new double[values.size()];
-        int rowIndArray[] = new int[rowIndices.size()];
+        double[] valuesArray = new double[values.size()];
+        int[] rowIndArray = new int[rowIndices.size()];
         for (int i = 0; i < values.size(); i++) {
             valuesArray[i] = values.get(i);
             rowIndArray[i] = rowIndices.get(i);
@@ -301,47 +334,15 @@ public class CCSMatrix extends ColumnMajorSparseMatrix {
     }
 
     /**
-     * Parses {@link CCSMatrix} from the given Matrix Market string.
+     * Parses {@link CCSMatrix} from the given Matrix Market.
      *
-     * @param mm the string in Matrix Market format
+     * @param is the input stream in Matrix Market format
      *
      * @return a parsed matrix
+     * @exception  IOException  if an I/O error occurs.
      */
-    public static CCSMatrix fromMatrixMarket(String mm) {
-        return Matrix.fromMatrixMarket(mm).to(Matrices.CCS);
-    }
-
-    private static final int MINIMUM_SIZE = 32;
-
-    private double values[];
-    private int rowIndices[];
-    private int columnPointers[];
-
-    public CCSMatrix() {
-        this(0, 0);
-    }
-
-    public CCSMatrix(int rows, int columns) {
-        this (rows, columns, 0);
-    }
-
-    public CCSMatrix(int rows, int columns, int capacity) {
-        super(rows, columns);
-        ensureCardinalityIsCorrect(rows, columns, capacity);
-
-        int alignedSize = align(capacity);
-        this.values = new double[alignedSize];
-        this.rowIndices = new int[alignedSize];
-        this.columnPointers = new int[columns + 1];
-    }
-
-    public CCSMatrix(int rows, int columns, int cardinality, double values[], int rowIndices[], int columnPointers[]) {
-        super(rows, columns, cardinality);
-        ensureCardinalityIsCorrect(rows, columns, cardinality);
-
-        this.values = values;
-        this.rowIndices = rowIndices;
-        this.columnPointers = columnPointers;
+    public static CCSMatrix fromMatrixMarket(InputStream is) throws IOException {
+        return Matrix.fromMatrixMarket(is).to(Matrices.CCS);
     }
 
     @Override
@@ -402,8 +403,8 @@ public class CCSMatrix extends ColumnMajorSparseMatrix {
     @Override
     public Vector getColumn(int j) {
         int columnCardinality = columnPointers[j + 1] - columnPointers[j];
-        double columnValues[] = new double[columnCardinality];
-        int columnIndices[] = new int[columnCardinality];
+        double[] columnValues = new double[columnCardinality];
+        int[] columnIndices = new int[columnCardinality];
 
         System.arraycopy(values, columnPointers[j], columnValues, 0, 
                          columnCardinality);
@@ -436,9 +437,9 @@ public class CCSMatrix extends ColumnMajorSparseMatrix {
         ensureDimensionsAreCorrect(rows, columns);
 
         if (rows >= this.rows && columns >= this.columns) {
-            double $values[] = new double[align(cardinality)];
-            int $rowIndices[] = new int[align(cardinality)];
-            int $columnPointers[] = new int[columns + 1];
+            double[] $values = new double[align(cardinality)];
+            int[] $rowIndices = new int[align(cardinality)];
+            int[] $columnPointers = new int[columns + 1];
 
             System.arraycopy(values, 0, $values, 0, cardinality);
             System.arraycopy(rowIndices, 0, $rowIndices, 0, cardinality);
@@ -451,13 +452,14 @@ public class CCSMatrix extends ColumnMajorSparseMatrix {
             return new CCSMatrix(rows, columns, cardinality, $values, $rowIndices, $columnPointers);
         }
 
-        double $values[] = new double[align(cardinality)];
-        int $rowIndices[] = new int[align(cardinality)];
-        int $columnPointers[] = new int[columns + 1];
+        double[] $values = new double[align(cardinality)];
+        int[] $rowIndices = new int[align(cardinality)];
+        int[] $columnPointers = new int[columns + 1];
 
         int $cardinality = 0;
 
-        int k = 0, j = 0;
+        int k = 0;
+        int j = 0;
         while (k < cardinality && j < columns) {
 
             $columnPointers[j] = $cardinality;
@@ -481,7 +483,8 @@ public class CCSMatrix extends ColumnMajorSparseMatrix {
 
     @Override
     public void eachNonZero(MatrixProcedure procedure) {
-        int k = 0, j = 0;
+        int k = 0;
+        int j = 0;
         while (k < cardinality) {
             for (int i = columnPointers[j]; i < columnPointers[j + 1]; i++, k++) {
                 procedure.apply(rowIndices[i], j, values[i]);
@@ -631,8 +634,8 @@ public class CCSMatrix extends ColumnMajorSparseMatrix {
             );
         int capacity = Math.min(min, (cardinality * 3) / 2 + 1);
 
-        double $values[] = new double[capacity];
-        int $rowIndices[] = new int[capacity];
+        double[] $values = new double[capacity];
+        int[] $rowIndices = new int[capacity];
 
         System.arraycopy(values, 0, $values, 0, cardinality);
         System.arraycopy(rowIndices, 0, $rowIndices, 0, cardinality);
@@ -777,6 +780,9 @@ public class CCSMatrix extends ColumnMajorSparseMatrix {
 
             @Override
             public Integer next() {
+                if(!hasNext()) {
+                    throw new NoSuchElementException();
+                }
                 j++;
                 return j;
             }
@@ -833,6 +839,10 @@ public class CCSMatrix extends ColumnMajorSparseMatrix {
 
             @Override
             public Double next() {
+                if(!hasNext()) {
+                    throw new NoSuchElementException();
+                }
+
                 if (currentNonZero) {
                     k++;
                 }
@@ -889,6 +899,9 @@ public class CCSMatrix extends ColumnMajorSparseMatrix {
 
             @Override
             public Double next() {
+                if(!hasNext()) {
+                    throw new NoSuchElementException();
+                }
                 currentIsRemoved = false;
                 k++;
                 while (columnPointers[j + 1] == k) {
@@ -938,6 +951,9 @@ public class CCSMatrix extends ColumnMajorSparseMatrix {
 
             @Override
             public Double next() {
+                if(!hasNext()) {
+                    throw new NoSuchElementException();
+                }
                 currentIsRemoved = false;
                 return values[++k];
             }
@@ -984,6 +1000,9 @@ public class CCSMatrix extends ColumnMajorSparseMatrix {
 
             @Override
             public Double next() {
+                if(!hasNext()) {
+                    throw new NoSuchElementException();
+                }
                 i++;
                 if (k < columnPointers[jj + 1] && rowIndices[k] == i - 1) {
                     k++;
diff --git a/src/main/java/org/la4j/matrix/sparse/CRSMatrix.java b/src/main/java/org/la4j/matrix/sparse/CRSMatrix.java
index 5c0cbac..4289d0c 100644
--- a/src/main/java/org/la4j/matrix/sparse/CRSMatrix.java
+++ b/src/main/java/org/la4j/matrix/sparse/CRSMatrix.java
@@ -25,11 +25,10 @@
 
 package org.la4j.matrix.sparse;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.Random;
+import java.util.*;
 
 import org.la4j.iterator.RowMajorMatrixIterator;
 import org.la4j.iterator.VectorIterator;
@@ -49,6 +48,38 @@ import org.la4j.vector.sparse.CompressedVector;
 public class CRSMatrix extends RowMajorSparseMatrix {
 
     private static final byte MATRIX_TAG = (byte) 0x20;
+    private static final int MINIMUM_SIZE = 32;
+
+    private double[] values;
+    private int[] columnIndices;
+    private int[] rowPointers;
+
+    public CRSMatrix() {
+        this(0, 0);
+    }
+
+    public CRSMatrix(int rows, int columns) {
+        this(rows, columns, 0);
+    }
+
+    public CRSMatrix(int rows, int columns, int capacity) {
+        super(rows, columns);
+        ensureCardinalityIsCorrect(rows, columns, capacity);
+
+        int alignedSize = align(capacity);
+        this.values = new double[alignedSize];
+        this.columnIndices = new int[alignedSize];
+        this.rowPointers = new int[rows + 1];
+    }
+
+    public CRSMatrix(int rows, int columns, int cardinality, double[] values, int[] columnIndices, int[] rowPointers) {
+        super(rows, columns, cardinality);
+        ensureCardinalityIsCorrect(rows, columns, cardinality);
+
+        this.values = values;
+        this.columnIndices = columnIndices;
+        this.rowPointers = rowPointers;
+    }
 
     /**
      * Creates a zero {@link CRSMatrix} of the given shape:
@@ -71,9 +102,9 @@ public class CRSMatrix extends RowMajorSparseMatrix {
      * diagonal elements are equal to {@code diagonal}.
      */
     public static CRSMatrix diagonal(int size, double diagonal) {
-        double values[] = new double[size];
-        int columnIndices[] = new int[size];
-        int rowPointers[] = new int[size + 1];
+        double[] values = new double[size];
+        int[] columnIndices = new int[size];
+        int[] rowPointers = new int[size + 1];
 
         for (int i = 0; i < size; i++) {
             columnIndices[i] = i;
@@ -104,12 +135,12 @@ public class CRSMatrix extends RowMajorSparseMatrix {
 
         int cardinality = Math.max((int) ((rows * columns) * density), rows);
 
-        double values[] = new double[cardinality];
-        int columnIndices[] = new int[cardinality];
-        int rowPointers[] = new int[rows + 1];
+        double[] values = new double[cardinality];
+        int[] columnIndices = new int[cardinality];
+        int[] rowPointers = new int[rows + 1];
 
         int kk = cardinality / rows;
-        int indices[] = new int[kk];
+        int[] indices = new int[kk];
 
         int k = 0;
         for (int i = 0; i < rows; i++) {
@@ -216,10 +247,11 @@ public class CRSMatrix extends RowMajorSparseMatrix {
             throw new IllegalArgumentException("Sides of blocks are incompatible!");
         }
 
-        int rows = a.rows() + c.rows(), columns = a.columns() + b.columns();
+        int rows = a.rows() + c.rows();
+        int columns = a.columns() + b.columns();
         ArrayList<Double> values = new ArrayList<Double>();
         ArrayList<Integer> columnIndices = new ArrayList<Integer>();
-        int rowPointers[] = new int[rows + 1];
+        int[] rowPointers = new int[rows + 1];
 
         int k = 0;
         rowPointers[0] = 0;
@@ -246,8 +278,8 @@ public class CRSMatrix extends RowMajorSparseMatrix {
             }
             rowPointers[i + 1] = k;
         }
-        double valuesArray[] = new double[values.size()];
-        int colIndArray[] = new int[columnIndices.size()];
+        double[] valuesArray = new double[values.size()];
+        int[] colIndArray = new int[columnIndices.size()];
         for (int i = 0; i < values.size(); i++) {
             valuesArray[i] = values.get(i);
             colIndArray[i] = columnIndices.get(i);
@@ -302,47 +334,15 @@ public class CRSMatrix extends RowMajorSparseMatrix {
     }
 
     /**
-     * Parses {@link CRSMatrix} from the given Matrix Market string.
+     * Parses {@link CRSMatrix} from the given Matrix Market.
      *
-     * @param mm the string in Matrix Market format
+     * @param is the input stream in Matrix Market format
      *
      * @return a parsed matrix
+     * @exception  IOException  if an I/O error occurs.
      */
-    public static CRSMatrix fromMatrixMarket(String mm) {
-        return Matrix.fromMatrixMarket(mm).to(Matrices.CRS);
-    }
-
-    private static final int MINIMUM_SIZE = 32;
-
-    private double values[];
-    private int columnIndices[];
-    private int rowPointers[];
-
-    public CRSMatrix() {
-        this(0, 0);
-    }
-
-    public CRSMatrix(int rows, int columns) {
-        this(rows, columns, 0);
-    }
-
-    public CRSMatrix(int rows, int columns, int capacity) {
-        super(rows, columns);
-        ensureCardinalityIsCorrect(rows, columns, capacity);
-
-        int alignedSize = align(capacity);
-        this.values = new double[alignedSize];
-        this.columnIndices = new int[alignedSize];
-        this.rowPointers = new int[rows + 1];
-    }
-
-    public CRSMatrix(int rows, int columns, int cardinality, double values[], int columnIndices[], int rowPointers[]) {
-        super(rows, columns, cardinality);
-        ensureCardinalityIsCorrect(rows, columns, cardinality);
-
-        this.values = values;
-        this.columnIndices = columnIndices;
-        this.rowPointers = rowPointers;
+    public static CRSMatrix fromMatrixMarket(InputStream is) throws IOException {
+        return Matrix.fromMatrixMarket(is).to(Matrices.CRS);
     }
 
     @Override
@@ -403,8 +403,8 @@ public class CRSMatrix extends RowMajorSparseMatrix {
     @Override
     public Vector getRow(int i) {
         int rowCardinality = rowPointers[i + 1] - rowPointers[i];
-        double rowValues[] = new double[rowCardinality];
-        int rowIndices[] = new int[rowCardinality];
+        double[] rowValues = new double[rowCardinality];
+        int[] rowIndices = new int[rowCardinality];
 
         System.arraycopy(values, rowPointers[i], rowValues, 0, rowCardinality);
         System.arraycopy(columnIndices, rowPointers[i], rowIndices, 
@@ -436,9 +436,9 @@ public class CRSMatrix extends RowMajorSparseMatrix {
         ensureDimensionsAreCorrect(rows, columns);
 
         if (rows >= this.rows && columns >= this.columns) {
-            double $values[] = new double[align(cardinality)];
-            int $columnIndices[] = new int[align(cardinality)];
-            int $rowPointers[] = new int[rows + 1];
+            double[] $values = new double[align(cardinality)];
+            int[] $columnIndices = new int[align(cardinality)];
+            int[] $rowPointers = new int[rows + 1];
 
             System.arraycopy(values, 0, $values, 0, cardinality);
             System.arraycopy(columnIndices, 0, $columnIndices, 0, cardinality);
@@ -451,13 +451,14 @@ public class CRSMatrix extends RowMajorSparseMatrix {
             return new CRSMatrix(rows, columns, cardinality, $values, $columnIndices, $rowPointers);
         }
 
-        double $values[] = new double[align(cardinality)];
-        int $columnIndices[] = new int[align(cardinality)];
-        int $rowPointers[] = new int[rows + 1];
+        double[] $values = new double[align(cardinality)];
+        int[] $columnIndices = new int[align(cardinality)];
+        int[] $rowPointers = new int[rows + 1];
 
         int $cardinality = 0;
 
-        int k = 0, i = 0;
+        int k = 0;
+        int i = 0;
         while (k < cardinality && i < rows) {
 
             $rowPointers[i] = $cardinality;
@@ -481,7 +482,8 @@ public class CRSMatrix extends RowMajorSparseMatrix {
 
     @Override
     public void eachNonZero(MatrixProcedure procedure) {
-        int k = 0, i = 0;
+        int k = 0;
+        int i = 0;
         while (k < cardinality) {
             for (int j = rowPointers[i]; j < rowPointers[i + 1]; j++, k++) {
                 procedure.apply(i, columnIndices[j], values[j]);
@@ -630,8 +632,8 @@ public class CRSMatrix extends RowMajorSparseMatrix {
             );
         int capacity = Math.min(min, (cardinality * 3) / 2 + 1);
 
-        double $values[] = new double[capacity];
-        int $columnIndices[] = new int[capacity];
+        double[] $values = new double[capacity];
+        int[] $columnIndices = new int[capacity];
 
         System.arraycopy(values, 0, $values, 0, cardinality);
         System.arraycopy(columnIndices, 0, $columnIndices, 0, cardinality);
@@ -777,6 +779,9 @@ public class CRSMatrix extends RowMajorSparseMatrix {
 
             @Override
             public Integer next() {
+                if(!hasNext()) {
+                    throw new NoSuchElementException();
+                }
                 i++;
                 return i;
             }
@@ -833,6 +838,9 @@ public class CRSMatrix extends RowMajorSparseMatrix {
 
             @Override
             public Double next() {
+                if(!hasNext()) {
+                    throw new NoSuchElementException();
+                }
                 if (currentNonZero) {
                     k++;
                 }
@@ -889,6 +897,9 @@ public class CRSMatrix extends RowMajorSparseMatrix {
 
             @Override
             public Double next() {
+                if(!hasNext()) {
+                    throw new NoSuchElementException();
+                }
                 currentIsRemoved = false;
                 k++;
                 while (rowPointers[i + 1] == k) {
@@ -938,6 +949,9 @@ public class CRSMatrix extends RowMajorSparseMatrix {
 
             @Override
             public Double next() {
+                if(!hasNext()) {
+                    throw new NoSuchElementException();
+                }
                 currentIsRemoved = false;
                 return values[++k];
             }
@@ -984,6 +998,9 @@ public class CRSMatrix extends RowMajorSparseMatrix {
 
             @Override
             public Double next() {
+                if(!hasNext()) {
+                    throw new NoSuchElementException();
+                }
                 j++;
                 if (k < rowPointers[ii + 1] && columnIndices[k] == j - 1) {
                     k++;
diff --git a/src/main/java/org/la4j/vector/DenseVector.java b/src/main/java/org/la4j/vector/DenseVector.java
index 3660791..375bd4d 100644
--- a/src/main/java/org/la4j/vector/DenseVector.java
+++ b/src/main/java/org/la4j/vector/DenseVector.java
@@ -30,6 +30,8 @@ import org.la4j.operation.VectorOperation;
 import org.la4j.operation.VectorVectorOperation;
 import org.la4j.vector.dense.BasicVector;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.text.NumberFormat;
 import java.util.Collection;
 import java.util.Map;
@@ -50,6 +52,10 @@ import java.util.Random;
  */
 public abstract class DenseVector extends Vector {
 
+    public DenseVector(int length) {
+        super(length);
+    }
+
     /**
      * Creates a zero {@link DenseVector} of the given {@code length}.
      */
@@ -100,14 +106,15 @@ public abstract class DenseVector extends Vector {
     }
 
     /**
-     * Parses {@link DenseVector} from the given Matrix Market string.
+     * Parses {@link DenseVector} from the given Matrix Market.
      *
-     * @param mm the string in Matrix Market format
+     * @param is the input stream in Matrix Market format
      *
      * @return a parsed vector
+     * @exception  IOException  if an I/O error occurs.
      */
-    public static DenseVector fromMatrixMarket(String mm) {
-        return Vector.fromMatrixMarket(mm).to(Vectors.DENSE);
+    public static DenseVector fromMatrixMarket(InputStream is) throws IOException {
+        return Vector.fromMatrixMarket(is).to(Vectors.DENSE);
     }
 
     /**
@@ -157,10 +164,6 @@ public abstract class DenseVector extends Vector {
      */
     public abstract double[] toArray();
 
-    public DenseVector(int length) {
-        super(length);
-    }
-
     @Override
     public Matrix toRowMatrix() {
         Matrix result = Basic2DMatrix.zero(1, length);
diff --git a/src/main/java/org/la4j/vector/SparseVector.java b/src/main/java/org/la4j/vector/SparseVector.java
index 0b16900..75d2b55 100644
--- a/src/main/java/org/la4j/vector/SparseVector.java
+++ b/src/main/java/org/la4j/vector/SparseVector.java
@@ -21,6 +21,8 @@
 
 package org.la4j.vector;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.text.NumberFormat;
 import java.util.Collection;
 import java.util.Map;
@@ -55,6 +57,17 @@ import org.la4j.vector.sparse.CompressedVector;
  */
 public abstract class SparseVector extends Vector {
 
+    protected int cardinality;
+
+    public SparseVector(int length) {
+        this(length, 0);
+    }
+
+    public SparseVector(int length, int cardinality) {
+        super(length);
+        this.cardinality = cardinality;
+    }
+
     /**
      * Creates a zero {@link SparseVector} of the given {@code length}.
      */
@@ -98,14 +111,15 @@ public abstract class SparseVector extends Vector {
     }
 
     /**
-     * Parses {@link SparseVector} from the given Matrix Market string.
+     * Parses {@link SparseVector} from the given Matrix Market.
      *
-     * @param mm the string in Matrix Market format
+     * @param is the input stream in Matrix Market format
      *
      * @return a parsed vector
+     * @exception  IOException  if an I/O error occurs.
      */
-    public static SparseVector fromMatrixMarket(String mm) {
-        return Vector.fromMatrixMarket(mm).to(Vectors.SPARSE);
+    public static SparseVector fromMatrixMarket(InputStream is) throws IOException {
+        return Vector.fromMatrixMarket(is).to(Vectors.SPARSE);
     }
 
     /**
@@ -130,17 +144,6 @@ public abstract class SparseVector extends Vector {
         return CompressedVector.fromMap(map, length);
     }
 
-    protected int cardinality;
-
-    public SparseVector(int length) {
-        this(length, 0);
-    }
-
-    public SparseVector(int length, int cardinality) {
-        super(length);
-        this.cardinality = cardinality;
-    }
-
     /**
      * Returns the cardinality (the number of non-zero elements)
      * of this sparse vector.
diff --git a/src/main/java/org/la4j/vector/dense/BasicVector.java b/src/main/java/org/la4j/vector/dense/BasicVector.java
index ab4a870..b7ae417 100644
--- a/src/main/java/org/la4j/vector/dense/BasicVector.java
+++ b/src/main/java/org/la4j/vector/dense/BasicVector.java
@@ -21,6 +21,8 @@
 
 package org.la4j.vector.dense;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -51,6 +53,21 @@ public class BasicVector extends DenseVector {
 
     private static final byte VECTOR_TAG = (byte) 0x00;
 
+    private double[] self;
+
+    public BasicVector() {
+        this(0);
+    }
+
+    public BasicVector(int length) {
+        this(new double[length]);
+    }
+
+    public BasicVector(double[] array) {
+        super(array.length);
+        this.self = array;
+    }
+
     /**
      * Creates a zero {@link BasicVector} of the given {@code length}.
      */
@@ -63,7 +80,7 @@ public class BasicVector extends DenseVector {
      * the given {@code value}.
      */
     public static BasicVector constant(int length, double value) {
-        double array[] = new double[length];
+        double[] array = new double[length];
         Arrays.fill(array, value);
 
         return new BasicVector(array);
@@ -81,7 +98,7 @@ public class BasicVector extends DenseVector {
      * the given {@code Random}.
      */
     public static BasicVector random(int length, Random random) {
-        double array[] = new double[length];
+        double[] array = new double[length];
         for (int i = 0; i < length; i++) {
             array[i] = random.nextDouble();
         }
@@ -131,14 +148,15 @@ public class BasicVector extends DenseVector {
     }
 
     /**
-     * Parses {@link BasicVector} from the given Matrix Market string.
+     * Parses {@link BasicVector} from the given Matrix Market.
      *
-     * @param mm the string in Matrix Market format
+     * @param is the input stream in Matrix Market format
      *
      * @return a parsed vector
+     * @exception  IOException  if an I/O error occurs.
      */
-    public static BasicVector fromMatrixMarket(String mm) {
-        return Vector.fromMatrixMarket(mm).to(Vectors.BASIC);
+    public static BasicVector fromMatrixMarket(InputStream is) throws IOException {
+        return Vector.fromMatrixMarket(is).to(Vectors.BASIC);
     }
 
     /**
@@ -172,21 +190,6 @@ public class BasicVector extends DenseVector {
         return Vector.fromMap(map, length).to(Vectors.BASIC);
     }
 
-    private double self[];
-
-    public BasicVector() {
-        this(0);
-    }
-
-    public BasicVector(int length) {
-        this(new double[length]);
-    }
-
-    public BasicVector(double array[]) {
-        super(array.length);
-        this.self = array;
-    }
-
     @Override
     public double get(int i) {
         return self[i];
@@ -210,7 +213,7 @@ public class BasicVector extends DenseVector {
     public Vector copyOfLength(int length) {
       ensureLengthIsCorrect(length);
 
-      double $self[] = new double[length];
+      double[] $self = new double[length];
       System.arraycopy(self, 0, $self, 0, Math.min($self.length, self.length));
 
       return new BasicVector($self);
@@ -218,7 +221,7 @@ public class BasicVector extends DenseVector {
 
     @Override
     public double[] toArray() {
-        double result[] = new double[length];
+        double[] result = new double[length];
         System.arraycopy(self, 0, result, 0, length);
         return result;
     }
diff --git a/src/main/java/org/la4j/vector/sparse/CompressedVector.java b/src/main/java/org/la4j/vector/sparse/CompressedVector.java
index 8fd4a5b..7464f3b 100644
--- a/src/main/java/org/la4j/vector/sparse/CompressedVector.java
+++ b/src/main/java/org/la4j/vector/sparse/CompressedVector.java
@@ -23,11 +23,10 @@
 
 package org.la4j.vector.sparse;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Random;
+import java.util.*;
 
 import org.la4j.Vectors;
 import org.la4j.iterator.VectorIterator;
@@ -60,6 +59,30 @@ public class CompressedVector extends SparseVector {
 
     private static final int MINIMUM_SIZE = 32;
 
+    private double[] values;
+    private int[] indices;
+
+    public CompressedVector() {
+        this(0);
+    }
+
+    public CompressedVector(int length) {
+        this(length, 0);
+    }
+
+    public CompressedVector(int length, int capacity) {
+        super(length);
+        int alignedSize = align(length, capacity);
+        this.values = new double[alignedSize];
+        this.indices = new int[alignedSize];
+    }
+
+    public CompressedVector(int length, int cardinality, double[] values, int[] indices) {
+        super(length, cardinality);
+        this.values = values;
+        this.indices = indices;
+    }
+
     /**
      * Creates a zero {@link CompressedVector} of the given {@code length}.
      */
@@ -85,8 +108,8 @@ public class CompressedVector extends SparseVector {
         }
 
         int cardinality = (int) (length * density);
-        double values[] = new double[cardinality];
-        int indices[] = new int[cardinality];
+        double[] values = new double[cardinality];
+        int[] indices = new int[cardinality];
 
         for (int i = 0; i < cardinality; i++) {
             values[i] = random.nextDouble();
@@ -154,14 +177,15 @@ public class CompressedVector extends SparseVector {
     }
 
     /**
-     * Parses {@link CompressedVector} from the given Matrix Market string.
+     * Parses {@link CompressedVector} from the given Matrix Market.
      *
-     * @param mm the string in Matrix Market format
+     * @param is the input stream in Matrix Market format
      *
      * @return a parsed vector
+     * @exception  IOException  if an I/O error occurs.
      */
-    public static CompressedVector fromMatrixMarket(String mm) {
-        return Vector.fromMatrixMarket(mm).to(Vectors.COMPRESSED);
+    public static CompressedVector fromMatrixMarket(InputStream is) throws IOException {
+        return Vector.fromMatrixMarket(is).to(Vectors.COMPRESSED);
     }
 
     /**
@@ -186,11 +210,12 @@ public class CompressedVector extends SparseVector {
      */
     public static CompressedVector fromMap(Map<Integer, ? extends Number> map, int length) {
         //TODO goto lambdas
-        int cardinality = map.size();
+        TreeMap<Integer, ? extends Number> sortedMap = new TreeMap<>(map);
+        int cardinality = sortedMap.size();
         int[] indices = new int[cardinality];
         double[] values = new double[cardinality];
         int i = 0;
-        for (Map.Entry<Integer, ? extends Number> entry : map.entrySet()) {
+        for (Map.Entry<Integer, ? extends Number> entry : sortedMap.entrySet()) {
             int index = entry.getKey();
             if (index < 0 || index >= length) {
                 throw new IllegalArgumentException("Check your map: Index must be 0..n-1");
@@ -202,30 +227,6 @@ public class CompressedVector extends SparseVector {
         return new CompressedVector(length, cardinality, values, indices);
     }
 
-    private double values[];
-    private int indices[];
-
-    public CompressedVector() {
-        this(0);
-    }
-
-    public CompressedVector(int length) {
-        this(length, 0);
-    }
-
-    public CompressedVector(int length, int capacity) {
-        super(length);
-        int alignedSize = align(length, capacity);
-        this.values = new double[alignedSize];
-        this.indices = new int[alignedSize];
-    }
-
-    public CompressedVector(int length, int cardinality, double values[], int indices[]) {
-        super(length, cardinality);
-        this.values = values;
-        this.indices = indices;
-    }
-
     @Override
     public double getOrElse(int i, double defaultValue) {
         ensureIndexIsInBounds(i);
@@ -343,8 +344,8 @@ public class CompressedVector extends SparseVector {
             cardinality : searchForIndex(length);
         int capacity = align(length, $cardinality);
 
-        double $values[] = new double[capacity];
-        int $indices[] = new int[capacity];
+        double[] $values = new double[capacity];
+        int[] $indices = new int[capacity];
 
         System.arraycopy(values, 0, $values, 0, $cardinality);
         System.arraycopy(indices, 0, $indices, 0, $cardinality);
@@ -509,8 +510,8 @@ public class CompressedVector extends SparseVector {
 
         int capacity = Math.min(length, (cardinality * 3) / 2 + 1);
 
-        double $values[] = new double[capacity];
-        int $indices[] = new int[capacity];
+        double[] $values = new double[capacity];
+        int[] $indices = new int[capacity];
 
         System.arraycopy(values, 0, $values, 0, cardinality);
         System.arraycopy(indices, 0, $indices, 0, cardinality);
@@ -567,6 +568,9 @@ public class CompressedVector extends SparseVector {
 
             @Override
             public Double next() {
+                if(!hasNext()) {
+                    throw new NoSuchElementException();
+                }
                 currentIsRemoved = false;
                 return values[++k];
             }
@@ -612,6 +616,9 @@ public class CompressedVector extends SparseVector {
 
             @Override
             public Double next() {
+                if(!hasNext()) {
+                    throw new NoSuchElementException();
+                }
                 if (currentNonZero) {
                     k++;
                 }
diff --git a/src/test/java/org/la4j/matrix/MatrixTest.java b/src/test/java/org/la4j/matrix/MatrixTest.java
index 492f312..a8a8a39 100644
--- a/src/test/java/org/la4j/matrix/MatrixTest.java
+++ b/src/test/java/org/la4j/matrix/MatrixTest.java
@@ -26,6 +26,8 @@
 
 package org.la4j.matrix;
 
+import java.io.ByteArrayInputStream;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 
 import org.junit.Assert;
@@ -52,6 +54,82 @@ public abstract class MatrixTest<T extends Matrix> {
         return M.mz(rows, columns).to(factory);
     }
 
+    @Test
+    public void testInsertRowInEmptyMatrix() {
+
+        Matrix a = m(a(1.0, 0.0, 0.0),
+            a(0.0, 1.0, 0.0),
+            a(0.0, 0.0, 1.0));
+
+        Vector v1 = v(1.0, 0.0, 0.0);
+        Vector v2 = v(0.0, 1.0, 0.0);
+        Vector v3 = v(0.0, 0.0, 1.0);
+
+        Matrix b = mz(0, 0);
+        b = b.insertRow(0, v3);
+        b = b.insertRow(0, v2);
+        b = b.insertRow(0, v1);
+
+        Assert.assertEquals(a, b);
+    }
+
+    @Test
+    public void testInsertColumnInEmptyMatrix() {
+
+        Matrix a = m(a(1.0, 0.0, 0.0),
+            a(0.0, 1.0, 0.0),
+            a(0.0, 0.0, 1.0));
+
+        Vector v1 = v(1.0, 0.0, 0.0);
+        Vector v2 = v(0.0, 1.0, 0.0);
+        Vector v3 = v(0.0, 0.0, 1.0);
+
+        Matrix b = mz(0, 0);
+        b = b.insertColumn(0, v3);
+        b = b.insertColumn(0, v2);
+        b = b.insertColumn(0, v1);
+
+        Assert.assertEquals(a, b);
+    }
+
+    @Test
+    public void testInsertRowAtTheEnd() {
+
+        Matrix a = m(a(1.0, 0.0, 0.0),
+            a(0.0, 1.0, 0.0),
+            a(0.0, 0.0, 1.0));
+
+        Vector v1 = v(1.0, 0.0, 0.0);
+        Vector v2 = v(0.0, 1.0, 0.0);
+        Vector v3 = v(0.0, 0.0, 1.0);
+
+        Matrix b = mz(0, 0);
+        b = b.insertRow(0, v1);
+        b = b.insertRow(1, v2);
+        b = b.insertRow(2, v3);
+
+        Assert.assertEquals(a, b);
+    }
+
+    @Test
+    public void testInsertColumnAtTheEnd() {
+
+        Matrix a = m(a(1.0, 0.0, 0.0),
+            a(0.0, 1.0, 0.0),
+            a(0.0, 0.0, 1.0));
+
+        Vector v1 = v(1.0, 0.0, 0.0);
+        Vector v2 = v(0.0, 1.0, 0.0);
+        Vector v3 = v(0.0, 0.0, 1.0);
+
+        Matrix b = mz(0, 0);
+        b = b.insertColumn(0, v1);
+        b = b.insertColumn(1, v2);
+        b = b.insertColumn(2, v3);
+
+        Assert.assertEquals(a, b);
+    }
+
     @Test
     public void testInsert_3x3_into_3x3() {
         Matrix a = m(a(1.0, 2.0, 3.0),
@@ -1879,6 +1957,17 @@ public abstract class MatrixTest<T extends Matrix> {
         Assert.assertTrue(e.equals(f));
     }
 
+    @Test
+    public void testFromCSV() {
+        Matrix a = Matrix.fromCSV("");
+        Assert.assertTrue(a.equals(mz(0, 0)));
+
+        a = Matrix.fromCSV("1,2\n3,4");
+        Matrix b = m(a(1.0, 2.0),
+                     a(3.0, 4.0));
+        Assert.assertTrue(a.equals(b, Matrices.EPS));
+    }
+
     @Test
     public void testFromMatrixMarket() throws Exception {
         String mm = "%%MatrixMarket matrix coordinate real general\n" +
@@ -1905,7 +1994,7 @@ public abstract class MatrixTest<T extends Matrix> {
         matrix.set(3, 4, 3.332e+01);
         matrix.set(4, 4, 1.200e+01);
 
-        Matrix from_mm_matrix = Matrix.fromMatrixMarket(mm);
+        Matrix from_mm_matrix = Matrix.fromMatrixMarket(new ByteArrayInputStream(mm.getBytes(StandardCharsets.UTF_8)));
         Assert.assertNotNull(from_mm_matrix);
         Assert.assertTrue(matrix.equals(from_mm_matrix));
 
@@ -1944,7 +2033,7 @@ public abstract class MatrixTest<T extends Matrix> {
         bcs_matrix.set(13, 13, 1.7282857345500e-01);
         bcs_matrix.set(14, 14, 1.7282857345500e-01);
 
-        Matrix bcs_mm_matrix = Matrix.fromMatrixMarket(bcsstm02_mm);
+        Matrix bcs_mm_matrix = Matrix.fromMatrixMarket(new ByteArrayInputStream(bcsstm02_mm.getBytes(StandardCharsets.UTF_8)));
 
         Assert.assertNotNull(bcs_mm_matrix);
         Assert.assertTrue(bcs_matrix.equals(bcs_mm_matrix));
diff --git a/src/test/java/org/la4j/vector/VectorTest.java b/src/test/java/org/la4j/vector/VectorTest.java
index 52963f9..7515a06 100644
--- a/src/test/java/org/la4j/vector/VectorTest.java
+++ b/src/test/java/org/la4j/vector/VectorTest.java
@@ -36,8 +36,14 @@ import org.la4j.vector.functor.VectorPredicate;
 import static org.la4j.V.*;
 import static org.la4j.M.*;
 
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringBufferInputStream;
+import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -724,6 +730,16 @@ public abstract class VectorTest<T extends Vector> {
         Assert.assertEquals(v, Vector.fromMap(map, 7));
     }
 
+    @Test
+    public void testFromMap_unordered() {
+        Map<Integer, Double> map = new LinkedHashMap<>();
+        map.put(5, 1.0);
+        map.put(0, 1.0);
+        map.put(3, 2.0);
+        Vector v = Vector.fromArray(new double[]{1, 0, 0, 2, 0, 1, 0});
+        Assert.assertEquals(v, Vector.fromMap(map, 7));
+    }
+
     @Test
     public void testFromMap_emptyMap() {
         Map<Integer, Double> map = new HashMap<>();
@@ -743,4 +759,62 @@ public abstract class VectorTest<T extends Vector> {
     public void testFromMap_NPE() {
         Vector v = Vector.fromMap(null, 4);
     }
+
+    @Test
+    public void testFromMatrixMarketArray_empty() throws IOException {
+        InputStream is = new ByteArrayInputStream("%%MatrixMarket vector array real\n0".getBytes(StandardCharsets.UTF_8));
+        Assert.assertEquals(Vector.fromMatrixMarket(is), Vector.zero(0));
+    }
+
+    @Test
+    public void testFromMatrixMarketCoordinate_empty() throws IOException {
+        InputStream is = new ByteArrayInputStream("%%MatrixMarket vector coordinate real\n0 0".getBytes(StandardCharsets.UTF_8));
+        Assert.assertEquals(Vector.fromMatrixMarket(is), Vector.zero(0));
+    }
+
+    @Test
+    public void testFromMatrixMarketArray_normal() throws IOException {
+        InputStream is = new ByteArrayInputStream("%%MatrixMarket vector array real\n3 1 2 3".getBytes(StandardCharsets.UTF_8));
+        Assert.assertEquals(Vector.fromMatrixMarket(is), Vector.fromArray(new double[] {1, 2, 3}));
+    }
+
+    @Test
+    public void testFromMatrixMarketCoordinate_normal() throws IOException {
+        InputStream is = new ByteArrayInputStream("%%MatrixMarket vector coordinate real\n3 3\n1 1\n2 2\n3 3".getBytes(StandardCharsets.UTF_8));
+        Assert.assertEquals(Vector.fromMatrixMarket(is), Vector.fromArray(new double[] {1, 2, 3}));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testFromMatrixMarket_IAE() throws IOException {
+        InputStream is = new ByteArrayInputStream("%%".getBytes(StandardCharsets.UTF_8));
+        Vector.fromMatrixMarket(is);
+    }
+
+    @Test
+    public void testFromCSV() {
+        Assert.assertEquals(Vector.fromCSV(""), Vector.zero(0));
+
+        Assert.assertEquals(Vector.fromCSV("1,2,3"), Vector.fromArray(new double[]{1, 2, 3}));
+
+        try {
+            Vector.fromCSV("a");
+            Assert.fail();
+        } catch (NumberFormatException e) {
+        }
+    }
+
+    @Test
+    public void testCosineSimilarity() {
+        Vector a = v(5, 1, 0, 0, 0, 1, 10, 15);
+        Vector b = v(1, 8, 0, 9, 6, 4, 2, 5);
+        Vector c = v(9, 0, 2, 1, 1, 0, 8, 12);
+        Vector d = v(900, 0, 200, 100, 100, 0, 800, 1200);
+
+        // a & c are more similar to each other than b
+        Assert.assertTrue(a.cosineSimilarity(b) < a.cosineSimilarity(c));
+        Assert.assertTrue(c.cosineSimilarity(b) < c.cosineSimilarity(a));
+
+        Assert.assertEquals(1.0, c.cosineSimilarity(d), 0.00005);
+        Assert.assertEquals(1.0, d.cosineSimilarity(c), 0.00005);
+    }
 }