internal override void CopySubMatrixToUnchecked(MatrixStorage <T> target,
                                                        int sourceRowIndex, int targetRowIndex, int rowCount,
                                                        int sourceColumnIndex, int targetColumnIndex, int columnCount,
                                                        ExistingData existingData)
        {
            var denseTarget = target as DenseColumnMajorMatrixStorage <T>;

            if (denseTarget != null)
            {
                CopySubMatrixToUnchecked(denseTarget, sourceRowIndex, targetRowIndex, rowCount, sourceColumnIndex, targetColumnIndex, columnCount, existingData);
                return;
            }

            var diagonalTarget = target as DiagonalMatrixStorage <T>;

            if (diagonalTarget != null)
            {
                CopySubMatrixToUnchecked(diagonalTarget, sourceRowIndex, targetRowIndex, rowCount, sourceColumnIndex, targetColumnIndex, columnCount);
                return;
            }

            // TODO: Proper Sparse Implementation

            // FALL BACK

            if (existingData == ExistingData.Clear)
            {
                target.ClearUnchecked(targetRowIndex, rowCount, targetColumnIndex, columnCount);
            }

            if (sourceRowIndex == sourceColumnIndex)
            {
                for (var i = 0; i < System.Math.Min(columnCount, rowCount); i++)
                {
                    target.At(targetRowIndex + i, targetColumnIndex + i, Data[sourceRowIndex + i]);
                }
            }
            else if (sourceRowIndex > sourceColumnIndex && sourceColumnIndex + columnCount > sourceRowIndex)
            {
                // column by column, but skip resulting zero columns at the beginning
                int columnInit = sourceRowIndex - sourceColumnIndex;
                for (var i = 0; i < System.Math.Min(columnCount - columnInit, rowCount); i++)
                {
                    target.At(targetRowIndex + i, columnInit + targetColumnIndex + i, Data[sourceRowIndex + i]);
                }
            }
            else if (sourceRowIndex < sourceColumnIndex && sourceRowIndex + rowCount > sourceColumnIndex)
            {
                // row by row, but skip resulting zero rows at the beginning
                int rowInit = sourceColumnIndex - sourceRowIndex;
                for (var i = 0; i < System.Math.Min(columnCount, rowCount - rowInit); i++)
                {
                    target.At(rowInit + targetRowIndex + i, targetColumnIndex + i, Data[sourceColumnIndex + i]);
                }
            }
        }
        // COLUMN COPY

        internal override void CopyToColumnUnchecked(MatrixStorage <T> target, int columnIndex, ExistingData existingData)
        {
            if (existingData == ExistingData.Clear)
            {
                target.ClearUnchecked(0, Length, columnIndex, 1);
            }

            if (ValueCount == 0)
            {
                return;
            }

            for (int i = 0; i < ValueCount; i++)
            {
                target.At(Indices[i], columnIndex, Values[i]);
            }
        }
        // Row COPY

        internal override void CopyToRowUnchecked(MatrixStorage <T> target, int rowIndex, ExistingData existingData)
        {
            if (existingData == ExistingData.Clear)
            {
                target.ClearUnchecked(rowIndex, 1, 0, Length);
            }

            if (ValueCount == 0)
            {
                return;
            }

            for (int i = 0; i < ValueCount; i++)
            {
                target.At(rowIndex, Indices[i], Values[i]);
            }
        }
        internal override void MapSubMatrixIndexedToUnchecked <TU>(MatrixStorage <TU> target, Func <int, int, T, TU> f,
                                                                   int sourceRowIndex, int targetRowIndex, int rowCount,
                                                                   int sourceColumnIndex, int targetColumnIndex, int columnCount,
                                                                   Zeros zeros, ExistingData existingData)
        {
            var diagonalTarget = target as DiagonalMatrixStorage <TU>;

            if (diagonalTarget != null)
            {
                MapSubMatrixIndexedToUnchecked(diagonalTarget, f, sourceRowIndex, targetRowIndex, rowCount, sourceColumnIndex, targetColumnIndex, columnCount, zeros);
                return;
            }

            var denseTarget = target as DenseColumnMajorMatrixStorage <TU>;

            if (denseTarget != null)
            {
                MapSubMatrixIndexedToUnchecked(denseTarget, f, sourceRowIndex, targetRowIndex, rowCount, sourceColumnIndex, targetColumnIndex, columnCount, zeros, existingData);
                return;
            }

            // TODO: Proper Sparse Implementation

            // FALL BACK

            if (existingData == ExistingData.Clear)
            {
                target.ClearUnchecked(targetRowIndex, rowCount, targetColumnIndex, columnCount);
            }

            if (sourceRowIndex == sourceColumnIndex)
            {
                int targetRow    = targetRowIndex;
                int targetColumn = targetColumnIndex;
                for (var i = 0; i < System.Math.Min(columnCount, rowCount); i++)
                {
                    target.At(targetRow, targetColumn, f(targetRow, targetColumn, Data[sourceRowIndex + i]));
                    targetRow++;
                    targetColumn++;
                }
            }
            else if (sourceRowIndex > sourceColumnIndex && sourceColumnIndex + columnCount > sourceRowIndex)
            {
                // column by column, but skip resulting zero columns at the beginning
                int columnInit   = sourceRowIndex - sourceColumnIndex;
                int targetRow    = targetRowIndex;
                int targetColumn = targetColumnIndex + columnInit;
                for (var i = 0; i < System.Math.Min(columnCount - columnInit, rowCount); i++)
                {
                    target.At(targetRow, targetColumn, f(targetRow, targetColumn, Data[sourceRowIndex + i]));
                    targetRow++;
                    targetColumn++;
                }
            }
            else if (sourceRowIndex < sourceColumnIndex && sourceRowIndex + rowCount > sourceColumnIndex)
            {
                // row by row, but skip resulting zero rows at the beginning
                int rowInit      = sourceColumnIndex - sourceRowIndex;
                int targetRow    = targetRowIndex + rowInit;
                int targetColumn = targetColumnIndex;
                for (var i = 0; i < System.Math.Min(columnCount, rowCount - rowInit); i++)
                {
                    target.At(targetRow, targetColumn, f(targetRow, targetColumn, Data[sourceColumnIndex + i]));
                    targetRow++;
                    targetColumn++;
                }
            }
        }