diff --git a/Documentation/Doxyfile b/Documentation/Doxyfile
index 11a3160f8637b739c7152c154064a7489f6e1e86..39df663bfd374585f602d37e6b674a3396eff402 100644
--- a/Documentation/Doxyfile
+++ b/Documentation/Doxyfile
@@ -2107,7 +2107,8 @@ INCLUDE_FILE_PATTERNS  =
 # recursively expanded use the := operator instead of the = operator.
 # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
-PREDEFINED             =
+PREDEFINED             = HAVE_MPI=1
+                         HAVE_CUDA=1
 
 # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
 # tag can be used to specify a list of macro names that should be expanded. The
diff --git a/src/Benchmarks/BLAS/array-operations.h b/src/Benchmarks/BLAS/array-operations.h
index b5cf9ff58da754aaa4c8ce645989afbb25e61f7c..926c729ce1af887c030d2a129bde735374377af1 100644
--- a/src/Benchmarks/BLAS/array-operations.h
+++ b/src/Benchmarks/BLAS/array-operations.h
@@ -66,10 +66,10 @@ benchmarkArrayOperations( Benchmark & benchmark,
 
 
    auto compareHost = [&]() {
-      resultHost = (int) hostArray == hostArray2;
+      resultHost = (int) ( hostArray == hostArray2 );
    };
    auto compareCuda = [&]() {
-      resultDevice = (int) deviceArray == deviceArray2;
+      resultDevice = (int) ( deviceArray == deviceArray2 );
    };
    benchmark.setOperation( "comparison (operator==)", 2 * datasetSize );
    benchmark.time< Devices::Host >( reset1, "CPU", compareHost );
diff --git a/src/Benchmarks/DistSpMV/tnl-benchmark-distributed-spmv.h b/src/Benchmarks/DistSpMV/tnl-benchmark-distributed-spmv.h
index 23f08152724222009ff8e818bfee9d6e78f81611..62e37117247bbe1d24398ed8b40159010213b182 100644
--- a/src/Benchmarks/DistSpMV/tnl-benchmark-distributed-spmv.h
+++ b/src/Benchmarks/DistSpMV/tnl-benchmark-distributed-spmv.h
@@ -163,9 +163,8 @@ struct SpmvBenchmark
    {
       MatrixType matrix;
       VectorType vector;
-      if( ! matrix.load( parameters.getParameter< String >( "input-matrix" ) ) ||
-          ! vector.load( parameters.getParameter< String >( "input-vector" ) ) )
-          return false;
+      matrix.load( parameters.getParameter< String >( "input-matrix" ) );
+      vector.load( parameters.getParameter< String >( "input-vector" ) );
 
       typename MatrixType::CompressedRowLengthsVector rowLengths;
       matrix.getCompressedRowLengths( rowLengths );
diff --git a/src/Benchmarks/HeatEquation/HeatEquationBenchmarkProblem_impl.h b/src/Benchmarks/HeatEquation/HeatEquationBenchmarkProblem_impl.h
index e63e431c67a39eed8a06993f71605db48d8e39c5..2bfd1e71cf58bea53963d33c24c5baf601939cc9 100644
--- a/src/Benchmarks/HeatEquation/HeatEquationBenchmarkProblem_impl.h
+++ b/src/Benchmarks/HeatEquation/HeatEquationBenchmarkProblem_impl.h
@@ -144,7 +144,11 @@ setInitialCondition( const Config::ParameterContainer& parameters,
 {
    const String& initialConditionFile = parameters.getParameter< String >( "initial-condition" );
    Functions::MeshFunction< Mesh > u( this->getMesh(), dofsPointer );
-   if( ! u.boundLoad( initialConditionFile ) )
+   try
+   {
+      u.boundLoad( initialConditionFile );
+   }
+   catch(...)
    {
       std::cerr << "I am not able to load the initial condition from the file " << initialConditionFile << "." << std::endl;
       return false;
@@ -200,8 +204,7 @@ makeSnapshot( const RealType& time,
    fileName.setIndex( step );
 
    //FileNameBaseNumberEnding( "u-", step, 5, ".tnl", fileName );
-   if( ! u.save( fileName.getFileName() ) )
-      return false;
+   u.save( fileName.getFileName() );
    return true;
 }
 
diff --git a/src/Benchmarks/LinearSolvers/tnl-benchmark-linear-solvers.h b/src/Benchmarks/LinearSolvers/tnl-benchmark-linear-solvers.h
index 55211c4edb9043e1ae0258e041fcfd2846976e51..2926e6bb149131cb01592532027c1d2b66fc8968 100644
--- a/src/Benchmarks/LinearSolvers/tnl-benchmark-linear-solvers.h
+++ b/src/Benchmarks/LinearSolvers/tnl-benchmark-linear-solvers.h
@@ -332,10 +332,9 @@ struct LinearSolversBenchmark
    {
       SharedPointer< MatrixType > matrixPointer;
       VectorType x0, b;
-      if( ! matrixPointer->load( parameters.getParameter< String >( "input-matrix" ) ) ||
-          ! x0.load( parameters.getParameter< String >( "input-dof" ) ) ||
-          ! b.load( parameters.getParameter< String >( "input-rhs" ) ) )
-          return false;
+      matrixPointer->load( parameters.getParameter< String >( "input-matrix" ) );
+      x0.load( parameters.getParameter< String >( "input-dof" ) );
+      b.load( parameters.getParameter< String >( "input-rhs" ) );
 
       typename MatrixType::CompressedRowLengthsVector rowLengths;
       matrixPointer->getCompressedRowLengths( rowLengths );
diff --git a/src/Examples/ArrayExample.cpp b/src/Examples/ArrayExample.cpp
deleted file mode 100644
index 2cc9c54e5167b6ed9faf6a67bf6de76305ed9b15..0000000000000000000000000000000000000000
--- a/src/Examples/ArrayExample.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-#include <iostream>
-#include <TNL/Containers/Array.h>
-
-using namespace TNL;
-using namespace std;
-
-int main()
-{
-    Containers::Array<int> array1;
-    array1.setSize(5);
-    array1.setValue(0);
-    cout << "Does array contain 1?" << array1.containsValue(1) << endl;
-    cout << "Does array contain only zeros?" << array1.containsOnlyValue(0) << endl;
-
-    Containers::Array<int> array2(3);
-    array2.setValue(1);
-    array2.swap(array1);
-    array2.setElement(2,4);
-
-    cout << "First array:" << array1.getData() << endl;
-    cout << "Second array:" << array2.getData() << endl;
-
-    array2.reset();
-    cout << "Second array after reset:" << array2.getData() << endl;
-
-    // bind
-}
diff --git a/src/Examples/CMakeLists.txt b/src/Examples/CMakeLists.txt
index 1c52839e9116646d982eafaea5ba30bf04a9b995..2d46b24465629193ff505257561e974f8fa55a4a 100644
--- a/src/Examples/CMakeLists.txt
+++ b/src/Examples/CMakeLists.txt
@@ -1,3 +1,5 @@
+ADD_SUBDIRECTORY( Containers )
+
 add_subdirectory( simple-examples )
 add_subdirectory( heat-equation )
 add_subdirectory( transport-equation )
@@ -10,28 +12,85 @@ add_subdirectory( flow )
 add_subdirectory( flow-sw )
 add_subdirectory( flow-vl )
 
-#add_subdirectory( mean-curvature-flow )
-#add_subdirectory( hamilton-jacobi )
-#add_subdirectory( hamilton-jacobi-parallel )
-#add_subdirectory( fast-sweeping )
-#add_subdirectory( hamilton-jacobi-parallel-map )
-#add_subdirectory( fast-sweeping-map )
-#add_subdirectory( narrow-band )
-
-ADD_EXECUTABLE( ArrayExample ArrayExample.cpp )
 
 ADD_EXECUTABLE( ConfigDescriptionExample ConfigDescriptionExample.cpp )
+
 ADD_EXECUTABLE( FileExample FileExample.cpp )
+ADD_CUSTOM_COMMAND( COMMAND FileExample > FileExample.out OUTPUT FileExample.out )
+
+IF( BUILD_CUDA )
+   CUDA_ADD_EXECUTABLE(FileExampleCuda FileExampleCuda.cu)
+   ADD_CUSTOM_COMMAND( COMMAND FileExampleCuda > FileExampleCuda.out OUTPUT FileExampleCuda.out )
+ENDIF()
+
+ADD_EXECUTABLE( FileExampleSaveAndLoad FileExampleSaveAndLoad.cpp )
+ADD_CUSTOM_COMMAND( COMMAND FileExampleSaveAndLoad > FileExampleSaveAndLoad.out OUTPUT FileExampleSaveAndLoad.out )
+
+ADD_EXECUTABLE( FileNameExample FileNameExample.cpp )
+ADD_CUSTOM_COMMAND( COMMAND FileNameExample > FileNameExample.out OUTPUT FileNameExample.out )
+
+ADD_EXECUTABLE( FileNameExampleDistributedSystemNodeCoordinates FileNameExampleDistributedSystemNodeCoordinates.cpp )
+ADD_CUSTOM_COMMAND( COMMAND FileNameExampleDistributedSystemNodeCoordinates > FileNameExampleDistributedSystemNodeCoordinates.out OUTPUT FileNameExampleDistributedSystemNodeCoordinates.out )
+
+
+ADD_EXECUTABLE( FileNameExampleDistributedSystemNodeId FileNameExampleDistributedSystemNodeId.cpp )
+ADD_CUSTOM_COMMAND( COMMAND FileNameExampleDistributedSystemNodeId > FileNameExampleDistributedSystemNodeId.out OUTPUT FileNameExampleDistributedSystemNodeId.out )
+
 ADD_EXECUTABLE( ListExample ListExample.cpp )
 ADD_EXECUTABLE( LoggerExample LoggerExample.cpp )
 ADD_EXECUTABLE( MathExample MathExample.cpp )
 
+ADD_EXECUTABLE( ObjectExample_getType ObjectExample_getType.cpp )
+ADD_CUSTOM_COMMAND( COMMAND ObjectExample_getType > ObjectExample_getType.out OUTPUT ObjectExample_getType.out )
+
 ADD_EXECUTABLE( ParameterContainerExample ParameterContainerExample.cpp )
 
+ADD_EXECUTABLE( ParseObjectTypeExample ParseObjectTypeExample.cpp )
+ADD_CUSTOM_COMMAND( COMMAND ParseObjectTypeExample > ParseObjectTypeExample.out OUTPUT ParseObjectTypeExample.out )
+
 ADD_EXECUTABLE( StringExample StringExample.cpp )
+ADD_CUSTOM_COMMAND( COMMAND StringExample > StringExample.out OUTPUT StringExample.out )
+
 ADD_EXECUTABLE( StringExampleGetAllocatedSize StringExampleGetAllocatedSize.cpp )
-ADD_EXECUTABLE( StringExampleGetSize StringExampleGetSize.cpp )
+ADD_CUSTOM_COMMAND( COMMAND StringExampleGetAllocatedSize > StringExampleGetAllocatedSize.out OUTPUT StringExampleGetAllocatedSize.out )
+
+ADD_EXECUTABLE( StringExampleReplace StringExampleReplace.cpp )
+ADD_CUSTOM_COMMAND( COMMAND StringExampleReplace > StringExampleReplace.out OUTPUT StringExampleReplace.out )
+
 ADD_EXECUTABLE( StringExampleSetSize StringExampleSetSize.cpp )
+ADD_CUSTOM_COMMAND( COMMAND StringExampleSetSize > StringExampleSetSize.out OUTPUT StringExampleSetSize.out )
+
+ADD_EXECUTABLE( StringExampleSplit StringExampleSplit.cpp )
+ADD_CUSTOM_COMMAND( COMMAND StringExampleSplit > StringExampleSplit.out OUTPUT StringExampleSplit.out )
+
+ADD_EXECUTABLE( StringExampleStrip StringExampleStrip.cpp )
+ADD_CUSTOM_COMMAND( COMMAND StringExampleStrip > StringExampleStrip.out OUTPUT StringExampleStrip.out )
+
 ADD_EXECUTABLE( TimerExample TimerExample.cpp )
+ADD_CUSTOM_COMMAND( COMMAND TimerExample > TimerExample.out OUTPUT TimerExample.out )
+
+ADD_EXECUTABLE( TimerExampleLogger TimerExampleLogger.cpp )
+ADD_CUSTOM_COMMAND( COMMAND TimerExampleLogger > TimerExampleLogger.out OUTPUT TimerExampleLogger.out )
 
 ADD_EXECUTABLE( VectorExample VectorExample.cpp )
+
+ADD_CUSTOM_TARGET( RunExamples ALL DEPENDS
+   FileExample.out
+   FileExampleSaveAndLoad.out
+   FileNameExample.out
+   FileNameExampleDistributedSystemNodeCoordinates.out
+   FileNameExampleDistributedSystemNodeId.out
+   ObjectExample_getType.out
+   ParseObjectTypeExample.out
+   StringExample.out
+   StringExampleGetAllocatedSize.out
+   StringExampleReplace.out
+   StringExampleSplit.out
+   StringExampleStrip.out
+   TimerExample.out
+   TimerExampleLogger.out )
+
+if( BUILD_CUDA )
+   ADD_CUSTOM_TARGET( RunExamples-cuda ALL DEPENDS
+      FileExampleCuda.out )
+ENDIF()
\ No newline at end of file
diff --git a/src/Examples/Containers/ArrayExample.cpp b/src/Examples/Containers/ArrayExample.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9dcfd7cbddc9ad4920ce024b3e2044b3a248efcf
--- /dev/null
+++ b/src/Examples/Containers/ArrayExample.cpp
@@ -0,0 +1,78 @@
+#include <iostream>
+#include <list>
+#include <vector>
+#include <TNL/Containers/Array.h>
+
+using namespace TNL;
+using namespace std;
+
+/***
+ * The following works for any device (CPU, GPU ...).
+ */
+template< typename Device >
+void arrayExample()
+{
+   const int size = 10;
+   using ArrayType = Containers::Array< int, Device >;
+   using IndexType = typename ArrayType::IndexType;
+   ArrayType a1( size ), a2( size );
+
+   /***
+    * You may initiate the array using setElement
+    */
+   for( int i = 0; i< size; i++ )
+      a1.setElement( i, i );
+   std::cout << "a1 = " << a1 << std::endl;
+
+   /***
+    * You may also assign value to all array elements ...
+    */
+   a2 = 0.0;
+   std::cout << "a2 = " << a2 << std::endl;
+
+   /***
+    * ... or assign STL list and vector.
+    */
+   std::list< float > l = { 1.0, 2.0, 3.0 };
+   std::vector< float > v = { 5.0, 6.0, 7.0 };
+   a1 = l;
+   std::cout << "a1 = " << a1 << std::endl;
+   a1 = v;
+   std::cout << "a1 = " << a1 << std::endl;
+
+   /***
+    * Simple array values checks can be done as follows ...
+    */
+   if( a1.containsValue( 1 ) )
+      std::cout << "a1 contains value 1." << std::endl;
+   if( a1.containsValue( size ) )
+      std::cout << "a1 contains value " << size << "." << std::endl;
+   if( a1.containsOnlyValue( 0 ) )
+      std::cout << "a2 contains only value 0." << std::endl;
+
+   /***
+    * You may swap array data with the swap method.
+    */
+   a1.swap( a2 );
+
+   /***
+    * Of course, you may save it to file and load again
+    */
+   a1.save( "a1.tnl" );
+   a2.load( "a1.tnl" );
+
+   if( a2 != a1 )
+      std::cerr << "Something is wrong!!!" << std::endl;
+
+   std::cout << "a2 = " << a2 << std::endl;
+}
+
+int main()
+{
+   std::cout << "The first test runs on CPU ..." << std::endl;
+   arrayExample< Devices::Host >();
+#ifdef HAVE_CUDA
+   std::cout << "The second test runs on GPU ..." << std::endl;
+   arrayExample< Devices::Cuda >();
+#endif
+}
diff --git a/src/Examples/Containers/ArrayExample.cu b/src/Examples/Containers/ArrayExample.cu
new file mode 120000
index 0000000000000000000000000000000000000000..6cee614fe57fdd448dbc4b7dd6bacd2949d574d3
--- /dev/null
+++ b/src/Examples/Containers/ArrayExample.cu
@@ -0,0 +1 @@
+ArrayExample.cpp
\ No newline at end of file
diff --git a/src/Examples/Containers/ArrayViewExample.cpp b/src/Examples/Containers/ArrayViewExample.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..087dc19c6abf28d117eb0e05c048aab012e54bc3
--- /dev/null
+++ b/src/Examples/Containers/ArrayViewExample.cpp
@@ -0,0 +1,81 @@
+#include <iostream>
+#include <list>
+#include <vector>
+#include <TNL/Containers/Array.h>
+#include <TNL/Containers/ArrayView.h>
+
+using namespace TNL;
+using namespace std;
+
+/***
+ * The following works for any device (CPU, GPU ...).
+ */
+template< typename Device >
+void arrayViewExample()
+{
+   const int size = 10;
+   using ArrayType = Containers::Array< int, Device >;
+   using IndexType = typename ArrayType::IndexType;
+   using ViewType = Containers::ArrayView< int, Device >;
+   ArrayType _a1( size ), _a2( size );
+   ViewType a1( _a1 ), a2( _a2 );
+
+   /***
+    * You may initiate the array view using setElement
+    */
+   for( int i = 0; i< size; i++ )
+      a1.setElement( i, i );
+
+   /***
+    * You may also assign value to all array view elements ...
+    */
+   a2 = 0.0;
+
+   /***
+    * Simple array view values checks can be done as follows ...
+    */
+   if( a1.containsValue( 1 ) )
+      std::cout << "a1 contains value 1." << std::endl;
+   if( a1.containsValue( size ) )
+      std::cout << "a1 contains value " << size << "." << std::endl;
+   if( a1.containsOnlyValue( 0 ) )
+      std::cout << "a2 contains only value 0." << std::endl;
+
+   /***
+    * More efficient way of array view elements manipulation is with the lambda functions
+    */
+   ArrayType _a3( size );
+   ViewType a3( _a3 );
+   auto f1 = [] __cuda_callable__ ( IndexType i ) -> int { return 2 * i;};
+   a3.evaluate( f1 );
+
+   for( int i = 0; i < size; i++ )
+      if( a3.getElement( i ) != 2 * i )
+         std::cerr << "Something is wrong!!!" << std::endl;
+
+   /***
+    * You may swap array view data with the swap method.
+    */
+   a1.swap( a3 );
+
+   /***
+    * Of course, you may save it to file and load again
+    */
+   a1.save( "a1.tnl" );
+   a2.load( "a1.tnl" );
+
+   if( a2 != a1 )
+      std::cerr << "Something is wrong!!!" << std::endl;
+
+   std::cout << "a2 = " << a2 << std::endl;
+}
+
+int main()
+{
+   std::cout << "The first test runs on CPU ..." << std::endl;
+   arrayViewExample< Devices::Host >();
+#ifdef HAVE_CUDA
+   std::cout << "The second test runs on GPU ..." << std::endl;
+   arrayViewExample< Devices::Cuda >();
+#endif
+}
diff --git a/src/Examples/Containers/ArrayViewExample.cu b/src/Examples/Containers/ArrayViewExample.cu
new file mode 120000
index 0000000000000000000000000000000000000000..10c7b94b2128415b1c93b849d3ff49a1b7176709
--- /dev/null
+++ b/src/Examples/Containers/ArrayViewExample.cu
@@ -0,0 +1 @@
+ArrayViewExample.cpp
\ No newline at end of file
diff --git a/src/Examples/Containers/CMakeLists.txt b/src/Examples/Containers/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..b70b12670f085c70e9c00821b2f67fc0fe5458be
--- /dev/null
+++ b/src/Examples/Containers/CMakeLists.txt
@@ -0,0 +1,26 @@
+IF( BUILD_CUDA )
+   CUDA_ADD_EXECUTABLE( ArrayExampleCuda ArrayExample.cu )
+   ADD_CUSTOM_COMMAND( COMMAND ArrayExampleCuda > ArrayExampleCuda.out OUTPUT ArrayExampleCuda.out )
+ELSE()
+   ADD_EXECUTABLE( ArrayExample ArrayExample.cpp )
+   ADD_CUSTOM_COMMAND( COMMAND ArrayExample > ArrayExample.out OUTPUT ArrayExample.out )
+ENDIF()
+
+IF( BUILD_CUDA )
+   CUDA_ADD_EXECUTABLE( ArrayViewExampleCuda ArrayViewExample.cu )
+   ADD_CUSTOM_COMMAND( COMMAND ArrayViewExampleCuda > ArrayViewExampleCuda.out OUTPUT ArrayViewExampleCuda.out )
+ELSE()
+   ADD_EXECUTABLE( ArrayViewExample ArrayViewExample.cpp )
+   ADD_CUSTOM_COMMAND( COMMAND ArrayViewExample > ArrayViewExample.out OUTPUT ArrayViewExample.out )
+ENDIF()
+
+
+IF( BUILD_CUDA )
+ADD_CUSTOM_TARGET( RunContainersExamples-cuda ALL DEPENDS
+   ArrayExampleCuda.out
+   ArrayViewExampleCuda.out )
+ELSE()
+ADD_CUSTOM_TARGET( RunContainersExamples ALL DEPENDS
+   ArrayExample.out
+   ArrayViewExample.out )
+ENDIF()
diff --git a/src/Examples/FileExample.cpp b/src/Examples/FileExample.cpp
index 4d379f4b18f5ffd107cb5840ee745841486fa547..5239fc2144d6795a5dd1df79af47129bf314a8a6 100644
--- a/src/Examples/FileExample.cpp
+++ b/src/Examples/FileExample.cpp
@@ -4,21 +4,21 @@
 
 using namespace TNL;
 using namespace std;
-       
+
 int main()
 {
     File file;
 
-    file.open( String("new-file.tnl"), IOMode::write );
-    String title("Header");
-    file.write( &title );
+    file.open( String("new-file.tnl"), File::Mode::Out );
+    String title("'string to file'");
+    file << title;
     file.close();
 
-    file.open( String("new-file.tnl"), IOMode::read );
-    String title2;
-    file.read( &title2, 4);
+    file.open( String("new-file.tnl"), File::Mode::In );
+    String restoredString;
+    file >> restoredString;
     file.close();
 
-    cout << "title2:" << title2 <<endl;
+    cout << "restored string = " << restoredString <<endl;
 }
 
diff --git a/src/Examples/FileExampleCuda.cpp b/src/Examples/FileExampleCuda.cpp
new file mode 120000
index 0000000000000000000000000000000000000000..53d150113492bacd7c39a515657054c818a3c95b
--- /dev/null
+++ b/src/Examples/FileExampleCuda.cpp
@@ -0,0 +1 @@
+FileExampleCuda.cu
\ No newline at end of file
diff --git a/src/Examples/FileExampleCuda.cu b/src/Examples/FileExampleCuda.cu
new file mode 100644
index 0000000000000000000000000000000000000000..cd7c2839923776d453b8df4b3df7e1b8c75a86b0
--- /dev/null
+++ b/src/Examples/FileExampleCuda.cu
@@ -0,0 +1,57 @@
+#include <iostream>
+#include <TNL/File.h>
+#include <cuda.h>
+
+using namespace TNL;
+using namespace std;
+
+int main()
+{
+   const int size = 3;
+   double doubleArray[] = {  3.1415926535897932384626433,
+                             2.7182818284590452353602874,
+                             1.6180339887498948482045868 };
+
+   /***
+    * Save array to file.
+    */
+   File file;
+   file.open( "test-file.tnl", File::Mode::Out | File::Mode::Truncate );
+   file.save< double, double, Devices::Host >( doubleArray, size );
+   file.close();
+
+   /***
+    * Allocate arrays on host and device
+    */
+   double *deviceArray, *hostArray;
+   cudaMalloc( ( void** ) &deviceArray, size * sizeof( double ) );
+   hostArray = new double[ 3 ];
+
+   /***
+    * Read array from the file to device
+    */
+   file.open( "test-file.tnl", File::Mode::In );
+   file.load< double, double, Devices::Cuda >( deviceArray, size );
+   file.close();
+
+   /***
+    * Copy array from device to host
+    */
+   cudaMemcpy( ( void* ) hostArray, ( const void* ) deviceArray, size * sizeof( double), cudaMemcpyDeviceToHost );
+
+   /***
+    * Print the array on host
+    */
+   std::cout.precision( 15 );
+   for( int i = 0; i < size; i++ )
+      std::cout << hostArray[ i ] << std::endl;
+
+   /***
+    * Free allocated memory
+    */
+   cudaFree( deviceArray );
+   delete[] hostArray;
+}
+
+
+
diff --git a/src/Examples/FileExampleSaveAndLoad.cpp b/src/Examples/FileExampleSaveAndLoad.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..59718ed3ff1bbb845d1a333a078f0139d8a23ff5
--- /dev/null
+++ b/src/Examples/FileExampleSaveAndLoad.cpp
@@ -0,0 +1,48 @@
+#include <iostream>
+#include <TNL/File.h>
+
+using namespace TNL;
+using namespace std;
+
+int main()
+{
+   const int size = 3;
+   double doubleArray[] = {  3.1415926535897932384626433,
+                             2.7182818284590452353602874,
+                             1.6180339887498948482045868 };
+   float floatArray[ 3 ];
+   int intArray[ 3 ];
+
+   /***
+    * Save the array of doubles as floats.
+    */
+   File file;
+   file.open( "test-file.tnl", File::Mode::Out | File::Mode::Truncate );
+   file.save< double, float, Devices::Host >( doubleArray, size );
+   file.close();
+
+   /***
+    * Load the array of floats from the file.
+    */
+   file.open( "test-file.tnl", File::Mode::In );
+   file.load< float, float, Devices::Host >( floatArray, size );
+   file.close();
+
+   /***
+    * Load the array of floats from the file and convert them to integers.
+    */
+   file.open( "test-file.tnl", File::Mode::In );
+   file.load< int, float, Devices::Host >( intArray, size );
+   file.close();
+
+   /***
+    * Print all arrays.
+    */
+   std::cout.precision( 15 );
+   for( int i = 0; i < size; i++ )
+      std::cout << doubleArray[ i ] << " -- "
+                << floatArray[ i ] << " -- "
+                << intArray[ i ] << std::endl;
+}
+
+
diff --git a/src/Examples/FileNameExample.cpp b/src/Examples/FileNameExample.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..32425377a76c711178c2cc427997857e814c359e
--- /dev/null
+++ b/src/Examples/FileNameExample.cpp
@@ -0,0 +1,37 @@
+#include <iostream>
+#include <TNL/FileName.h>
+
+
+using namespace TNL;
+using namespace std;
+
+int main()
+{
+   /***
+    * Create file name with filename base 'velocity' and extension 'vtk'.
+    */
+   FileName fileName( "velocity-", "vtk" );
+
+   /**
+    * Set the number of digits for the index to 2 and print file names for
+    * indexes 0 to 10.
+    */
+   fileName.setDigitsCount( 2 );
+   for( int i = 0; i <= 10; i ++ )
+   {
+      fileName.setIndex( i );
+      std::cout << fileName.getFileName() << std::endl;
+   }
+
+   /***
+    * Now set the number if index digits to 3 and do the same.
+    */
+   fileName.setDigitsCount( 3 );
+   for( int i = 0; i <= 10; i ++ )
+   {
+      fileName.setIndex( i );
+      std::cout << fileName.getFileName() << std::endl;
+   }
+}
+
+
diff --git a/src/Examples/FileNameExampleDistributedSystemNodeCoordinates.cpp b/src/Examples/FileNameExampleDistributedSystemNodeCoordinates.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fc9a3626e551424a169a59c20625a064c5745a67
--- /dev/null
+++ b/src/Examples/FileNameExampleDistributedSystemNodeCoordinates.cpp
@@ -0,0 +1,34 @@
+#include <iostream>
+#include <TNL/FileName.h>
+#include <TNL/Containers/StaticVector.h>
+
+using namespace TNL;
+using namespace std;
+
+int main()
+{
+   /**
+    * Create file name with filename base 'velocity' and extension 'vtk'.
+    */
+   FileName fileName( "velocity-", "vtk" );
+
+   /***
+    * Set the distributed system node ID to 0-0-0.
+    */
+   using CoordinatesType = Containers::StaticVector< 3, int >;
+   CoordinatesType coordinates( 0, 0, 0 );
+   fileName.setDistributedSystemNodeCoordinates( coordinates );
+
+   /**
+    * Now set the file name index digits count to 2 and print file names
+    * for indexes 0 to 10.
+    */
+   fileName.setDigitsCount( 2 );
+   for( int i = 0; i <= 10; i ++ )
+   {
+      fileName.setIndex( i );
+      std::cout << fileName.getFileName() << std::endl;
+   }
+}
+
+
diff --git a/src/Examples/FileNameExampleDistributedSystemNodeId.cpp b/src/Examples/FileNameExampleDistributedSystemNodeId.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d704c96b304413eea52275fde57f4073cd458899
--- /dev/null
+++ b/src/Examples/FileNameExampleDistributedSystemNodeId.cpp
@@ -0,0 +1,31 @@
+#include <iostream>
+#include <TNL/FileName.h>
+
+using namespace TNL;
+using namespace std;
+
+int main()
+{
+   /**
+    * Create file name with filename base 'velocity' and extension 'vtk'.
+    */
+   FileName fileName( "velocity-", "vtk" );
+
+   /**
+    * Set the distributed system node ID to 0;
+    */
+   fileName.setDistributedSystemNodeId( 0 );
+
+   /**
+    * Set the number of digits for the index to 2 and print file names for
+    * indexes 0 to 10.
+    */
+   fileName.setDigitsCount( 2 );
+   for( int i = 0; i <= 10; i ++ )
+   {
+      fileName.setIndex( i );
+      std::cout << fileName.getFileName() << std::endl;
+   }
+}
+
+
diff --git a/src/Examples/ObjectExample_getType.cpp b/src/Examples/ObjectExample_getType.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7cc7476d6cc90debc1e495eab8b84959619881f7
--- /dev/null
+++ b/src/Examples/ObjectExample_getType.cpp
@@ -0,0 +1,63 @@
+#include <iostream>
+#include <TNL/param-types.h>
+#include <TNL/Object.h>
+#include <TNL/Devices/Host.h>
+#include <TNL/Devices/Cuda.h>
+
+using namespace TNL;
+using namespace std;
+
+template< typename Value,
+          typename Device >
+class MyArray : public Object
+{
+   public:
+
+      using HostType = MyArray< Value, Devices::Host >;
+      
+      static String getType()
+      {
+         return "MyArray< " + TNL::getType< Value >() + ", " + TNL::getType< Device >() + " >";
+      }
+
+      String getTypeVirtual() const
+      {
+         return getType();
+      }
+
+      static String getSerializationType()
+      {
+         return HostType::getType();
+      }
+
+      String getSerializationTypeVirtual() const
+      {
+         return getSerializationType();
+      }
+};
+
+int main()
+{
+   using HostArray = MyArray< int, Devices::Host >;
+   using CudaArray = MyArray< int, Devices::Cuda >;
+
+   HostArray hostArray;
+   CudaArray cudaArray;
+   Object* hostArrayPtr = &hostArray;
+   Object* cudaArrayPtr = &cudaArray;
+
+   // Object types
+   cout << "HostArray type is                  " << HostArray::getType() << endl;
+   cout << "hostArrayPtr type is               " << hostArrayPtr->getTypeVirtual() << endl;
+
+   cout << "CudaArray type is                  " << CudaArray::getType() << endl;
+   cout << "cudaArrayPtr type is               " << cudaArrayPtr->getTypeVirtual() << endl;
+
+   // Object serialization types
+   cout << "HostArray serialization type is    " << HostArray::getSerializationType() << endl;
+   cout << "hostArrayPtr serialization type is " << hostArrayPtr->getSerializationTypeVirtual() << endl;
+
+   cout << "CudaArray serialization type is    " << CudaArray::getSerializationType() << endl;
+   cout << "cudaArrayPtr serialization type is " << cudaArrayPtr->getSerializationTypeVirtual() << endl;
+}
+
diff --git a/src/Examples/ParseObjectTypeExample.cpp b/src/Examples/ParseObjectTypeExample.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1ded8575534cf7c210c308f8a4699519cdce1e70
--- /dev/null
+++ b/src/Examples/ParseObjectTypeExample.cpp
@@ -0,0 +1,16 @@
+#include <iostream>
+#include <TNL/Object.h>
+#include <unistd.h>
+
+using namespace TNL;
+using namespace std;
+
+int main()
+{
+   auto parsedObjectType = parseObjectType( String( "MyObject< Value, Device, Index >" ) );
+   for( auto &token : parsedObjectType )
+   {
+      cout << token << endl;
+   }
+}
+
diff --git a/src/Examples/StringExample.cpp b/src/Examples/StringExample.cpp
index a23904a4f96118ff3139f0403462e934fc8a7641..19ed24bd11d67e7b4b7d98de9c9f93c758bcbaa2 100644
--- a/src/Examples/StringExample.cpp
+++ b/src/Examples/StringExample.cpp
@@ -8,132 +8,50 @@ using namespace std;
 
 int main( int argc, char* argv[] )
 {
-    // constructors
-    String str1;
-    String str2( "string" );
-    String str3( str2 );                    // copy constructor
-    String str4 = convertToString( 28.4 );  // converts to string
-
-    cout << "str1:" << str1 << endl;
-    cout << "str2:" << str2 << endl;
-    cout << "str3:" << str3 << endl;
-    cout << "str4:" << str4 << endl;
-
-    // functions
-    /*int size = str3.getSize();
-    cout << "size of string:" << size << "bytes" << endl;
-
-    int alloc_size = str3.getAllocatedSize();
-    cout << "alloc_size:" << alloc_size << endl;
-
-    str1.setSize( 256 );
-    size = str3.getSize();
-    cout << "size of string:" << size << "bytes" << endl;*/
-
-    String setter = "Something new";
-    cout << "setter:" << setter << endl;
-
-    const char* getter = str4.getString();
-    cout << "getter:" << getter << endl;
-
-    String word( "computer" ) ;
-    char third_letter = word[2];
-    cout << "third_letter:" << third_letter << endl;
-
-    // Operators for C Strings
-    String a( "hello" );
-    a = "bye";
-    cout << "a:" << a << endl;
-
-    String b( "see" );
-    b += " you";
-    cout << "b:" << b << endl;
-
-    String c;
-    c = b + " soon";
-    cout << "c:" << c << endl;
-
-    String name( "Jack" );
-    if ( name == "Jack" ) cout << "Names are the same." << endl;
-
-    String surname( "Sparrow" );
-    if ( surname != "Jones" ) cout << "Surnames are different." << endl;
-
-    // Operators for Strings
-    String d1( "Cheese" );
-    String d = d1;
-    cout << "d:" << d << endl;
-
-    String e( "Mac&" );
-    e += d;
-    cout << "e:" << e << endl;
-
-    String f;
-    String f1("Tim likes ");
-    f = f1 + e;
-    cout << "f:" << f << endl;
-
-    String num1( "one" );
-    String num2( "Anyone", 3);
-    if ( num1 == num2 ) cout << "Numbers are the same." << endl;
-
-    String eq1( "a + b" );
-    String eq2( "a" );
-    if ( eq1 != eq2 ) cout << "Equations are different." << endl;
-
-    // Operators for single characters
-    String g;
-    g = 'y';
-    cout << "g:" << g << endl;
-
-    String h( "x" );
-    h += g;
-    cout << "h:" << h << endl;
-
-    String i;
-    i = convertToString( 'a' ) + 'b';
-    cout << "i:" << i << endl;
-
-    String letter1( "u" );
-    if ( letter1 == "u" ) cout << "Letters are the same." << endl;
-
-    String letter2( "v" );
-    if ( letter2 != "w" ) cout << "Letters are different." << endl;
-
-    // Cast to bool operators
-    String full( "string" );
-    if ( full ) cout << "String is not empty." << endl;
-
-    String empty;
-    if ( !empty ) cout << "String is empty." << endl;
-
-    // replace
-    String phrase( "Hakuna matata" );
-    String new_phrase = phrase.replace( "a", "u", 2 );
-    cout << "new_phrase:" << new_phrase << endl;
-
-    // strip
-    String names("       Josh Martin   John  Marley Charles   ");
-    String better_names = names.strip();
-    cout << "better_names:" << better_names << endl;
-
-    // split
-    String dates("3/4/2005;8/7/2011;11/12/2019");
-    std::vector<String> list = dates.split(';');
-    cout << "list_dates: " << list[0] << ", " << list[1] << ", " << list[2] << endl;
-
-    String cars("opel,mazda,,skoda,");
-    std::vector<String> list3 = cars.split(',', true);
-    cout << "split with true:" << list3[0] << ", " << list3[1] << ", " << list3[2] << endl;
-    std::vector<String> list5 = cars.split(',');
-    cout << "split with false:" << list5[0] << ", " << list5[1] << ", " << list5[2] << ", " << list5[3] << endl;
-
-    // save
-    File myFile;
-    myFile << String("Header"); // saves "Header" into myFile
-
-    // load
-    String strg;
-    myFile >> strg;
-    cout << "strg:" << strg << endl;
+   String emptyString;
+   String string1( "string 1" );
+   String string2( "string 2" );
+   String string3( string2 );
+   String string4 = convertToString( 28.4 );
+
+   cout << "empytString = " << emptyString << endl;
+   cout << "string1 = " << string1 << endl;
+   cout << "string2 = " << string2 << endl;
+   cout << "string3 = " << string3 << endl;
+   cout << "string4 = " << string4 << endl;
+
+   cout << "emptyString size = " << emptyString.getSize() << endl;
+   cout << "string1 size = " << string1.getSize() << endl;
+   cout << "string1 length = " << string1.getLength() << endl;
+
+   const char* c_string = string1.getString();
+   cout << "c_string = " << c_string << endl;
+
+   cout << " 3rd letter of string1 =" << string1[ 2 ] << endl;
+
+   cout << " string1 + string2 = " << string1 + string2 << endl;
+   cout << " string1 + \" another string\" = " << string1 + " another string" << endl;
+   
+   string2 += "another string";
+   cout << " string2 = " << string2;
+   string2 = "string 2";
+
+   if( string3 == string2 )
+      cout << "string3 == string2" << endl;
+   if( string1 != string2 )
+      cout << "string1 != string2" << endl;
+
+   if( ! emptyString )
+      cout << "emptyString is empty" << endl;
+   if( string1 )
+      cout << "string1 is not empty" << endl;
+
+   File myFile;
+   myFile.open( "string_save.out", File::Mode::Out );
+   myFile << string1;
+   myFile.close();
+
+   myFile.open( "string_save.out", File::Mode::In );
+   myFile >> string3;
+   cout << "string 3 after loading = " << string3 << endl;
 }
diff --git a/src/Examples/StringExampleGetAllocatedSize.cpp b/src/Examples/StringExampleGetAllocatedSize.cpp
index ad616de67304d41769fbd4389a0d2d3e03e90546..2065c6d1ff98d9e8905446702a206f0f3b9c5a6e 100644
--- a/src/Examples/StringExampleGetAllocatedSize.cpp
+++ b/src/Examples/StringExampleGetAllocatedSize.cpp
@@ -3,10 +3,9 @@
 
 using namespace TNL;
 using namespace std;
-       
+
 int main()
 {
     String str("my world");
-    int alloc_size = str.getAllocatedSize();
-    cout << "alloc_size:" << alloc_size << endl;
+    cout << "Allocated_size = " << str.getAllocatedSize() << endl;
 }
\ No newline at end of file
diff --git a/src/Examples/StringExampleGetSize.cpp b/src/Examples/StringExampleGetSize.cpp
deleted file mode 100644
index 77fb499a478f45b9da7355355e01c747bdd1e639..0000000000000000000000000000000000000000
--- a/src/Examples/StringExampleGetSize.cpp
+++ /dev/null
@@ -1,13 +0,0 @@
-#include <iostream>
-#include <TNL/String.h>
-
-using namespace TNL;
-using namespace std;
-       
-int main()
-{
-    String str("my world");
-    int size = str.getSize();
-    cout << "size of string:" << size << "bytes" << endl;
-}
-
diff --git a/src/Examples/StringExampleReplace.cpp b/src/Examples/StringExampleReplace.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f24c82b1e9064563be7f72af6bbdf1e89017fe42
--- /dev/null
+++ b/src/Examples/StringExampleReplace.cpp
@@ -0,0 +1,13 @@
+#include <iostream>
+#include <TNL/String.h>
+
+using namespace TNL;
+using namespace std;
+
+int main()
+{
+   String phrase( "Say yes yes yes!" );
+   cout << "phrase.replace( \"yes\", \"no\", 1 ) = " << phrase.replace( "yes", "no", 1 ) << endl;
+   cout << "phrase.replace( \"yes\", \"no\", 2 ) = " << phrase.replace( "yes", "no", 2 ) << endl;
+   cout << "phrase.replace( \"yes\", \"no\", 3 ) = " << phrase.replace( "yes", "no", 3 ) << endl;
+}
\ No newline at end of file
diff --git a/src/Examples/StringExampleSetSize.cpp b/src/Examples/StringExampleSetSize.cpp
index 8451295a75a87f49e46c286cb5ef6ea94c06dcc8..2b9de7844469e500271e0a10b347dd36a52dacd4 100644
--- a/src/Examples/StringExampleSetSize.cpp
+++ b/src/Examples/StringExampleSetSize.cpp
@@ -3,11 +3,11 @@
 
 using namespace TNL;
 using namespace std;
-       
+
 int main()
 {
-    String memory;
-    memory.setSize( 256 );
-    int memorysize = memory.getSize();
-    cout << "memory:" << memorysize << endl;
+    String string;
+    string.setSize( 1024 );
+    cout << "String size = " << string.getSize() << endl;
+    cout << "Allocated size = " << string.getAllocatedSize() << endl;
 }
diff --git a/src/Examples/StringExampleSplit.cpp b/src/Examples/StringExampleSplit.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d0b45e52586d8eced440fdf422c1a20f01d3e1ba
--- /dev/null
+++ b/src/Examples/StringExampleSplit.cpp
@@ -0,0 +1,18 @@
+#include <iostream>
+#include <TNL/String.h>
+
+using namespace TNL;
+using namespace std;
+
+int main()
+{
+   String dates("3/4/2005;8/7/2011;11/12/2019");
+   vector< String > list = dates.split(';');
+   cout << "list_dates = " << list[0] << ", " << list[1] << ", " << list[2] << endl;
+
+   String cars("Subaru,Mazda,,Skoda," );
+   vector< String > list3 = cars.split(',', String::SplitSkip::SkipEmpty );
+   cout << "split with String::SkipEmpty = " << list3[0] << ", " << list3[1] << ", " << list3[2] << endl;
+   std::vector<String> list5 = cars.split(',');
+   cout << "split without  String::SkipEmpty = " << list5[0] << ", " << list5[1] << ", " << list5[2] << ", " << list5[3] << endl;
+}
diff --git a/src/Examples/StringExampleStrip.cpp b/src/Examples/StringExampleStrip.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ed3fd656ce5d0244a4caed6034efdad5cf7796c8
--- /dev/null
+++ b/src/Examples/StringExampleStrip.cpp
@@ -0,0 +1,13 @@
+#include <iostream>
+#include <TNL/String.h>
+
+using namespace TNL;
+using namespace std;
+
+int main()
+{
+    String names(  "       Josh Martin   John  Marley Charles   " );
+    String names2( ".......Josh Martin...John..Marley.Charles..." );
+    cout << "names strip is: " << names.strip() << endl;
+    cout << "names2 strip is: " << names.strip( '.' ) << endl;
+}
\ No newline at end of file
diff --git a/src/Examples/TimerExample.cpp b/src/Examples/TimerExample.cpp
index 5d5a814540aa7265e023efb571627dffc3c47334..ab8cdb8635cffce0e89379e41ee1f601d4885c6f 100644
--- a/src/Examples/TimerExample.cpp
+++ b/src/Examples/TimerExample.cpp
@@ -1,11 +1,10 @@
 #include <iostream>
 #include <TNL/Timer.h>
-#include <TNL/Logger.h>
 #include <unistd.h>
 
 using namespace TNL;
 using namespace std;
-       
+
 int main()
 {
     unsigned int microseconds = 0.5;
@@ -13,11 +12,12 @@ int main()
     time.start();
     usleep(microseconds);
     time.stop();
-    cout << "before reset:" << time.getRealTime() << endl;
+    cout << "Elapsed real time: " << time.getRealTime() << endl;
+    cout << "Elapsed CPU time: " << time.getCPUTime() << endl;
+    cout << "Elapsed CPU cycles: " << time.getCPUCycles() << endl;
     time.reset();
-    cout << "after reset:" << time.getRealTime() << endl;
-    // writeLog example
-    Logger log1(50,cout);
-    time.writeLog( log1, 0 );
+    cout << "Real time after reset:" << time.getRealTime() << endl;
+    cout << "CPU time after reset: " << time.getCPUTime() << endl;
+    cout << "CPU cycles after reset: " << time.getCPUCycles() << endl;
 }
 
diff --git a/src/Examples/TimerExampleLogger.cpp b/src/Examples/TimerExampleLogger.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..96dde57022418be1174c2e7278e11d10d58c845b
--- /dev/null
+++ b/src/Examples/TimerExampleLogger.cpp
@@ -0,0 +1,19 @@
+#include <iostream>
+#include <TNL/Timer.h>
+#include <TNL/Logger.h>
+#include <unistd.h>
+
+using namespace TNL;
+using namespace std;
+
+int main()
+{
+    unsigned int microseconds = 0.5;
+    Timer time;
+    time.start();
+    usleep(microseconds);
+    time.stop();
+
+    Logger logger( 50,cout );
+    time.writeLog( logger, 0 );
+}
diff --git a/src/Examples/flow-sw/navierStokesProblem_impl.h b/src/Examples/flow-sw/navierStokesProblem_impl.h
index fbe14668a3af75727800a9038d6f77962b47848a..886c9f03f4e981cd9533d72ba5f71809388c6438 100644
--- a/src/Examples/flow-sw/navierStokesProblem_impl.h
+++ b/src/Examples/flow-sw/navierStokesProblem_impl.h
@@ -193,16 +193,13 @@ makeSnapshot( const RealType& time,
    fileName.setExtension( "tnl" );
    fileName.setIndex( step );
    fileName.setFileNameBase( "density-" );
-   if( ! this->conservativeVariables->getDensity()->save( fileName.getFileName() ) )
-      return false;
+   this->conservativeVariables->getDensity()->save( fileName.getFileName() );
    
    fileName.setFileNameBase( "velocity-" );
-   if( ! this->velocity->save( fileName.getFileName() ) )
-      return false;
+   this->velocity->save( fileName.getFileName() );
 
    fileName.setFileNameBase( "pressure-" );
-   if( ! this->pressure->save( fileName.getFileName() ) )
-      return false;
+   this->pressure->save( fileName.getFileName() );
 
    /*fileName.setFileNameBase( "energy-" );
    if( ! this->conservativeVariables->getEnergy()->save( fileName.getFileName() ) )
diff --git a/src/Examples/flow-vl/navierStokesProblem_impl.h b/src/Examples/flow-vl/navierStokesProblem_impl.h
index fbe14668a3af75727800a9038d6f77962b47848a..886c9f03f4e981cd9533d72ba5f71809388c6438 100644
--- a/src/Examples/flow-vl/navierStokesProblem_impl.h
+++ b/src/Examples/flow-vl/navierStokesProblem_impl.h
@@ -193,16 +193,13 @@ makeSnapshot( const RealType& time,
    fileName.setExtension( "tnl" );
    fileName.setIndex( step );
    fileName.setFileNameBase( "density-" );
-   if( ! this->conservativeVariables->getDensity()->save( fileName.getFileName() ) )
-      return false;
+   this->conservativeVariables->getDensity()->save( fileName.getFileName() );
    
    fileName.setFileNameBase( "velocity-" );
-   if( ! this->velocity->save( fileName.getFileName() ) )
-      return false;
+   this->velocity->save( fileName.getFileName() );
 
    fileName.setFileNameBase( "pressure-" );
-   if( ! this->pressure->save( fileName.getFileName() ) )
-      return false;
+   this->pressure->save( fileName.getFileName() );
 
    /*fileName.setFileNameBase( "energy-" );
    if( ! this->conservativeVariables->getEnergy()->save( fileName.getFileName() ) )
diff --git a/src/Examples/flow/navierStokesProblem_impl.h b/src/Examples/flow/navierStokesProblem_impl.h
index 96603490cf90a3834e6c9107242641614e04d5fb..4b0c7977441e87cab05fccab2c3984705670cfd4 100644
--- a/src/Examples/flow/navierStokesProblem_impl.h
+++ b/src/Examples/flow/navierStokesProblem_impl.h
@@ -209,8 +209,7 @@ makeSnapshot( const RealType& time,
 //      return false;
    
    fileName.setFileNameBase( "velocity-" );
-   if( ! this->velocity->save( fileName.getFileName() ) )
-      return false;
+   this->velocity->save( fileName.getFileName() );
 
 //   fileName.setFileNameBase( "pressure-" );
 //   if( ! this->pressure->save( fileName.getFileName() ) )
diff --git a/src/Examples/inviscid-flow-sw/eulerProblem_impl.h b/src/Examples/inviscid-flow-sw/eulerProblem_impl.h
index e043589cc7eb0330ab3f3caedfc6fa14ee1aa374..e0382e9c2485bbec5740df99af47b87a28122139 100644
--- a/src/Examples/inviscid-flow-sw/eulerProblem_impl.h
+++ b/src/Examples/inviscid-flow-sw/eulerProblem_impl.h
@@ -190,24 +190,19 @@ makeSnapshot( const RealType& time,
    fileName.setExtension( "tnl" );
    fileName.setIndex( step );
    fileName.setFileNameBase( "density-" );
-   if( ! this->conservativeVariables->getDensity()->save( fileName.getFileName() ) )
-      return false;
+   this->conservativeVariables->getDensity()->save( fileName.getFileName() );
    
    fileName.setFileNameBase( "velocity-" );
-   if( ! this->velocity->save( fileName.getFileName() ) )
-      return false;
+   this->velocity->save( fileName.getFileName() );
 
    fileName.setFileNameBase( "pressure-" );
-   if( ! this->pressure->save( fileName.getFileName() ) )
-      return false;
+   this->pressure->save( fileName.getFileName() );
 
    fileName.setFileNameBase( "energy-" );
-   if( ! this->conservativeVariables->getEnergy()->save( fileName.getFileName() ) )
-      return false;
+   this->conservativeVariables->getEnergy()->save( fileName.getFileName() );
 
    fileName.setFileNameBase( "momentum-" );
-   if( ! this->conservativeVariables->getMomentum()->save( fileName.getFileName() ) )
-      return false;
+   this->conservativeVariables->getMomentum()->save( fileName.getFileName() );
    
    return true;
 }
diff --git a/src/Examples/inviscid-flow-vl/eulerProblem_impl.h b/src/Examples/inviscid-flow-vl/eulerProblem_impl.h
index e043589cc7eb0330ab3f3caedfc6fa14ee1aa374..e0382e9c2485bbec5740df99af47b87a28122139 100644
--- a/src/Examples/inviscid-flow-vl/eulerProblem_impl.h
+++ b/src/Examples/inviscid-flow-vl/eulerProblem_impl.h
@@ -190,24 +190,19 @@ makeSnapshot( const RealType& time,
    fileName.setExtension( "tnl" );
    fileName.setIndex( step );
    fileName.setFileNameBase( "density-" );
-   if( ! this->conservativeVariables->getDensity()->save( fileName.getFileName() ) )
-      return false;
+   this->conservativeVariables->getDensity()->save( fileName.getFileName() );
    
    fileName.setFileNameBase( "velocity-" );
-   if( ! this->velocity->save( fileName.getFileName() ) )
-      return false;
+   this->velocity->save( fileName.getFileName() );
 
    fileName.setFileNameBase( "pressure-" );
-   if( ! this->pressure->save( fileName.getFileName() ) )
-      return false;
+   this->pressure->save( fileName.getFileName() );
 
    fileName.setFileNameBase( "energy-" );
-   if( ! this->conservativeVariables->getEnergy()->save( fileName.getFileName() ) )
-      return false;
+   this->conservativeVariables->getEnergy()->save( fileName.getFileName() );
 
    fileName.setFileNameBase( "momentum-" );
-   if( ! this->conservativeVariables->getMomentum()->save( fileName.getFileName() ) )
-      return false;
+   this->conservativeVariables->getMomentum()->save( fileName.getFileName() );
    
    return true;
 }
diff --git a/src/Examples/inviscid-flow/eulerProblem_impl.h b/src/Examples/inviscid-flow/eulerProblem_impl.h
index 7347755cb118832f86b1015dac5d16428294ad3f..f992a30671844f1e94d0e3007b86a6f807e33e14 100644
--- a/src/Examples/inviscid-flow/eulerProblem_impl.h
+++ b/src/Examples/inviscid-flow/eulerProblem_impl.h
@@ -190,20 +190,16 @@ makeSnapshot( const RealType& time,
    fileName.setExtension( "tnl" );
    fileName.setIndex( step );
    fileName.setFileNameBase( "density-" );
-   if( ! this->conservativeVariables->getDensity()->save( fileName.getFileName() ) )
-      return false;
+   this->conservativeVariables->getDensity()->save( fileName.getFileName() );
    
    fileName.setFileNameBase( "velocity-" );
-   if( ! this->velocity->save( fileName.getFileName() ) )
-      return false;
+   this->velocity->save( fileName.getFileName() );
 
    fileName.setFileNameBase( "pressure-" );
-   if( ! this->pressure->save( fileName.getFileName() ) )
-      return false;
+   this->pressure->save( fileName.getFileName() );
 
    fileName.setFileNameBase( "energy-" );
-   if( ! this->conservativeVariables->getEnergy()->save( fileName.getFileName() ) )
-      return false;
+   this->conservativeVariables->getEnergy()->save( fileName.getFileName() );
    
    return true;
 }
diff --git a/src/Examples/quad-test/main.cpp b/src/Examples/quad-test/main.cpp
index 583d3c4ca8470297d320ec305a99e96f6ef547d7..7f4626d74a1b553c7ff624419b454b85fb69a78a 100644
--- a/src/Examples/quad-test/main.cpp
+++ b/src/Examples/quad-test/main.cpp
@@ -34,7 +34,7 @@ int main(int argc, char* argv[]) {
 
 	String inputFile = parameters.getParameter <String> ("input-file");
 	File binaryFile;
-	if(! binaryFile.open(inputFile, IOMode::read)) {
+	if(! binaryFile.open(inputFile, File::Mode::In)) {
 		cerr << "I am not able to open the file " << inputFile << "." << std::endl;
 		return 1;
 	}
diff --git a/src/Examples/transport-equation/transportEquationProblemEoc_impl.h b/src/Examples/transport-equation/transportEquationProblemEoc_impl.h
index 512e310d2f62ac5e118a729db9a1c5ae775bef89..0ac3af2d8d963ea89cbb9a40837cc298c243fa40 100644
--- a/src/Examples/transport-equation/transportEquationProblemEoc_impl.h
+++ b/src/Examples/transport-equation/transportEquationProblemEoc_impl.h
@@ -100,8 +100,7 @@ setup( const Config::ParameterContainer& parameters,
          fileName.setFileNameBase( "exact-u-" );
          fileName.setExtension( "tnl" );
          fileName.setIndex( step );
-         if( ! u->save( fileName.getFileName() ) )
-            return false;
+         u->save( fileName.getFileName() );
          while( time < finalTime )
          {
             time += snapshotPeriod;
@@ -112,8 +111,7 @@ setup( const Config::ParameterContainer& parameters,
             std::cerr << exactSolution->getOperator().getShift() << std::endl;
             evaluator.evaluate( u, exactSolution, time );
             fileName.setIndex( ++step );
-            if( ! u->save( fileName.getFileName() ) )
-               return false;
+            u->save( fileName.getFileName() );
          }
       }
       if( velocityFieldType == "rotation" )
@@ -141,7 +139,11 @@ setInitialCondition( const Config::ParameterContainer& parameters,
    fileName.setFileNameBase( "exact-u-" );
    fileName.setExtension( "tnl" );
    fileName.setIndex( 0 );   
-   if( ! this->uPointer->boundLoad( fileName.getFileName() ) )
+   try
+   {
+      this->uPointer->boundLoad( fileName.getFileName() );
+   }
+   catch(...)
    {
       std::cerr << "I am not able to load the initial condition from the file " << fileName.getFileName() << "." << std::endl;
       return false;
diff --git a/src/Examples/transport-equation/transportEquationProblem_impl.h b/src/Examples/transport-equation/transportEquationProblem_impl.h
index 2d019602cc69f4703ac8caa5d81d8ad9d26e7275..80c018e853f859adf5e9138fa6dfb2d65fc550b4 100644
--- a/src/Examples/transport-equation/transportEquationProblem_impl.h
+++ b/src/Examples/transport-equation/transportEquationProblem_impl.h
@@ -117,7 +117,11 @@ setInitialCondition( const Config::ParameterContainer& parameters,
 {
    this->bindDofs( dofs );
    const String& initialConditionFile = parameters.getParameter< String >( "initial-condition" );
-   if( ! this->uPointer->boundLoad( initialConditionFile ) )
+   try
+   {
+      this->uPointer->boundLoad( initialConditionFile );
+   }
+   catch(...)
    {
       std::cerr << "I am not able to load the initial condition from the file " << initialConditionFile << "." << std::endl;
       return false;
@@ -169,8 +173,7 @@ makeSnapshot( const RealType& time,
    fileName.setFileNameBase( "u-" );
    fileName.setExtension( "tnl" );
    fileName.setIndex( step );
-   if( ! printDofs.save( fileName.getFileName() ) )
-      return false;
+   printDofs.save( fileName.getFileName() );
    return true;
 }
 
diff --git a/src/Python/pytnl/tnl/Object.cpp b/src/Python/pytnl/tnl/Object.cpp
index cd592a2c6ac8eb0e3cd24ce09c5e27110e92f8a2..56b0f54e523df5201a3a14261d3ab712f1ea11da 100644
--- a/src/Python/pytnl/tnl/Object.cpp
+++ b/src/Python/pytnl/tnl/Object.cpp
@@ -10,13 +10,13 @@ void export_Object( py::module & m )
 {
     py::class_< TNL::Object >( m, "Object" )
         // TODO: make it abstract class in Python
-        .def("save", (bool (TNL::Object::*)(const TNL::String &) const) &TNL::Object::save)
-        .def("load", (bool (TNL::Object::*)(const TNL::String &)) &TNL::Object::load)
-        .def("boundLoad", (bool (TNL::Object::*)(const TNL::String &)) &TNL::Object::boundLoad)
+        .def("save", (void (TNL::Object::*)(const TNL::String &) const) &TNL::Object::save)
+        .def("load", (void (TNL::Object::*)(const TNL::String &)) &TNL::Object::load)
+        .def("boundLoad", (void (TNL::Object::*)(const TNL::String &)) &TNL::Object::boundLoad)
         // FIXME: why does it not work?
 //        .def("save", py::overload_cast<TNL::File>(&TNL::Object::save, py::const_))
 //        .def("load", py::overload_cast<TNL::File>(&TNL::Object::load))
-        .def("save", (bool (TNL::Object::*)(TNL::File &) const) &TNL::Object::save)
-        .def("load", (bool (TNL::Object::*)(TNL::File &)) &TNL::Object::load)
+        .def("save", (void (TNL::Object::*)(TNL::File &) const) &TNL::Object::save)
+        .def("load", (void (TNL::Object::*)(TNL::File &)) &TNL::Object::load)
     ;
 }
diff --git a/src/TNL/Communicators/MPIPrint.h b/src/TNL/Communicators/MPIPrint.h
index 52684e5740c8a503fbb7e3de8c6723c587a0014c..825ae239f92487358a3eeae71479a8624025fc5e 100644
--- a/src/TNL/Communicators/MPIPrint.h
+++ b/src/TNL/Communicators/MPIPrint.h
@@ -25,7 +25,7 @@ else
       __tnl_mpi_print_stream_ << "Node " << TNL::Communicators::MpiCommunicator::GetRank() << " of "                             \
          << TNL::Communicators::MpiCommunicator::GetSize() << " : " << message << std::endl;                                     \
       TNL::String __tnl_mpi_print_string_( __tnl_mpi_print_stream_.str().c_str() );                                              \
-      __tnl_mpi_print_string_.send( 0, std::numeric_limits< int >::max() );                                                                                         \
+      mpiSend( __tnl_mpi_print_string_, 0, std::numeric_limits< int >::max() );                                                                                         \
    }                                                                                                                             \
    else                                                                                                                          \
    {                                                                                                                             \
@@ -35,7 +35,7 @@ else
            __tnl_mpi_print_j++ )                                                                                                 \
          {                                                                                                                       \
             TNL::String __tnl_mpi_print_string_;                                                                                 \
-            __tnl_mpi_print_string_.receive( __tnl_mpi_print_j, std::numeric_limits< int >::max() );                                                                \
+            mpiReceive( __tnl_mpi_print_string_, __tnl_mpi_print_j, std::numeric_limits< int >::max() );                                                                \
             std::cerr << __tnl_mpi_print_string_;                                                                                \
          }                                                                                                                       \
    }                                                                                                                             \
@@ -78,7 +78,7 @@ else
          __tnl_mpi_print_stream_ << "Node " << TNL::Communicators::MpiCommunicator::GetRank() << " of "                          \
             << TNL::Communicators::MpiCommunicator::GetSize() << " : " << message << std::endl;                                  \
          TNL::String __tnl_mpi_print_string_( __tnl_mpi_print_stream_.str().c_str() );                                           \
-         __tnl_mpi_print_string_.send( 0, std::numeric_limits< int >::max() );                                                                                      \
+         mpiSsend( __tnl_mpi_print_string_, 0, std::numeric_limits< int >::max() );                                                                                      \
       }                                                                                                                          \
    }                                                                                                                             \
    else                                                                                                                          \
@@ -94,7 +94,7 @@ else
             if( __tnl_mpi_print_cond )                                                                                           \
             {                                                                                                                    \
                TNL::String __tnl_mpi_print_string_;                                                                              \
-               __tnl_mpi_print_string_.receive( __tnl_mpi_print_j, std::numeric_limits< int >::max() );                                                             \
+               mpiReceive( __tnl_mpi_print_string_, __tnl_mpi_print_j, std::numeric_limits< int >::max() );                                                             \
                std::cerr << __tnl_mpi_print_string_;                                                                             \
             }                                                                                                                    \
          }                                                                                                                       \
diff --git a/src/TNL/Containers/Algorithms/ArrayAssignment.h b/src/TNL/Containers/Algorithms/ArrayAssignment.h
new file mode 100644
index 0000000000000000000000000000000000000000..62ab43a84aa4046ee195439bd3102d1be579f4f7
--- /dev/null
+++ b/src/TNL/Containers/Algorithms/ArrayAssignment.h
@@ -0,0 +1,93 @@
+/***************************************************************************
+                          ArrayOperations.h  -  description
+                             -------------------
+    begin                : Jul 15, 2013
+    copyright            : (C) 2013 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include<type_traits>
+#include<utility>
+#include <TNL/Containers/Algorithms/ArrayOperations.h>
+
+namespace TNL {
+namespace Containers {
+namespace Algorithms {
+
+namespace Details {
+/**
+ * SFINAE for checking if T has getArrayData method
+ */
+template< typename T >
+class HasGetArrayData
+{
+private:
+    typedef char YesType[1];
+    typedef char NoType[2];
+
+    template< typename C > static YesType& test( decltype(std::declval< C >().getArrayData()) );
+    template< typename C > static NoType& test(...);
+
+public:
+    static constexpr bool value = ( sizeof( test< T >(0) ) == sizeof( YesType ) );
+};
+} // namespace Details
+
+template< typename Array,
+          typename T,
+          bool hasGetArrayData = Details::HasGetArrayData< T >::value >
+struct ArrayAssignment{};
+
+/**
+ * \brief Specialization for array-array assignment with containers implementing
+ * getArrayData method.
+ */
+template< typename Array,
+          typename T >
+struct ArrayAssignment< Array, T, true >
+{
+   static void resize( Array& a, const T& t )
+   {
+      a.setSize( t.getSize() );
+   }
+
+   static void assign( Array& a, const T& t )
+   {
+      TNL_ASSERT_EQ( a.getSize(), t.getSize(), "The sizes of the arrays must be equal." );
+      if( t.getSize() > 0 ) // we allow even assignment of empty arrays
+         ArrayOperations< typename Array::DeviceType, typename T::DeviceType >::template
+            copyMemory< typename Array::ValueType, typename T::ValueType, typename Array::IndexType >
+            ( a.getArrayData(), t.getArrayData(), t.getSize() );
+   };
+};
+
+/**
+ * \brief Specialization for array-value assignment for other types. We assume
+ * that T is convertible to Array::ValueType.
+ */
+template< typename Array,
+          typename T >
+struct ArrayAssignment< Array, T, false >
+{
+   static void resize( Array& a, const T& t )
+   {
+   };
+   static void assign( Array& a, const T& t )
+   {
+      TNL_ASSERT_FALSE( a.empty(), "Cannot assign value to empty array." );
+      ArrayOperations< typename Array::DeviceType >::template
+         setMemory< typename Array::ValueType, typename Array::IndexType >
+         ( a.getArrayData(), ( typename Array::ValueType ) t, a.getSize() );
+   };
+
+};
+
+
+
+} // namespace Algorithms
+} // namespace Containers
+} // namespace TNL
diff --git a/src/TNL/Containers/Algorithms/ArrayIO.h b/src/TNL/Containers/Algorithms/ArrayIO.h
index 9b14f7cca0e68a928ac166ed4ae7f2ba147784f7..77e82355f82d414dc77224633ed5bc79a6f4fb08 100644
--- a/src/TNL/Containers/Algorithms/ArrayIO.h
+++ b/src/TNL/Containers/Algorithms/ArrayIO.h
@@ -71,14 +71,16 @@ class ArrayIO< Value, Device, Index, false >
                      const Value* data,
                      const Index elements )
    {
-      return file.write< Value, Device >( data, elements );
+      file.save< Value, Value, Device >( data, elements );
+      return true;
    }
 
    static bool load( File& file,
                      Value* data,
                      const Index elements )
    {
-      return file.read< Value, Device >( data, elements );
+      file.load< Value, Value, Device >( data, elements );
+      return true;
    }
 
 };
diff --git a/src/TNL/Containers/Algorithms/ArrayOperations.h b/src/TNL/Containers/Algorithms/ArrayOperations.h
index 47050d32fd8f037251e3fe5258c98fe4d5f90b2c..a6acc816edc4e20a73949c49df42164e365475b9 100644
--- a/src/TNL/Containers/Algorithms/ArrayOperations.h
+++ b/src/TNL/Containers/Algorithms/ArrayOperations.h
@@ -10,6 +10,7 @@
 
 #pragma once
 
+#include <list>
 #include <TNL/Devices/Host.h>
 #include <TNL/Devices/Cuda.h>
 #include <TNL/Devices/MIC.h>
@@ -53,6 +54,11 @@ class ArrayOperations< Devices::Host >
                               const SourceElement* source,
                               const Index size );
 
+      template< typename DestinationElement,
+                typename SourceElement >
+      static void copySTLList( DestinationElement* destination,
+                               const std::list< SourceElement >& source );
+
       template< typename Element1,
                 typename Element2,
                 typename Index >
@@ -104,6 +110,11 @@ class ArrayOperations< Devices::Cuda >
                               const SourceElement* source,
                               const Index size );
 
+      template< typename DestinationElement,
+                typename SourceElement >
+      static void copySTLList( DestinationElement* destination,
+                               const std::list< SourceElement >& source );
+
       template< typename Element1,
                 typename Element2,
                 typename Index >
@@ -196,6 +207,11 @@ class ArrayOperations< Devices::MIC >
                               const SourceElement* source,
                               const Index size );
 
+      template< typename DestinationElement,
+                typename SourceElement >
+      static void copySTLList( DestinationElement* destination,
+                               const std::list< SourceElement >& source );
+
       template< typename Element1,
                 typename Element2,
                 typename Index >
@@ -260,6 +276,6 @@ class ArrayOperations< Devices::Host, Devices::MIC >
 } // namespace Containers
 } // namespace TNL
 
-#include <TNL/Containers/Algorithms/ArrayOperationsHost_impl.h>
-#include <TNL/Containers/Algorithms/ArrayOperationsCuda_impl.h>
-#include <TNL/Containers/Algorithms/ArrayOperationsMIC_impl.h>
+#include <TNL/Containers/Algorithms/ArrayOperationsHost.hpp>
+#include <TNL/Containers/Algorithms/ArrayOperationsCuda.hpp>
+#include <TNL/Containers/Algorithms/ArrayOperationsMIC.hpp>
diff --git a/src/TNL/Containers/Algorithms/ArrayOperationsCuda_impl.h b/src/TNL/Containers/Algorithms/ArrayOperationsCuda.hpp
similarity index 90%
rename from src/TNL/Containers/Algorithms/ArrayOperationsCuda_impl.h
rename to src/TNL/Containers/Algorithms/ArrayOperationsCuda.hpp
index 34946628a0ed9bb60b70b8802e30cc4c1385e8c6..3efe7e4d472bb5d9766faee73946941a480374e4 100644
--- a/src/TNL/Containers/Algorithms/ArrayOperationsCuda_impl.h
+++ b/src/TNL/Containers/Algorithms/ArrayOperationsCuda.hpp
@@ -171,6 +171,29 @@ copyMemory( DestinationElement* destination,
 #endif
 }
 
+template< typename DestinationElement,
+          typename SourceElement >
+void
+ArrayOperations< Devices::Cuda >::
+copySTLList( DestinationElement* destination,
+             const std::list< SourceElement >& source )
+{
+   const auto size = source.size();
+   const std::size_t copy_buffer_size = std::min( Devices::Cuda::TransferBufferSize / (std::size_t) sizeof( DestinationElement ), ( std::size_t ) size );
+   using BaseType = typename std::remove_cv< DestinationElement >::type;
+   std::unique_ptr< BaseType[] > copy_buffer{ new BaseType[ copy_buffer_size ] };
+   size_t copiedElements = 0;
+   auto it = source.begin();
+   while( copiedElements < size )
+   {
+      const auto copySize = std::min( size - copiedElements, copy_buffer_size );
+      for( size_t i = 0; i < copySize; i++ )
+         copy_buffer[ i ] = static_cast< DestinationElement >( * it ++ );
+      ArrayOperations< Devices::Cuda, Devices::Host >::copyMemory( &destination[ copiedElements ], &copy_buffer[ 0 ], copySize );
+      copiedElements += copySize;
+   }
+}
+
 template< typename Element1,
           typename Element2,
           typename Index >
@@ -245,7 +268,8 @@ copyMemory( DestinationElement* destination,
    }
    else
    {
-      std::unique_ptr< SourceElement[] > buffer{ new SourceElement[ Devices::Cuda::getGPUTransferBufferSize() ] };
+      using BaseType = typename std::remove_cv< SourceElement >::type;
+      std::unique_ptr< BaseType[] > buffer{ new BaseType[ Devices::Cuda::getGPUTransferBufferSize() ] };
       Index i( 0 );
       while( i < size )
       {
diff --git a/src/TNL/Containers/Algorithms/ArrayOperationsHost_impl.h b/src/TNL/Containers/Algorithms/ArrayOperationsHost.hpp
similarity index 93%
rename from src/TNL/Containers/Algorithms/ArrayOperationsHost_impl.h
rename to src/TNL/Containers/Algorithms/ArrayOperationsHost.hpp
index 18fe544ea120c8ebd7596e325a8bf01a9a9274c3..ff24b237deaa074b7e3a46602606957fbb0fc629 100644
--- a/src/TNL/Containers/Algorithms/ArrayOperationsHost_impl.h
+++ b/src/TNL/Containers/Algorithms/ArrayOperationsHost.hpp
@@ -100,6 +100,19 @@ copyMemory( DestinationElement* destination,
          destination[ i ] = ( DestinationElement ) source[ i ];
 }
 
+template< typename DestinationElement,
+          typename SourceElement >
+void
+ArrayOperations< Devices::Host >::
+copySTLList( DestinationElement* destination,
+             const std::list< SourceElement >& source )
+{
+   size_t i = 0;
+   for( const SourceElement& e : source )
+      destination[ i ++ ] = static_cast< DestinationElement >( e );
+}
+
+
 template< typename DestinationElement,
           typename SourceElement,
           typename Index >
diff --git a/src/TNL/Containers/Algorithms/ArrayOperationsMIC_impl.h b/src/TNL/Containers/Algorithms/ArrayOperationsMIC.hpp
similarity index 97%
rename from src/TNL/Containers/Algorithms/ArrayOperationsMIC_impl.h
rename to src/TNL/Containers/Algorithms/ArrayOperationsMIC.hpp
index 1823d8077eb8a69364c457708e2287b19179cc31..b41e09f0bee1bfee02d2587b0cb865a8d4f78e91 100644
--- a/src/TNL/Containers/Algorithms/ArrayOperationsMIC_impl.h
+++ b/src/TNL/Containers/Algorithms/ArrayOperationsMIC.hpp
@@ -139,6 +139,16 @@ copyMemory( DestinationElement* destination,
    #endif
 }
 
+template< typename DestinationElement,
+          typename SourceElement >
+void
+ArrayOperations< Devices::MIC >::
+copySTLList( DestinationElement* destination,
+                  const std::list< SourceElement >& source )
+{
+   TNL_ASSERT( false, std::cerr << "TODO" );
+}
+
 template< typename Element1,
           typename Element2,
           typename Index >
diff --git a/src/TNL/Containers/Array.h b/src/TNL/Containers/Array.h
index 867bca6a2b6c66d9bd50eb823dd9280a8c362cca..fd6a1ac4e53ce92fda6552332539601245a2c093 100644
--- a/src/TNL/Containers/Array.h
+++ b/src/TNL/Containers/Array.h
@@ -10,9 +10,11 @@
 
 #pragma once
 
+#include <list>
+#include <vector>
+
 #include <TNL/Object.h>
-#include <TNL/File.h>
-#include <TNL/Devices/Host.h>
+#include <TNL/Containers/ArrayView.h>
 
 namespace TNL {
 /**
@@ -23,14 +25,37 @@ namespace Containers {
 template< int, typename > class StaticArray;
 
 /**
- * \brief Array handles memory allocation and sharing of the same data between more Arrays.
+ * \brief Array is responsible for memory management, basic elements
+ * manipulation and I/O operations.
+ *
+ * \tparam Value is type of array elements.
+ * \tparam Device is device where the array is going to be allocated - some of \ref Devices::Host and \ref Devices::Cuda.
+ * \tparam Index is indexing type.
  *
- * \tparam Value Type of array values.
- * \tparam Device Device type.
- * \tparam Index Type of index.
+ * In the \e Device type, the Array remembers where the memory is allocated.
+ * This ensures the compile-time checks of correct pointers manipulation.
+ * Methods defined as \ref __cuda_callable__ can be called even from kernels
+ * running on device. Array elements can be changed either using the \ref operator[]
+ * which is more efficient but it can be called from CPU only for arrays
+ * allocated on host (CPU) and when the array is allocated on GPU, the operator[]
+ * can be called only from kernels running on the device (GPU). On the other
+ * hand, methods \ref setElement and \ref getElement, can be called only from the
+ * host (CPU) does not matter if the array is allocated on the host or the device.
+ * In the latter case, explicit data transfer between host and device (via PCI
+ * express or NVlink in more lucky systems) is invoked and so it can be very
+ * slow. In not time critical parts of code, this is not an issue, however.
+ * Another way to change data stored in the array is \ref evaluate which evaluates
+ * given lambda function. This is performed at the same place where the array is
+ * allocated i.e. it is efficient even on GPU. For simple checking of the array
+ * contents, one may use methods \ref containValue and \ref containsValue and
+ * \ref containsOnlyValue.
+ * Array also offers data sharing using methods \ref bind. This is, however, obsolete
+ * and will be soon replaced with proxy object \ref ArrayView.
  *
  * \par Example
  * \include ArrayExample.cpp
+ *
+ * See also \ref Containers::ArravView, \ref Containers::Vector, \ref Containers::VectorView.
  */
 template< typename Value,
           typename Device = Devices::Host,
@@ -39,27 +64,36 @@ class Array : public Object
 {
    public:
 
-      typedef Value ValueType;
-      typedef Device DeviceType;
-      typedef Index IndexType;
-      typedef Containers::Array< Value, Devices::Host, Index > HostType;
-      typedef Containers::Array< Value, Devices::Cuda, Index > CudaType;
+      using ValueType = Value;
+      using DeviceType = Device;
+      using IndexType = Index;
+      using HostType = Containers::Array< Value, Devices::Host, Index >;
+      using CudaType = Containers::Array< Value, Devices::Cuda, Index >;
+      using ViewType = ArrayView< Value, Device, Index >;
+      using ConstViewType = ArrayView< typename std::add_const< Value >::type, Device, Index >;
 
-      /** \brief Basic constructor.
+      /**
+       * \brief Basic constructor.
        *
-       * Constructs an empty array with the size of zero.
+       * Constructs an empty array with zero size.
        */
       Array();
 
       /**
-       * \brief Constructor with size.
+       * \brief Constructor with array size.
        *
-       * \param size Number of array elements. / Size of allocated memory.
+       * \param size is number of array elements.
        */
       Array( const IndexType& size );
 
       /**
-       * \brief Constructor with data and size.
+       * \brief Constructor with data pointer and size.
+       *
+       * In this case, the Array just encapsulates the pointer \e data. No
+       * deallocation is done in destructor.
+       *
+       * This behavior of the Array is obsolete and \ref ArrayView should be used
+       * instead.
        *
        * \param data Pointer to data.
        * \param size Number of array elements.
@@ -70,47 +104,110 @@ class Array : public Object
       /**
        * \brief Copy constructor.
        *
+       * \param array is an array to be copied.
+       */
+      explicit Array( const Array& array );
+
+      /**
+       * \brief Bind constructor .
+       *
        * The constructor does not make a deep copy, but binds to the supplied array.
-       * \param array Existing array that is to be bound.
-       * \param begin The first index which should be bound.
-       * \param size Number of array elements that should be bound.
+       * This is also obsolete, \ref ArraView should be used instead.
+       *
+       * \param array is an array that is to be bound.
+       * \param begin is the first index which should be bound.
+       * \param size is number of array elements that should be bound.
        */
       Array( Array& array,
              const IndexType& begin = 0,
              const IndexType& size = 0 );
 
-      /** \brief Returns type of array Value, Device type and the type of Index. */
+      /**
+       * \brief Move constructor.
+       *
+       * @param array is an array to be moved
+       */
+      Array( Array&& array );
+
+      /**
+       * \brief Initialize the array from initializer list, i.e. { ... }
+       *
+       * @param list Initializer list.
+       */
+      template< typename InValue >
+      Array( const std::initializer_list< InValue >& list );
+
+      /**
+       * \brief Initialize the array from std::list.
+       *
+       * @param list Input STL list.
+       */
+      template< typename InValue >
+      Array( const std::list< InValue >& list );
+
+      /**
+       * \brief Initialize the array from std::vector.
+       *
+       * @param vector Input STL vector.
+       */
+      template< typename InValue >
+      Array( const std::vector< InValue >& vector );
+
+      /**
+       * \brief Returns array type in C++ style.
+       *
+       * \return String with array type.
+       */
       static String getType();
 
-      /** \brief Returns type of array Value, Device type and the type of Index. */
+      /**
+       * \brief Returns array type in C++ style.
+       *
+       * \return String with array type.
+       */
       virtual String getTypeVirtual() const;
 
-      /** \brief Returns (host) type of array Value, Device type and the type of Index. */
+      /**
+       *  \brief Returns array type in C++ style where device is always \ref Devices::Host.
+       *
+       * \return String with serialization array type.
+       */
       static String getSerializationType();
 
-      /** \brief Returns (host) type of array Value, Device type and the type of Index. */
+      /**
+       *  \brief Returns array type in C++ style where device is always \ref Devices::Host.
+       *
+       * \return String with serialization array type.
+       */
       virtual String getSerializationTypeVirtual() const;
 
       /**
-       * \brief Method for setting the size of an array.
+       * \brief Method for setting the array size.
        *
        * If the array shares data with other arrays these data are released.
        * If the current data are not shared and the current size is the same
        * as the new one, nothing happens.
        *
-       * \param size Number of array elements.
+       * \param size is number of array elements.
        */
       void setSize( Index size );
 
-      /** \brief Method for getting the size of an array. */
+      /**
+       * \brief Method for getting the size of an array.
+       *
+       * This method can be called from device kernels.
+       *
+       * \return Array size.
+       */
       __cuda_callable__ Index getSize() const;
 
       /**
        * \brief Assigns features of the existing \e array to the given array.
        *
        * Sets the same size as the size of existing \e array.
-       * \tparam ArrayT Type of array.
-       * \param array Reference to an existing array.
+       *
+       * \tparam ArrayT is any array type having method \ref getSize().
+       * \param array is reference to the source array.
        */
       template< typename ArrayT >
       void setLike( const ArrayT& array );
@@ -120,8 +217,11 @@ class Array : public Object
        *
        * Releases old data and binds this array with new \e _data. Also sets new
        * \e _size of this array.
-       * @param _data Pointer to new data.
-       * @param _size Size of new _data. Number of elements.
+       *
+       * This method is obsolete, use \ref ArrayView instead.
+       *
+       * \param _data Pointer to new data.
+       * \param _size Size of new _data. Number of elements.
        */
       void bind( Value* _data,
                  const Index _size );
@@ -131,6 +231,9 @@ class Array : public Object
        *
        * Releases old data and binds this array with new \e array starting at
        * position \e begin. Also sets new \e size of this array.
+       *
+       * This method is obsolete, use \ref ArrayView instead.
+       *
        * \tparam ArrayT Type of array.
        * \param array Reference to a new array.
        * \param begin Starting index position.
@@ -146,6 +249,9 @@ class Array : public Object
        *
        * Releases old data and binds this array with a static array of size \e
        * Size.
+       *
+       * This method is obsolete, use \ref ArrayView instead.
+       *
        * \tparam Size Size of array.
        * \param array Reference to a static array.
        */
@@ -153,135 +259,278 @@ class Array : public Object
       void bind( StaticArray< Size, Value >& array );
 
       /**
-       * \brief Swaps all features of given array with existing \e array.
+       * \brief Returns a modifiable view of the array.
+       */
+      ViewType getView();
+
+      /**
+       * \brief Returns a non-modifiable view of the array.
+       */
+      ConstViewType getConstView() const;
+
+      /**
+       * \brief Conversion operator to a modifiable view of the array.
+       */
+      operator ViewType();
+
+      /**
+       * \brief Conversion operator to a non-modifiable view of the array.
+       */
+      operator ConstViewType() const;
+
+      /**
+       * \brief Swaps this array with another.
        *
-       * Swaps sizes, all values (data), allocated memory and references of given
-       * array with existing array.
-       * \param array Existing array, which features are swaped with given array.
+       * The swap is done in a shallow way, i.e. swapping only pointers and sizes.
+       *
+       * \param array is the array to be swapped with this array.
        */
       void swap( Array& array );
 
       /**
-       * \brief Resets the given array.
+       * \brief Resets the array.
        *
-       * Releases all data from array.
+       * Releases the array to empty state.
        */
       void reset();
 
       /**
-       * \brief Method for getting the data from given array with constant poiner.
+       * \brief Data pointer getter for constant instances.
+       *
+       * This method can be called from device kernels.
+       *
+       * \return Pointer to array data.
        */
       __cuda_callable__ const Value* getData() const;
 
       /**
-       * \brief Method for getting the data from given array.
+       * \brief Data pointer getter.
+       *
+       * This method can be called from device kernels.
+       *
+       * \return Pointer to array data.
        */
       __cuda_callable__ Value* getData();
 
       /**
-       * \brief Assignes the value \e x to the array element at position \e i.
+       * \brief Data pointer getter for constant instances.
+       *
+       * Use this method in algorithms where you want to emphasize that
+       * C-style array pointer is required.
+       *
+       * This method can be called from device kernels.
+       *
+       * \return Pointer to array data.
+       */
+      __cuda_callable__ const Value* getArrayData() const;
+
+      /**
+       * \brief Data pointer getter.
+       *
+       * Use this method in algorithms where you want to emphasize that
+       * C-style array pointer is required.
+       *
+       * This method can be called from device kernels.
+       *
+       * \return Pointer to array data.
+       */
+      __cuda_callable__ Value* getArrayData();
+
+
+      /**
+       * \brief Array elements setter - change value of an element at position \e i.
        *
-       * \param i Index position.
-       * \param x New value of an element.
+       * This method can be called only from the host system (CPU) but even for
+       * arrays allocated on device (GPU).
+       *
+       * \param i is element index.
+       * \param v is the new value of the element.
        */
-      void setElement( const Index& i, const Value& x );
+      void setElement( const Index& i, const Value& v );
 
       /**
-       * \brief Accesses specified element at the position \e i and returns its value.
+       * \brief Array elements getter - returns value of an element at position \e i.
+       *
+       * This method can be called only from the host system (CPU) but even for
+       * arrays allocated on device (GPU).
        *
        * \param i Index position of an element.
+       *
+       * \return Copy of i-th element.
        */
       Value getElement( const Index& i ) const;
 
       /**
-       * \brief Accesses specified element at the position \e i and returns a reference to its value.
+       * \brief Accesses specified element at the position \e i.
        *
-       * \param i Index position of an element.
+       * This method can be called from device (GPU) kernels if the array is allocated
+       * on the device. In this case, it cannot be called from host (CPU.)
+       *
+       * \param i is position of the element.
+       *
+       * \return Reference to i-th element.
        */
-      __cuda_callable__ inline Value& operator[] ( const Index& i );
+      __cuda_callable__ inline Value& operator[]( const Index& i );
 
       /**
-       * \brief Accesses specified element at the position \e i and returns a (constant?) reference to its value.
+       * \brief Accesses specified element at the position \e i.
        *
-       * \param i Index position of an element.
+       * This method can be called from device (GPU) kernels if the array is allocated
+       * on the device. In this case, it cannot be called from host (CPU.)
+       *
+       * \param i is position of the element.
+       *
+       * \return Constant reference to i-th pointer.
        */
-      __cuda_callable__ inline const Value& operator[] ( const Index& i ) const;
+      __cuda_callable__ inline const Value& operator[]( const Index& i ) const;
 
       /**
        * \brief Assigns \e array to this array, replacing its current contents.
        *
-       * \param array Reference to an array.
+       * \param array is reference to the array.
+       *
+       * \return Reference to this array.
        */
-      Array& operator = ( const Array& array );
+      Array& operator=( const Array& array );
 
       /**
-       * \brief Assigns \e array to this array, replacing its current contents.
+       * \brief Move contents of \e array to this array.
        *
-       * \tparam ArrayT Type of array.
-       * \param array Reference to an array.
+       * \param array is reference to the array.
+       *
+       * \return Reference to this array.
        */
-      template< typename ArrayT >
-      Array& operator = ( const ArrayT& array );
+      Array& operator=( Array&& array );
 
       /**
-       * \brief This function checks whether this array is equal to \e array.
+       * \brief Assigns either array-like container or single value.
        *
-       * \tparam ArrayT Type of array.
-       * \param array Reference to an array.
+       * If \e T is array type i.e. \ref Array, \ref ArrayView, \ref StaticArray,
+       * \ref Vector, \ref VectorView, \ref StaticVector, \ref DistributedArray,
+       * \ref DistributedArrayView, \ref DistributedVector or
+       * \ref DistributedVectorView, its elements are copied into this array. If
+       * it is other type convertibly to Array::ValueType, all array elements are
+       * set to the value \e data.
+       *
+       * \tparam T is type of array or value type.
+       *
+       * \param data is a reference to array or value.
+       *
+       * \return Reference to this array.
+       */
+      template< typename T >
+      Array& operator=( const T& data );
+
+      /**
+       * \brief Assigns STL list to this array.
+       *
+       * \param list is STL list
+       *
+       * \return Reference to this array.
+       */
+      template< typename InValue >
+      Array& operator=( const std::list< InValue >& list );
+
+      /**
+       * \brief Assigns STL vector to this array.
+       *
+       * \param vector is STL vector
+       *
+       * \return Reference to this array.
+       */
+      template< typename InValue >
+      Array& operator=( const std::vector< InValue >& vector );
+
+      /**
+       * \brief Comparison operator with another array-like container.
+       *
+       * \tparam ArrayT is type of an array-like container, i.e Array, ArrayView, Vector, VectorView, DistributedArray, DistributedVector etc.
+       * \param array is reference to an array.
+       *
+       * \return True if both arrays are equal element-wise and false otherwise.
        */
       template< typename ArrayT >
-      bool operator == ( const ArrayT& array ) const;
+      bool operator==( const ArrayT& array ) const;
 
       /**
        * \brief This function checks whether this array is not equal to \e array.
        *
        * \tparam ArrayT Type of array.
        * \param array Reference to an array.
+       *
+       * \return True if both arrays are not equal element-wise and false otherwise.
        */
       template< typename ArrayT >
-      bool operator != ( const ArrayT& array ) const;
+      bool operator!=( const ArrayT& array ) const;
 
       /**
-       * \brief Sets the array values.
+       * \brief Sets the array elements to given value.
        *
        * Sets all the array values to \e v.
        *
        * \param v Reference to a value.
        */
-      void setValue( const Value& v );
+      void setValue( const Value& v,
+                     const Index begin = 0,
+                     Index end = -1 );
 
       /**
-       * \brief Checks if there is an element with value \e v in this array.
+       * \brief Checks if there is an element with value \e v.
        *
-       * \param v Reference to a value.
+       * By default, the method checks all array elements. By setting indexes
+       * \e begin and \e end, only elements in given interval are checked.
+       *
+       * \param v is reference to the value.
+       * \param begin is the first element to be checked
+       * \param end is the last element to be checked. If \e end equals -1, its
+       * value is replaces by the array size.
+       *
+       * \return True if there is **at least one** array element in interval [\e begin, \e end ) having value \e v.
        */
-      bool containsValue( const Value& v ) const;
+      bool containsValue( const Value& v,
+                          const Index begin = 0,
+                          Index end = -1 ) const;
 
       /**
-       * \brief Checks if all elements in this array have the same value \e v.
+       * \brief Checks if all elements have the same value \e v.
+       *
+       * By default, the method checks all array elements. By setting indexes
+       * \e begin and \e end, only elements in given interval are checked.
        *
        * \param v Reference to a value.
+       * \param begin is the first element to be checked
+       * \param end is the last element to be checked. If \e end equals -1, its
+       * value is replaces by the array size.
+       *
+       * \return True if there **all** array elements in interval [\e begin, \e end ) have value \e v.
        */
-      bool containsOnlyValue( const Value& v ) const;
+      bool containsOnlyValue( const Value& v,
+                              const Index begin = 0,
+                              Index end = -1 ) const;
 
       /**
        * \brief Returns true if non-zero size is set.
+       *
+       * This method can be called from device kernels.
+       *
+       * \return Returns \e true if array view size is zero, \e false otherwise.
        */
-      operator bool() const;
+      __cuda_callable__
+      bool empty() const;
 
       /**
        * \brief Method for saving the object to a \e file as a binary data.
        *
        * \param file Reference to a file.
        */
-      bool save( File& file ) const;
+      void save( File& file ) const;
 
       /**
        * Method for loading the object from a file as a binary data.
        *
        * \param file Reference to a file.
        */
-      bool load( File& file );
+      void load( File& file );
 
       /**
        * \brief This method loads data without reallocation.
@@ -290,8 +539,10 @@ class Array : public Object
        * If the array was not initialize yet, common load is
        * performed. Otherwise, the array size must fit with
        * the size of array being loaded.
+       *
+       * This method is deprecated - use ArrayView instead.
        */
-      bool boundLoad( File& file );
+      void boundLoad( File& file );
 
       using Object::save;
 
@@ -308,10 +559,10 @@ class Array : public Object
       void releaseData() const;
 
       /** \brief Number of elements in array. */
-      mutable Index size;
+      mutable Index size = 0;
 
       /** \brief Pointer to data. */
-      mutable Value* data;
+      mutable Value* data = nullptr;
 
       /**
        * \brief Pointer to the originally allocated data.
@@ -322,7 +573,7 @@ class Array : public Object
        * by TNL) are bind then this pointer is zero since no deallocation is
        * necessary.
        */
-      mutable Value* allocationPointer;
+      mutable Value* allocationPointer = nullptr;
 
       /**
        * \brief Counter of objects sharing this array or some parts of it.
@@ -330,13 +581,13 @@ class Array : public Object
        * The reference counter is allocated after first sharing of the data between
        * more arrays. This is to avoid unnecessary dynamic memory allocation.
        */
-      mutable int* referenceCounter;
+      mutable int* referenceCounter = nullptr;
 };
 
 template< typename Value, typename Device, typename Index >
-std::ostream& operator << ( std::ostream& str, const Array< Value, Device, Index >& v );
+std::ostream& operator<<( std::ostream& str, const Array< Value, Device, Index >& v );
 
 } // namespace Containers
 } // namespace TNL
 
-#include <TNL/Containers/Array_impl.h>
+#include <TNL/Containers/Array.hpp>
diff --git a/src/TNL/Containers/Array_impl.h b/src/TNL/Containers/Array.hpp
similarity index 63%
rename from src/TNL/Containers/Array_impl.h
rename to src/TNL/Containers/Array.hpp
index b44bdf0a147fd46af42d3f70e7669cb78d8dec60..61c4db1da44d67ae6380eadcd9dedf8e11e6eee5 100644
--- a/src/TNL/Containers/Array_impl.h
+++ b/src/TNL/Containers/Array.hpp
@@ -11,13 +11,16 @@
 #pragma once
 
 #include <iostream>
+
 #include <TNL/Assert.h>
-#include <TNL/File.h>
 #include <TNL/Math.h>
 #include <TNL/param-types.h>
 #include <TNL/Containers/Algorithms/ArrayOperations.h>
 #include <TNL/Containers/Algorithms/ArrayIO.h>
-#include <TNL/Containers/Array.h>
+#include <TNL/Containers/Algorithms/ArrayAssignment.h>
+#include <TNL/Exceptions/ArrayWrongSize.h>
+
+#include "Array.h"
 
 namespace TNL {
 namespace Containers {
@@ -60,6 +63,20 @@ Array( Value* data,
 {
 }
 
+template< typename Value,
+          typename Device,
+          typename Index >
+Array< Value, Device, Index >::
+Array( const Array< Value, Device, Index >& array )
+: size( 0 ),
+  data( nullptr ),
+  allocationPointer( nullptr ),
+  referenceCounter( 0 )
+{
+   this->setSize( array.getSize() );
+   Algorithms::ArrayOperations< Device >::copyMemory( this->getData(), array.getData(), array.getSize() );
+}
+
 template< typename Value,
           typename Device,
           typename Index >
@@ -92,6 +109,72 @@ Array( Array< Value, Device, Index >& array,
    }
 }
 
+template< typename Value,
+          typename Device,
+          typename Index >
+Array< Value, Device, Index >::
+Array( Array< Value, Device, Index >&& array )
+{
+   this->size = array.size;
+   this->data = array.data;
+   this->allocationPointer = array.allocationPointer;
+   this->referenceCounter = array.referenceCounter;
+
+   array.size = 0;
+   array.data = nullptr;
+   array.allocationPointer = nullptr;
+   array.referenceCounter = nullptr;
+}
+
+template< typename Value,
+          typename Device,
+          typename Index >
+   template< typename InValue >
+Array< Value, Device, Index >::
+Array( const std::initializer_list< InValue >& list )
+: size( 0 ),
+  data( 0 ),
+  allocationPointer( 0 ),
+  referenceCounter( 0 )
+{
+   this->setSize( list.size() );
+   ////
+   // Here we assume that the underlying array for initializer_list is const T[N]
+   // as noted here:
+   // https://en.cppreference.com/w/cpp/utility/initializer_list
+   Algorithms::ArrayOperations< Device, Devices::Host >::copyMemory( this->getData(), &( *list.begin() ), list.size() );
+}
+
+template< typename Value,
+          typename Device,
+          typename Index >
+   template< typename InValue >
+Array< Value, Device, Index >::
+Array( const std::list< InValue >& list )
+: size( 0 ),
+  data( 0 ),
+  allocationPointer( 0 ),
+  referenceCounter( 0 )
+{
+   this->setSize( list.size() );
+   Algorithms::ArrayOperations< Device >::copySTLList( this->getData(), list );
+}
+
+template< typename Value,
+          typename Device,
+          typename Index >
+   template< typename InValue >
+Array< Value, Device, Index >::
+Array( const std::vector< InValue >& vector )
+: size( 0 ),
+  data( 0 ),
+  allocationPointer( 0 ),
+  referenceCounter( 0 )
+{
+   this->setSize( vector.size() );
+   Algorithms::ArrayOperations< Device, Devices::Host >::copyMemory( this->getData(), vector.data(), vector.size() );
+}
+
 template< typename Value,
           typename Device,
           typename Index >
@@ -192,7 +275,7 @@ Index
 Array< Value, Device, Index >::
 getSize() const
 {
-   return this -> size;
+   return this->size;
 }
 
 template< typename Value,
@@ -273,6 +356,43 @@ bind( StaticArray< Size, Value >& array )
    this->data = array.getData();
 }
 
+template< typename Value,
+          typename Device,
+          typename Index >
+typename Array< Value, Device, Index >::ViewType
+Array< Value, Device, Index >::
+getView()
+{
+   return ViewType( getData(), getSize() );
+}
+
+template< typename Value,
+          typename Device,
+          typename Index >
+typename Array< Value, Device, Index >::ConstViewType
+Array< Value, Device, Index >::
+getConstView() const
+{
+   return ConstViewType( getData(), getSize() );
+}
+
+template< typename Value,
+          typename Device,
+          typename Index >
+Array< Value, Device, Index >::
+operator ViewType()
+{
+   return getView();
+}
+
+template< typename Value,
+          typename Device,
+          typename Index >
+Array< Value, Device, Index >::
+operator ConstViewType() const
+{
+   return getConstView();
+}
 
 template< typename Value,
           typename Device,
@@ -315,6 +435,24 @@ Value* Array< Value, Device, Index >::getData()
    return this->data;
 }
 
+template< typename Value,
+          typename Device,
+          typename Index >
+__cuda_callable__
+const Value* Array< Value, Device, Index >::getArrayData() const
+{
+   return this->data;
+}
+
+template< typename Value,
+          typename Device,
+          typename Index >
+__cuda_callable__
+Value* Array< Value, Device, Index >::getArrayData()
+{
+   return this->data;
+}
+
 template< typename Value,
           typename Device,
           typename Index >
@@ -345,7 +483,7 @@ template< typename Value,
 __cuda_callable__
 inline Value&
 Array< Value, Device, Index >::
-operator[] ( const Index& i )
+operator[]( const Index& i )
 {
    TNL_ASSERT_GE( i, (Index) 0, "Element index must be non-negative." );
    TNL_ASSERT_LT( i, this->getSize(), "Element index is out of bounds." );
@@ -358,7 +496,7 @@ template< typename Value,
 __cuda_callable__
 inline const Value&
 Array< Value, Device, Index >::
-operator[] ( const Index& i ) const
+operator[]( const Index& i ) const
 {
    TNL_ASSERT_GE( i, (Index) 0, "Element index must be non-negative." );
    TNL_ASSERT_LT( i, this->getSize(), "Element index is out of bounds." );
@@ -370,7 +508,7 @@ template< typename Value,
           typename Index >
 Array< Value, Device, Index >&
 Array< Value, Device, Index >::
-operator = ( const Array< Value, Device, Index >& array )
+operator=( const Array< Value, Device, Index >& array )
 {
    //TNL_ASSERT_EQ( array.getSize(), this->getSize(), "Array sizes must be the same." );
    if( this->getSize() != array.getSize() )
@@ -380,26 +518,66 @@ operator = ( const Array< Value, Device, Index >& array )
          copyMemory( this->getData(),
                      array.getData(),
                      array.getSize() );
-   return ( *this );
+   return *this;
 }
 
 template< typename Value,
           typename Device,
           typename Index >
-   template< typename ArrayT >
 Array< Value, Device, Index >&
 Array< Value, Device, Index >::
-operator = ( const ArrayT& array )
+operator=( Array< Value, Device, Index >&& array )
 {
-   //TNL_ASSERT_EQ( array.getSize(), this->getSize(), "Array sizes must be the same." );
-   if( this->getSize() != array.getSize() )
-      this->setLike( array );
-   if( this->getSize() > 0 )
-      Algorithms::ArrayOperations< Device, typename ArrayT::DeviceType >::
-         copyMemory( this->getData(),
-                     array.getData(),
-                     array.getSize() );
-   return ( *this );
+   this->size = array.size;
+   this->data = array.data;
+   this->allocationPointer = array.allocationPointer;
+   this->referenceCounter = array.referenceCounter;
+
+   array.size = 0;
+   array.data = nullptr;
+   array.allocationPointer = nullptr;
+   array.referenceCounter = nullptr;
+   return *this;
+}
+
+
+template< typename Value,
+          typename Device,
+          typename Index >
+   template< typename T >
+Array< Value, Device, Index >&
+Array< Value, Device, Index >::
+operator=( const T& data )
+{
+   Algorithms::ArrayAssignment< Array, T >::assign( *this, data );
+   return *this;
+}
+
+template< typename Value,
+          typename Device,
+          typename Index >
+   template< typename InValue >
+Array< Value, Device, Index >&
+Array< Value, Device, Index >::
+operator=( const std::list< InValue >& list )
+{
+   this->setSize( list.size() );
+   Algorithms::ArrayOperations< Device >::copySTLList( this->getData(), list );
+   return *this;
+}
+
+template< typename Value,
+          typename Device,
+          typename Index >
+   template< typename InValue >
+Array< Value, Device, Index >&
+Array< Value, Device, Index >::
+operator=( const std::vector< InValue >& vector )
+{
+   if( this->getSize() != vector.size() )
+      this->setSize( vector.size() );
+   Algorithms::ArrayOperations< Device, Devices::Host >::copyMemory( this->getData(), vector.data(), vector.size() );
+   return *this;
 }
 
 template< typename Value,
@@ -408,7 +586,7 @@ template< typename Value,
    template< typename ArrayT >
 bool
 Array< Value, Device, Index >::
-operator == ( const ArrayT& array ) const
+operator==( const ArrayT& array ) const
 {
    if( array.getSize() != this->getSize() )
       return false;
@@ -424,18 +602,24 @@ template< typename Value,
           typename Device,
           typename Index >
    template< typename ArrayT >
-bool Array< Value, Device, Index >::operator != ( const ArrayT& array ) const
+bool
+Array< Value, Device, Index >::
+operator!=( const ArrayT& array ) const
 {
-   return ! ( ( *this ) == array );
+   return ! ( *this == array );
 }
 
 template< typename Value,
           typename Device,
           typename Index >
-void Array< Value, Device, Index >::setValue( const Value& e )
+void Array< Value, Device, Index >::setValue( const ValueType& e,
+                                              const Index begin,
+                                              Index end )
 {
    TNL_ASSERT_TRUE( this->getData(), "Attempted to set a value of an empty array." );
-   Algorithms::ArrayOperations< Device >::setMemory( this->getData(), e, this->getSize() );
+   if( end == -1 )
+      end = this->getSize();
+   Algorithms::ArrayOperations< Device >::setMemory( &this->getData()[ begin ], e, end - begin );
 }
 
 template< typename Value,
@@ -443,9 +627,15 @@ template< typename Value,
           typename Index >
 bool
 Array< Value, Device, Index >::
-containsValue( const Value& v ) const
+containsValue( const Value& v,
+               const Index begin,
+               Index end ) const
 {
-   return Algorithms::ArrayOperations< Device >::containsValue( this->data, this->size, v );
+   TNL_ASSERT_TRUE( this->getData(), "Attempted to check a value of an empty array." );
+   if( end == -1 )
+      end = this->getSize();
+
+   return Algorithms::ArrayOperations< Device >::containsValue( &this->getData()[ begin ], end - begin, v );
 }
 
 template< typename Value,
@@ -453,111 +643,78 @@ template< typename Value,
           typename Index >
 bool
 Array< Value, Device, Index >::
-containsOnlyValue( const Value& v ) const
+containsOnlyValue( const Value& v,
+                   const Index begin,
+                   Index end ) const
 {
-   return Algorithms::ArrayOperations< Device >::containsOnlyValue( this->data, this->size, v );
+   TNL_ASSERT_TRUE( this->getData(), "Attempted to check a value of an empty array." );
+   if( end == -1 )
+      end = this->getSize();
+
+   return Algorithms::ArrayOperations< Device >::containsOnlyValue( &this->getData()[ begin ], end - begin, v );
 }
 
 template< typename Value,
           typename Device,
           typename Index >
-Array< Value, Device, Index >::operator bool() const
+bool
+__cuda_callable__
+Array< Value, Device, Index >::
+empty() const
 {
-   return data != 0;
+   return ( data == nullptr );
 }
 
-
 template< typename Value,
           typename Device,
           typename Index >
-bool Array< Value, Device, Index >::save( File& file ) const
+void Array< Value, Device, Index >::save( File& file ) const
 {
-   if( ! Object::save( file ) )
-      return false;
-   if( ! file.write( &this->size ) )
-      return false;
-   if( this->size != 0 && ! Algorithms::ArrayIO< Value, Device, Index >::save( file, this->data, this->size ) )
-   {
-      std::cerr << "I was not able to save " << this->getType()
-           << " with size " << this -> getSize() << std::endl;
-      return false;
-   }
-   return true;
+   Object::save( file );
+   file.save( &this->size );
+   if( this->size != 0 )
+      Algorithms::ArrayIO< Value, Device, Index >::save( file, this->data, this->size );
 }
 
 template< typename Value,
           typename Device,
           typename Index >
-bool
+void
 Array< Value, Device, Index >::
 load( File& file )
 {
-   if( ! Object::load( file ) )
-      return false;
+   Object::load( file );
    Index _size;
-   if( ! file.read( &_size ) )
-   {
-      std::cerr << "Unable to read the array size." << std::endl;
-      return false;
-   }
+   file.load( &_size );
    if( _size < 0 )
-   {
-      std::cerr << "Error: The size " << _size << " of the file is not a positive number or zero." << std::endl;
-      return false;
-   }
+      throw Exceptions::ArrayWrongSize( _size, "positive" );
    setSize( _size );
    if( _size )
-   {
-      if( ! Algorithms::ArrayIO< Value, Device, Index >::load( file, this->data, this->size ) )
-      {
-         std::cerr << "I was not able to load " << this->getType()
-                    << " with size " << this -> getSize() << std::endl;
-         return false;
-      }
-   }
-   return true;
+      Algorithms::ArrayIO< Value, Device, Index >::load( file, this->data, this->size );
 }
 
 template< typename Value,
           typename Device,
           typename Index >
-bool
+void
 Array< Value, Device, Index >::
 boundLoad( File& file )
 {
-   if( ! Object::load( file ) )
-      return false;
+   Object::load( file );
    Index _size;
-   if( ! file.read( &_size ) )
-      return false;
+   file.load( &_size );
    if( _size < 0 )
-   {
-      std::cerr << "Error: The size " << _size << " of the file is not a positive number or zero." << std::endl;
-      return false;
-   }
+      throw Exceptions::ArrayWrongSize( _size, "Positive is expected," );
    if( this->getSize() != 0 )
    {
       if( this->getSize() != _size )
-      {
-         std::cerr << "Error: The current array size is not zero (" << this->getSize() << ") and it is different from the size of "
-                   << "the array being loaded (" << _size << "). This is not possible. Call method reset() before." << std::endl;
-         return false;
-      }
+         throw Exceptions::ArrayWrongSize( _size, convertToString( this->getSize() ) + " is expected." );
    }
    else setSize( _size );
    if( _size )
-   {
-      if( ! Algorithms::ArrayIO< Value, Device, Index >::load( file, this->data, this->size ) )
-      {
-         std::cerr << "I was not able to load " << this->getType()
-                   << " with size " << this -> getSize() << std::endl;
-         return false;
-      }
-   }
-   return true;
+      Algorithms::ArrayIO< Value, Device, Index >::load( file, this->data, this->size );
 }
 
-
 template< typename Value,
           typename Device,
           typename Index >
@@ -568,7 +725,7 @@ Array< Value, Device, Index >::
 }
 
 template< typename Value, typename Device, typename Index >
-std::ostream& operator << ( std::ostream& str, const Array< Value, Device, Index >& v )
+std::ostream& operator<<( std::ostream& str, const Array< Value, Device, Index >& v )
 {
    str << "[ ";
    if( v.getSize() > 0 )
diff --git a/src/TNL/Containers/ArrayView.h b/src/TNL/Containers/ArrayView.h
index 7e98a0d3db82209e70e810f6773f56e12094f18a..91de01dac18b7dd1a0178c0ae19b4cb449ec822a 100644
--- a/src/TNL/Containers/ArrayView.h
+++ b/src/TNL/Containers/ArrayView.h
@@ -12,6 +12,9 @@
 
 #pragma once
 
+#include <type_traits>  // std::add_const
+
+#include <TNL/File.h>
 #include <TNL/Devices/Host.h>
 #include <TNL/Devices/Cuda.h>
 
@@ -21,126 +24,424 @@ namespace Containers {
 template< typename Value, typename Device, typename Index >
 class Array;
 
-template< int Size, typename Value >
-class StaticArray;
-
+/**
+ * \brief ArrayView serves for managing array of data allocated by TNL::Array or
+ * another way. It makes no data deallocation at the end of its life cycle. Compared
+ * to TNL Array, it is lighter data structure and therefore it is more efficient
+ * especially when it is being passed on GPU. The ArrayView can also be created
+ * in CUDA kernels which is not the case of Array.
+ *
+ * \tparam Value is type of array elements.
+ * \tparam Device is device where the array is going to be allocated - some of \ref Devices::Host and \ref Devices::Cuda.
+ * \tparam Index is indexing type.
+ *
+ * In the \e Device type, the Array remembers where the memory is allocated.
+ * This ensures the compile-time checks of correct pointers manipulation.
+ * Methods defined as \ref __cuda_callable__ can be called even from kernels
+ * running on device. Array elements can be changed either using the \ref operator[].
+ * This can be called from CPU only for arrays allocated on host (CPU). If the
+ * array is allocated on GPU, the operator[] can be called only from kernels
+ * running on the device (GPU). On the other hand, methods \ref setElement and
+ * \ref getElement, can be called only from the host (CPU) does not matter if
+ * the array resides on the host or the device. In the latter case, explicit data
+ * transfer between host and device (via PCI express or NVlink in more lucky
+ * systems) is invoked and so it can be very slow. In not time critical parts
+ * of code, this is not an issue, however. Another way to change data being
+ * accessed by the ArrayView is \ref evaluate which evaluates given lambda
+ * function. This is performed at the same place where the array is
+ * allocated i.e. it is efficient even on GPU. For simple checking of the array
+ * contents, one may use methods \ref containValue and \ref containsValue and
+ * \ref containsOnlyValue.
+ *
+ * \par Example
+ * \include ArrayViewExample.cpp
+ *
+ * See also \ref Containers::Arrav, \ref Containers::Vector, \ref Containers::VectorView,
+ * Containers::StaticArray, Containers::StaticVector.
+ */
 template< typename Value,
           typename Device = Devices::Host,
           typename Index = int >
 class ArrayView
 {
+   using SerializationType = Array< Value, Devices::Host, Index >;
 public:
    using ValueType = Value;
    using DeviceType = Device;
    using IndexType = Index;
    using HostType = ArrayView< Value, Devices::Host, Index >;
    using CudaType = ArrayView< Value, Devices::Cuda, Index >;
+   using ViewType = ArrayView< Value, Device, Index >;
+   using ConstViewType = ArrayView< typename std::add_const< Value >::type, Device, Index >;
+
+   /**
+    * \brief Returns type of array view in C++ style.
+    *
+    * \return String with array view type.
+    */
+   static String getType();
 
+   /**
+    * \brief Basic constructor for empty ArrayView.
+    *
+    * This method can be called from device kernels.
+    */
    __cuda_callable__
    ArrayView() = default;
 
-   // explicit initialization by raw data pointer and size
+   /**
+    * \brief Constructor with explicit initialization by raw data pointer and size.
+    *
+    * This method can be called from device kernels.
+    *
+    * \param data is data pointer
+    * \param size is number of elements to be managed by the array view
+    */
    __cuda_callable__
    ArrayView( Value* data, Index size );
 
-   // Copy-constructor does shallow copy, so views can be passed-by-value into
-   // CUDA kernels and they can be captured-by-value in __cuda_callable__
-   // lambda functions.
+   /**
+    * \brief Copy constructor.
+    * Copy-constructor does shallow copy, so views can be passed-by-value into
+    * CUDA kernels and they can be captured-by-value in __cuda_callable__
+    * lambda functions.
+    *
+    * This method can be called from device kernels.
+    *
+    * \param view is ArrayView to be copied.
+    */
    __cuda_callable__
-   ArrayView( const ArrayView& ) = default;
-
-   // "Templated copy-constructor" accepting any cv-qualification of Value
+   ArrayView( const ArrayView& view ) = default;
+
+   /**
+    * \brief "Templated copy-constructor".
+    *
+    * It makes shallow copy only.
+    *
+    * This method can be called from device kernels.
+    *
+    * \tparam Value is any cv-qualified ValueType.
+    */
    template< typename Value_ >
    __cuda_callable__
    ArrayView( const ArrayView< Value_, Device, Index >& array )
    : data(array.getData()), size(array.getSize()) {}
 
-   // default move-constructor
-   __cuda_callable__
-   ArrayView( ArrayView&& ) = default;
-
-   // initialization from other array containers (using shallow copy)
-   template< typename Value_ >  // template catches both const and non-const qualified Value
-   __cuda_callable__
-   ArrayView( Array< Value_, Device, Index >& array );
-
-   template< int Size, typename Value_ >  // template catches both const and non-const qualified Value
-   __cuda_callable__
-   ArrayView( StaticArray< Size, Value_ >& array );
-
-   // these constructors will be used only when Value is const-qualified
-   // (const views are initializable by const references)
-   template< typename Value_ >  // template catches both const and non-const qualified Value
+   /**
+    * \brief Default move-constructor.
+    *
+    * This method can be called from device kernels.
+    *
+    * \param view is ArrayView to be moved to this ArrayView.
+    */
    __cuda_callable__
-   ArrayView( const Array< Value_, Device, Index >& array );
-
-   template< int Size, typename Value_ >  // template catches both const and non-const qualified Value
-   __cuda_callable__
-   ArrayView( const StaticArray< Size, Value_ >& array );
-
-
-   // methods for rebinding (reinitialization)
+   ArrayView( ArrayView&& view ) = default;
+
+   /**
+    * \brief Method for rebinding (reinitialization).
+    *
+    * This method can be called from device kernels.
+    *
+    * \param data is pointer to data to be bound to the array view.
+    * \param size is the number of elements to be managed by the array view.
+    */
    __cuda_callable__
    void bind( Value* data, const Index size );
 
-   // Note that you can also bind directly to Array and other types implicitly
-   // convertible to ArrayView.
+   /**
+    * \brief Method for rebinding (reinitialization) with another ArrayView.
+    *
+    * Note that you can also bind directly to Array and other types implicitly
+    * convertible to ArrayView.
+    *
+    * This method can be called from device kernels.
+    *
+    * \param view is array view to be bound.
+    */
    __cuda_callable__
    void bind( ArrayView view );
 
+   /**
+    * \brief Returns a modifiable view of the array view.
+    */
+   __cuda_callable__
+   ViewType getView();
 
-   // Copy-assignment does deep copy, just like regular array, but the sizes
-   // must match (i.e. copy-assignment cannot resize).
+   /**
+    * \brief Returns a non-modifiable view of the array view.
+    */
+   __cuda_callable__
+   ConstViewType getConstView() const;
+
+   /**
+    * \brief Assignment operator.
+    *
+    * Copy-assignment does deep copy, just like regular array, but the sizes
+    * must match (i.e. copy-assignment cannot resize).
+    *
+    * \param view is array view to be copied
+    */
    ArrayView& operator=( const ArrayView& view );
 
-   template< typename Array >
-   ArrayView& operator=( const Array& array );
-
-
-   static String getType();
-
-
+   /**
+    * \brief Assignment operator for array-like containers or single value.
+    *
+    * If \e T is array type i.e. \ref Array, \ref ArrayView, \ref StaticArray,
+    * \ref Vector, \ref VectorView, \ref StaticVector, \ref DistributedArray,
+    * \ref DistributedArrayView, \ref DistributedVector or
+    * \ref DistributedVectorView, its elements are copied into this array. If
+    * it is other type convertibly to ArrayView::ValueType, all array elements are
+    * set to the value \e data.
+    *
+    * \tparam T is type of array or value type.
+    *
+    * \param data is a reference to array or value.
+    *
+    * \return Reference to this array.
+    */
+   template< typename T >
+   ArrayView& operator=( const T& array );
+
+   /**
+    * \brief Swaps this array view content with another.
+    *
+    * The swap is done in a shallow way, i.e. swapping only  pointers and sizes.
+    *
+    * This method can be called from device kernels.
+    *
+    * \param view is the array view to be swapped with this array view.
+    */
    __cuda_callable__
    void swap( ArrayView& view );
 
+   /***
+    * \brief Resets the array view.
+    *
+    * The array view behaves like being empty after calling this method.
+    *
+    * This method can be called from device kernels.
+    */
    __cuda_callable__
    void reset();
 
+   /**
+    * \brief Returns constant pointer to data managed by the array view.
+    *
+    * This method can be called from device kernels.
+    *
+    * \return Pointer to array data.
+    */
    __cuda_callable__
    const Value* getData() const;
 
+   /**
+    * \brief Returns pointer to data managed by the array view.
+    *
+    * This method can be called from device kernels.
+    *
+    * \return Pointer to array data.
+    */
    __cuda_callable__
    Value* getData();
 
+   /**
+    * \brief Returns constant pointer to data managed by the array view.
+    *
+    * Use this method in algorithms where you want to emphasize that
+    * C-style array pointer is required.
+    *
+    * This method can be called from device kernels.
+    *
+    * \return Pointer to array data.
+    */
+   __cuda_callable__
+   const Value* getArrayData() const;
+
+   /**
+    * \brief Returns pointer to data managed by the array view.
+    *
+    * Use this method in algorithms where you want to emphasize that
+    * C-style array pointer is required.
+    *
+    * This method can be called from device kernels.
+    *
+    * \return Pointer to array data.
+    */
+   __cuda_callable__
+   Value* getArrayData();
+
+   /**
+    * \brief Returns the array view size, i.e. number of elements being managed by the array view.
+    *
+    * This method can be called from device kernels.
+    *
+    * \return The array view size.
+    */
    __cuda_callable__
    Index getSize() const;
 
+   /**
+    * \brief Array view elements setter - change value of an element at position \e i.
+    *
+    * This method can be called only from the host system (CPU) but even for
+    * array views managing data allocated on device (GPU).
+    *
+    * \param i is element index.
+    * \param v is the new value of the element.
+    */
    void setElement( Index i, Value value );
 
+   /**
+    * \brief Array view elements getter - returns value of an element at position \e i.
+    *
+    * This method can be called only from the host system (CPU) but even for
+    * array views managing data allocated on device (GPU).
+    *
+    * \param i Index position of an element.
+    *
+    * \return Copy of i-th element.
+    */
    Value getElement( Index i ) const;
 
+   /**
+    * \brief Accesses specified element at the position \e i.
+    *
+    * This method can be called from device (GPU) kernels if the array view
+    * manages data allocated on the device. In this case, it cannot be called
+    * from the host (CPU.)
+    *
+    * \param i is position of the element.
+    *
+    * \return Reference to i-th element.
+    */
    __cuda_callable__
    Value& operator[]( Index i );
 
+   /**
+    * \brief Returns constant reference to an element at a position \e i.
+    *
+    * This method can be called from device (GPU) kernels if the array view
+    * manages data allocated on the device. In this case, it cannot be called
+    * from the host (CPU.)
+    *
+    * \param i is position of the element.
+    *
+    * \return Reference to i-th element.
+    */
    __cuda_callable__
    const Value& operator[]( Index i ) const;
 
-   template< typename Value_, typename Device_, typename Index_ >
-   bool operator==( const ArrayView< Value_, Device_, Index_ >& view ) const;
-
-   template< typename Value_, typename Device_, typename Index_ >
-   bool operator!=( const ArrayView< Value_, Device_, Index_ >& view ) const;
-
+   /**
+    * \brief Comparison operator with another array-like container \e array.
+    *
+    * \tparam ArrayT is type of an array-like container, i.e Array, ArrayView, Vector, VectorView, DistributedArray, DistributedVector etc.
+    * \param array is reference to an array.
+    *
+    * \return True if both array views are equal element-wise and false otherwise.
+    */
+   template< typename ArrayT >
+   bool operator==( const ArrayT& array ) const;
+
+   /**
+    * \brief Comparison negation operator with another array-like container \e array.
+    *
+    * \tparam ArrayT is type of an array-like container, i.e Array, ArrayView, Vector, VectorView, DistributedArray, DistributedVector etc.
+    * \param array is reference to an array.
+    *
+    * \return True if both array views are not equal element-wise and false otherwise.
+    */
+   template< typename ArrayT >
+   bool operator!=( const ArrayT& array ) const;
+
+   /**
+    * \brief Sets the array view elements to given value.
+    *
+    * Sets all the array values to \e v.
+    *
+    * \param v Reference to a value.
+    */
    void setValue( Value value );
 
-   // Checks if there is an element with given value in this array
+   /**
+    * \brief Sets the array elements using given lambda function.
+    *
+    * Sets all the array values to \e v.
+    *
+    * \param v Reference to a value.
+    */
+   template< typename Function >
+   void evaluate( Function& f,
+                  const Index begin = 0,
+                  Index end = -1 );
+
+   /**
+    * \brief Checks if there is an element with value \e v.
+    *
+    * By default, the method checks all array view elements. By setting indexes
+    * \e begin and \e end, only elements in given interval are checked.
+    *
+    * \param v is reference to the value.
+    * \param begin is the first element to be checked
+    * \param end is the last element to be checked. If \e end equals -1, its
+    * value is replaces by the array size.
+    *
+    * \return True if there is **at least one** array element in interval [\e begin, \e end ) having value \e v.
+    */
    bool containsValue( Value value ) const;
 
-   // Checks if all elements in this array have the same given value
+   /**
+    * \brief Checks if all elements have the same value \e v.
+    *
+    * By default, the method checks all array view elements. By setting indexes
+    * \e begin and \e end, only elements in given interval are checked.
+    *
+    * \param v Reference to a value.
+    * \param begin is the first element to be checked
+    * \param end is the last element to be checked. If \e end equals -1, its
+    * value is replaces by the array size.
+    *
+    * \return True if there **all** array elements in interval [\e begin, \e end ) have value \e v.
+    */
    bool containsOnlyValue( Value value ) const;
 
-   //! Returns true if non-zero size is set.
-   operator bool() const;
+   /**
+    * \brief Returns true if non-zero size is set.
+    *
+    * This method can be called from device kernels.
+    *
+    * \return Returns \e true if array view size is zero, \e false otherwise.
+    */
+   __cuda_callable__
+   bool empty() const;
+
+   /**
+    * \brief Method for saving the object to a \e file as a binary data.
+    *
+    * \param file Reference to a file.
+    */
+   void save( File& file ) const;
+
+   /**
+    * Method for loading the object from a file as a binary data.
+    *
+    * \param file Reference to a file.
+    */
+   void load( File& file );
+
+   /**
+    * \brief Method for saving the array view to a file as a binary data.
+    *
+    * \param fileName String defining the name of a file.
+    */
+   void save( const String& fileName ) const;
+
+   /**
+    * \brief Method for restoring the array view from a file.
+    *
+    * \param fileName String defining the name of a file.
+    */
+   void load( const String& fileName );
+
 
 protected:
    //! Pointer to allocated data
@@ -156,4 +457,4 @@ std::ostream& operator<<( std::ostream& str, const ArrayView< Value, Device, Ind
 } // namespace Containers
 } // namespace TNL
 
-#include <TNL/Containers/ArrayView_impl.h>
+#include <TNL/Containers/ArrayView.hpp>
diff --git a/src/TNL/Containers/ArrayView_impl.h b/src/TNL/Containers/ArrayView.hpp
similarity index 71%
rename from src/TNL/Containers/ArrayView_impl.h
rename to src/TNL/Containers/ArrayView.hpp
index 96d00e7dea42ae244f928f5679a1045ba78af856..a32c2c5f07659e368ced1832bf68835126aed868 100644
--- a/src/TNL/Containers/ArrayView_impl.h
+++ b/src/TNL/Containers/ArrayView.hpp
@@ -13,98 +13,89 @@
 #include <iostream>
 
 #include <TNL/param-types.h>
+#include <TNL/ParallelFor.h>
 #include <TNL/Containers/Algorithms/ArrayOperations.h>
+#include <TNL/Containers/Algorithms/ArrayIO.h>
+#include <TNL/Containers/Algorithms/ArrayAssignment.h>
+#include <TNL/Exceptions/ArrayWrongSize.h>
 
 #include "ArrayView.h"
 
 namespace TNL {
 namespace Containers {
 
-// explicit initialization by raw data pointer and size
 template< typename Value,
           typename Device,
           typename Index >
-__cuda_callable__
+String
 ArrayView< Value, Device, Index >::
-ArrayView( Value* data, Index size ) : data(data), size(size)
+getType()
 {
-   TNL_ASSERT_GE( size, 0, "ArrayView size was initialized with a negative size." );
-   TNL_ASSERT_TRUE( (data == nullptr && size == 0) || (data != nullptr && size > 0),
-                    "ArrayView was initialized with a positive address and zero size or zero address and positive size." );
+   return String( "Containers::ArrayView< " ) + ", " +
+                  TNL::getType< Value >() + ", " +
+                  Device::getDeviceType() + ", " +
+                  TNL::getType< Index >() + " >";
 }
 
-// initialization from other array containers (using shallow copy)
+// explicit initialization by raw data pointer and size
 template< typename Value,
           typename Device,
           typename Index >
-   template< typename Value_ >
 __cuda_callable__
 ArrayView< Value, Device, Index >::
-ArrayView( Array< Value_, Device, Index >& array )
+ArrayView( Value* data, Index size ) : data(data), size(size)
 {
-   this->bind( array.getData(), array.getSize() );
+   TNL_ASSERT_GE( size, 0, "ArrayView size was initialized with a negative size." );
+   TNL_ASSERT_TRUE( (data == nullptr && size == 0) || (data != nullptr && size > 0),
+                    "ArrayView was initialized with a positive address and zero size or zero address and positive size." );
 }
 
+// methods for rebinding (reinitialization)
 template< typename Value,
           typename Device,
           typename Index >
-   template< int Size, typename Value_ >
 __cuda_callable__
+void
 ArrayView< Value, Device, Index >::
-ArrayView( StaticArray< Size, Value_ >& array )
+bind( Value* data, Index size )
 {
-   this->bind( array.getData(), Size );
-}
+   TNL_ASSERT_GE( size, 0, "ArrayView size was initialized with a negative size." );
+   TNL_ASSERT_TRUE( (data == nullptr && size == 0) || (data != nullptr && size > 0),
+                    "ArrayView was initialized with a positive address and zero size or zero address and positive size." );
 
-template< typename Value,
-          typename Device,
-          typename Index >
-   template< typename Value_ >
-__cuda_callable__
-ArrayView< Value, Device, Index >::
-ArrayView( const Array< Value_, Device, Index >& array )
-{
-   this->bind( array.getData(), array.getSize() );
+   this->data = data;
+   this->size = size;
 }
 
 template< typename Value,
           typename Device,
           typename Index >
-   template< int Size, typename Value_ >
 __cuda_callable__
-ArrayView< Value, Device, Index >::
-ArrayView( const StaticArray< Size, Value_ >& array )
+void ArrayView< Value, Device, Index >::bind( ArrayView view )
 {
-   this->bind( array.getData(), Size );
+   bind( view.getData(), view.getSize() );
 }
 
-// methods for rebinding (reinitialization)
 template< typename Value,
           typename Device,
           typename Index >
-__cuda_callable__
-void
+typename ArrayView< Value, Device, Index >::ViewType
 ArrayView< Value, Device, Index >::
-bind( Value* data, Index size )
+getView()
 {
-   TNL_ASSERT_GE( size, 0, "ArrayView size was initialized with a negative size." );
-   TNL_ASSERT_TRUE( (data == nullptr && size == 0) || (data != nullptr && size > 0),
-                    "ArrayView was initialized with a positive address and zero size or zero address and positive size." );
-
-   this->data = data;
-   this->size = size;
+   return *this;
 }
 
 template< typename Value,
           typename Device,
           typename Index >
-__cuda_callable__
-void ArrayView< Value, Device, Index >::bind( ArrayView view )
+typename ArrayView< Value, Device, Index >::ConstViewType
+ArrayView< Value, Device, Index >::
+getConstView() const
 {
-   bind( view.getData(), view.getSize() );
+   return *this;
 }
 
-
 // Copy-assignment does deep copy, just like regular array, but the sizes
 // must match (i.e. copy-assignment cannot resize).
 template< typename Value,
@@ -120,35 +111,18 @@ operator=( const ArrayView& view )
    return *this;
 }
 
-template< typename Value,
-           typename Device,
-           typename Index >
-   template< typename Array >
-ArrayView< Value, Device, Index >&
-ArrayView< Value, Device, Index >::
-operator=( const Array& array )
-{
-   TNL_ASSERT_EQ( getSize(), array.getSize(), "The sizes of the array views must be equal, views are not resizable." );
-   if( getSize() > 0 )
-      Algorithms::ArrayOperations< Device, typename Array::DeviceType >::copyMemory( getData(), array.getData(), getSize() );
-   return *this;
-}
-
-
 template< typename Value,
           typename Device,
           typename Index >
-String
+   template< typename T >
+ArrayView< Value, Device, Index >&
 ArrayView< Value, Device, Index >::
-getType()
+operator = ( const T& data )
 {
-   return String( "Containers::ArrayView< " ) + ", " +
-                  TNL::getType< Value >() + ", " +
-                  Device::getDeviceType() + ", " +
-                  TNL::getType< Index >() + " >";
+   Algorithms::ArrayAssignment< ArrayView, T >::assign( *this, data );
+   return *this;
 }
 
-
 template< typename Value,
           typename Device,
           typename Index >
@@ -173,7 +147,6 @@ reset()
    size = 0;
 }
 
-
 template< typename Value,
           typename Device,
           typename Index >
@@ -196,6 +169,28 @@ getData()
    return data;
 }
 
+template< typename Value,
+          typename Device,
+          typename Index >
+__cuda_callable__
+const
+Value* ArrayView< Value, Device, Index >::
+getArrayData() const
+{
+   return data;
+}
+
+template< typename Value,
+          typename Device,
+          typename Index >
+__cuda_callable__
+Value*
+ArrayView< Value, Device, Index >::
+getArrayData()
+{
+   return data;
+}
+
 template< typename Value,
           typename Device,
           typename Index >
@@ -259,27 +254,30 @@ operator[]( Index i ) const
 template< typename Value,
           typename Device,
           typename Index >
-   template< typename Value_, typename Device_, typename Index_ >
+   template< typename ArrayT >
 bool
 ArrayView< Value, Device, Index >::
-operator==( const ArrayView< Value_, Device_, Index_ >& view ) const
+operator==( const ArrayT& array ) const
 {
-   if( view.getSize() != getSize() )
+   if( array.getSize() != this->getSize() )
       return false;
-   if( getSize() == 0 )
+   if( this->getSize() == 0 )
       return true;
-   return Algorithms::ArrayOperations< Device, Device_ >::compareMemory( getData(), view.getData(), getSize() );
+   return Algorithms::ArrayOperations< DeviceType, typename ArrayT::DeviceType >::
+            compareMemory( this->getData(),
+                           array.getData(),
+                           array.getSize() );
 }
 
 template< typename Value,
           typename Device,
           typename Index >
-   template< typename Value_, typename Device_, typename Index_ >
+   template< typename ArrayT >
 bool
 ArrayView< Value, Device, Index >::
-operator!=( const ArrayView< Value_, Device_, Index_ >& view ) const
+operator!=( const ArrayT& array ) const
 {
-   return ! ( *this == view );
+   return ! ( *this == array );
 }
 
 template< typename Value,
@@ -293,6 +291,27 @@ setValue( Value value )
    Algorithms::ArrayOperations< Device >::setMemory( getData(), value, getSize() );
 }
 
+template< typename Value,
+          typename Device,
+          typename Index >
+   template< typename Function >
+void ArrayView< Value, Device, Index >::
+evaluate( Function& f, const Index begin, Index end )
+{
+   TNL_ASSERT_TRUE( this->getData(), "Attempted to set a value of an empty array view." );
+
+   ValueType* d = this->data;
+   auto eval = [=] __cuda_callable__ ( Index i )
+   {
+      d[ i ] = f( i );
+   };
+
+   if( end == -1 )
+      end = this->getSize();
+
+   ParallelFor< DeviceType >::exec( begin, end, eval );
+}
+
 template< typename Value,
           typename Device,
           typename Index >
@@ -316,12 +335,65 @@ containsOnlyValue( Value value ) const
 template< typename Value,
           typename Device,
           typename Index >
+bool
 ArrayView< Value, Device, Index >::
-operator bool() const
+empty() const
 {
-   return data;
+   return ( data == nullptr );
 }
 
+template< typename Value,
+          typename Device,
+          typename Index >
+void ArrayView< Value, Device, Index >::save( File& file ) const
+{
+   saveHeader( file, SerializationType::getType() );
+   file.save( &this->size );
+   if( this->size != 0 )
+      Algorithms::ArrayIO< Value, Device, Index >::save( file, this->data, this->size );
+}
+
+template< typename Value,
+          typename Device,
+          typename Index >
+void
+ArrayView< Value, Device, Index >::
+load( File& file )
+{
+   String type;
+   loadHeader( file, type );
+   if( type != SerializationType::getType() )
+      throw Exceptions::ObjectTypeMismatch( SerializationType::getType(), type );
+   Index _size;
+   file.load( &_size );
+   if( _size != this->getSize() )
+      throw Exceptions::ArrayWrongSize( _size, convertToString( this->getSize() ) );
+   Algorithms::ArrayIO< Value, Device, Index >::load( file, this->data, this->size );
+}
+
+template< typename Value,
+          typename Device,
+          typename Index >
+void
+ArrayView< Value, Device, Index >::
+save( const String& fileName ) const
+{
+   File file;
+   file.open( fileName, File::Mode::Out );
+   this->save( file );
+}
+
+template< typename Value,
+          typename Device,
+          typename Index >
+void
+ArrayView< Value, Device, Index >::
+load( const String& fileName )
+{
+   File file;
+   file.open( fileName, File::Mode::In );
+   this->load( file );
+}
 
 template< typename Value, typename Device, typename Index >
 std::ostream& operator<<( std::ostream& str, const ArrayView< Value, Device, Index >& v )
diff --git a/src/TNL/Containers/DistributedArray.h b/src/TNL/Containers/DistributedArray.h
index d653fc57170f519887bec2f7a3a12067e690e460..f624100cb6e8b6ad2a3c09d34f871e9994df440c 100644
--- a/src/TNL/Containers/DistributedArray.h
+++ b/src/TNL/Containers/DistributedArray.h
@@ -15,9 +15,7 @@
 #include <type_traits>  // std::add_const
 
 #include <TNL/Containers/Array.h>
-#include <TNL/Containers/ArrayView.h>
-#include <TNL/Communicators/MpiCommunicator.h>
-#include <TNL/Containers/Subrange.h>
+#include <TNL/Containers/DistributedArrayView.h>
 
 namespace TNL {
 namespace Containers {
@@ -41,6 +39,8 @@ public:
    using ConstLocalArrayViewType = Containers::ArrayView< typename std::add_const< Value >::type, Device, Index >;
    using HostType = DistributedArray< Value, Devices::Host, Index, Communicator >;
    using CudaType = DistributedArray< Value, Devices::Cuda, Index, Communicator >;
+   using ViewType = DistributedArrayView< Value, Device, Index, Communicator >;
+   using ConstViewType = DistributedArrayView< typename std::add_const< Value >::type, Device, Index, Communicator >;
 
    DistributedArray() = default;
 
@@ -69,9 +69,28 @@ public:
    // TODO: no getSerializationType method until there is support for serialization
 
 
-   /*
-    * Usual Array methods follow below.
+   // Usual Array methods follow below.
+
+   /**
+    * \brief Returns a modifiable view of the array.
+    */
+   ViewType getView();
+
+   /**
+    * \brief Returns a non-modifiable view of the array.
+    */
+   ConstViewType getConstView() const;
+
+   /**
+    * \brief Conversion operator to a modifiable view of the array.
+    */
+   operator ViewType();
+
+   /**
+    * \brief Conversion operator to a non-modifiable view of the array.
     */
+   operator ConstViewType() const;
+
    template< typename Array >
    void setLike( const Array& array );
 
diff --git a/src/TNL/Containers/DistributedArrayView.h b/src/TNL/Containers/DistributedArrayView.h
index e9e9e0a487e38cd084d3f6ec80c4ee5c372f095e..6995cf03e494fda563f0e0a386a494a8afc892c3 100644
--- a/src/TNL/Containers/DistributedArrayView.h
+++ b/src/TNL/Containers/DistributedArrayView.h
@@ -12,7 +12,9 @@
 
 #pragma once
 
-#include <TNL/Containers/DistributedArray.h>
+#include <TNL/Containers/ArrayView.h>
+#include <TNL/Communicators/MpiCommunicator.h>
+#include <TNL/Containers/Subrange.h>
 
 namespace TNL {
 namespace Containers {
@@ -34,6 +36,14 @@ public:
    using ConstLocalArrayViewType = Containers::ArrayView< typename std::add_const< Value >::type, Device, Index >;
    using HostType = DistributedArrayView< Value, Devices::Host, Index, Communicator >;
    using CudaType = DistributedArrayView< Value, Devices::Cuda, Index, Communicator >;
+   using ViewType = DistributedArrayView< Value, Device, Index, Communicator >;
+   using ConstViewType = DistributedArrayView< typename std::add_const< Value >::type, Device, Index, Communicator >;
+
+   // Initialization by raw data
+   __cuda_callable__
+   DistributedArrayView( const LocalRangeType& localRange, IndexType globalSize, CommunicationGroup group, LocalArrayViewType localData )
+   : localRange(localRange), globalSize(globalSize), group(group), localData(localData)
+   {}
 
    __cuda_callable__
    DistributedArrayView() = default;
@@ -53,15 +63,6 @@ public:
    __cuda_callable__
    DistributedArrayView( DistributedArrayView&& ) = default;
 
-   // initialization from distributed array
-   template< typename Value_ >
-   DistributedArrayView( DistributedArray< Value_, Device, Index, Communicator >& array );
-
-   // this constructor will be used only when Value is const-qualified
-   // (const views are initializable by const references)
-   template< typename Value_ >
-   DistributedArrayView( const DistributedArray< Value_, Device, Index, Communicator >& array );
-
    // method for rebinding (reinitialization)
    // Note that you can also bind directly to Array and other types implicitly
    // convertible to ArrayView.
@@ -73,6 +74,18 @@ public:
    template< typename Value_ >
    void bind( Value_* data, IndexType localSize );
 
+   /**
+    * \brief Returns a modifiable view of the array view.
+    */
+   __cuda_callable__
+   ViewType getView();
+
+   /**
+    * \brief Returns a non-modifiable view of the array view.
+    */
+   __cuda_callable__
+   ConstViewType getConstView() const;
+
 
    // Copy-assignment does deep copy, just like regular array, but the sizes
    // must match (i.e. copy-assignment cannot resize).
diff --git a/src/TNL/Containers/DistributedArrayView_impl.h b/src/TNL/Containers/DistributedArrayView_impl.h
index 8fa18cbff956866cece9efb2cc78ea36f2b2d6c6..ad4a38b110bf392b788fa19821d8f378843b4148 100644
--- a/src/TNL/Containers/DistributedArrayView_impl.h
+++ b/src/TNL/Containers/DistributedArrayView_impl.h
@@ -35,55 +35,53 @@ template< typename Value,
           typename Device,
           typename Index,
           typename Communicator >
-   template< typename Value_ >
+__cuda_callable__
+void
 DistributedArrayView< Value, Device, Index, Communicator >::
-DistributedArrayView( DistributedArray< Value_, Device, Index, Communicator >& array )
-: localRange( array.getLocalRange() ),
-  globalSize( array.getSize() ),
-  group( array.getCommunicationGroup() ),
-  localData( array.getLocalArrayView() )
-{}
+bind( DistributedArrayView view )
+{
+   localRange = view.getLocalRange();
+   globalSize = view.getSize();
+   group = view.getCommunicationGroup();
+   localData.bind( view.getLocalArrayView() );
+}
 
 template< typename Value,
           typename Device,
           typename Index,
           typename Communicator >
    template< typename Value_ >
+void
 DistributedArrayView< Value, Device, Index, Communicator >::
-DistributedArrayView( const DistributedArray< Value_, Device, Index, Communicator >& array )
-: localRange( array.getLocalRange() ),
-  globalSize( array.getSize() ),
-  group( array.getCommunicationGroup() ),
-  localData( array.getLocalArrayView() )
-{}
+bind( Value_* data, IndexType localSize )
+{
+   TNL_ASSERT_EQ( localSize, localRange.getSize(),
+                  "The local array size does not match the local range of the distributed array." );
+   localData.bind( data, localSize );
+}
 
 template< typename Value,
           typename Device,
           typename Index,
           typename Communicator >
 __cuda_callable__
-void
+typename DistributedArrayView< Value, Device, Index, Communicator >::ViewType
 DistributedArrayView< Value, Device, Index, Communicator >::
-bind( DistributedArrayView view )
+getView()
 {
-   localRange = view.getLocalRange();
-   globalSize = view.getSize();
-   group = view.getCommunicationGroup();
-   localData.bind( view.getLocalArrayView() );
+   return *this;
 }
 
 template< typename Value,
           typename Device,
           typename Index,
           typename Communicator >
-   template< typename Value_ >
-void
+__cuda_callable__
+typename DistributedArrayView< Value, Device, Index, Communicator >::ConstViewType
 DistributedArrayView< Value, Device, Index, Communicator >::
-bind( Value_* data, IndexType localSize )
+getConstView() const
 {
-   TNL_ASSERT_EQ( localSize, localRange.getSize(),
-                  "The local array size does not match the local range of the distributed array." );
-   localData.bind( data, localSize );
+   return *this;
 }
 
 
diff --git a/src/TNL/Containers/DistributedArray_impl.h b/src/TNL/Containers/DistributedArray_impl.h
index aab55bd718f480e839c83183fd0fe810c1cfc575..34e8e041b4b0945f708f40e26da8c3f8ea226c20 100644
--- a/src/TNL/Containers/DistributedArray_impl.h
+++ b/src/TNL/Containers/DistributedArray_impl.h
@@ -76,7 +76,7 @@ typename DistributedArray< Value, Device, Index, Communicator >::LocalArrayViewT
 DistributedArray< Value, Device, Index, Communicator >::
 getLocalArrayView()
 {
-   return localData;
+   return localData.getView();
 }
 
 template< typename Value,
@@ -87,7 +87,7 @@ typename DistributedArray< Value, Device, Index, Communicator >::ConstLocalArray
 DistributedArray< Value, Device, Index, Communicator >::
 getLocalArrayView() const
 {
-   return localData;
+   return localData.getConstView();
 }
 
 template< typename Value,
@@ -117,6 +117,48 @@ copyFromGlobal( ConstLocalArrayViewType globalArray )
  * Usual Array methods follow below.
  */
 
+template< typename Value,
+          typename Device,
+          typename Index,
+          typename Communicator >
+typename DistributedArray< Value, Device, Index, Communicator >::ViewType
+DistributedArray< Value, Device, Index, Communicator >::
+getView()
+{
+   return ViewType( getLocalRange(), getSize(), getCommunicationGroup(), getLocalArrayView() );
+}
+
+template< typename Value,
+          typename Device,
+          typename Index,
+          typename Communicator >
+typename DistributedArray< Value, Device, Index, Communicator >::ConstViewType
+DistributedArray< Value, Device, Index, Communicator >::
+getConstView() const
+{
+   return ConstViewType( getLocalRange(), getSize(), getCommunicationGroup(), getLocalArrayView() );
+}
+
+template< typename Value,
+          typename Device,
+          typename Index,
+          typename Communicator >
+DistributedArray< Value, Device, Index, Communicator >::
+operator ViewType()
+{
+   return getView();
+}
+
+template< typename Value,
+          typename Device,
+          typename Index,
+          typename Communicator >
+DistributedArray< Value, Device, Index, Communicator >::
+operator ConstViewType() const
+{
+   return getConstView();
+}
+
 template< typename Value,
           typename Device,
           typename Index,
diff --git a/src/TNL/Containers/DistributedVector.h b/src/TNL/Containers/DistributedVector.h
index 794b99f48d2996af94c52c24d29e20deae1a0e4c..3e110b1270e0609d6b5a140e83cb61dd58ea9829 100644
--- a/src/TNL/Containers/DistributedVector.h
+++ b/src/TNL/Containers/DistributedVector.h
@@ -12,8 +12,8 @@
 
 #pragma once
 
-#include "DistributedArray.h"
-#include <TNL/Containers/VectorView.h>
+#include <TNL/Containers/DistributedArray.h>
+#include <TNL/Containers/DistributedVectorView.h>
 
 namespace TNL {
 namespace Containers {
@@ -36,6 +36,8 @@ public:
    using ConstLocalVectorViewType = Containers::VectorView< typename std::add_const< Real >::type, Device, Index >;
    using HostType = DistributedVector< Real, Devices::Host, Index, Communicator >;
    using CudaType = DistributedVector< Real, Devices::Cuda, Index, Communicator >;
+   using ViewType = DistributedVectorView< Real, Device, Index, Communicator >;
+   using ConstViewType = DistributedVectorView< typename std::add_const< Real >::type, Device, Index, Communicator >;
 
    // inherit all constructors and assignment operators from Array
    using BaseType::DistributedArray;
@@ -46,6 +48,26 @@ public:
 
    ConstLocalVectorViewType getLocalVectorView() const;
 
+   /**
+    * \brief Returns a modifiable view of the vector.
+    */
+   ViewType getView();
+
+   /**
+    * \brief Returns a non-modifiable view of the vector.
+    */
+   ConstViewType getConstView() const;
+
+   /**
+    * \brief Conversion operator to a modifiable view of the vector.
+    */
+   operator ViewType();
+
+   /**
+    * \brief Conversion operator to a non-modifiable view of the vector.
+    */
+   operator ConstViewType() const;
+
 
    static String getType();
 
diff --git a/src/TNL/Containers/DistributedVectorView.h b/src/TNL/Containers/DistributedVectorView.h
index e36e60e00e4990efc986e3ef89c87bfe75720813..7fc3778b4dd162ce789f140315c433523bfcf695 100644
--- a/src/TNL/Containers/DistributedVectorView.h
+++ b/src/TNL/Containers/DistributedVectorView.h
@@ -37,15 +37,41 @@ public:
    using ConstLocalVectorViewType = Containers::VectorView< typename std::add_const< Real >::type, Device, Index >;
    using HostType = DistributedVectorView< Real, Devices::Host, Index, Communicator >;
    using CudaType = DistributedVectorView< Real, Devices::Cuda, Index, Communicator >;
+   using ViewType = DistributedVectorView< Real, Device, Index, Communicator >;
+   using ConstViewType = DistributedVectorView< typename std::add_const< Real >::type, Device, Index, Communicator >;
 
    // inherit all constructors and assignment operators from ArrayView
    using BaseType::DistributedArrayView;
    using BaseType::operator=;
 
+   // In C++14, default constructors cannot be inherited, although Clang
+   // and GCC since version 7.0 inherit them.
+   // https://stackoverflow.com/a/51854172
+   __cuda_callable__
+   DistributedVectorView() = default;
+
+   // initialization by base class is not a copy constructor so it has to be explicit
+   template< typename Real_ >  // template catches both const and non-const qualified Element
+   __cuda_callable__
+   DistributedVectorView( const DistributedArrayView< Real_, Device, Index, Communicator >& view )
+   : BaseType::DistributedArrayView( view ) {}
+
    LocalVectorViewType getLocalVectorView();
 
    ConstLocalVectorViewType getLocalVectorView() const;
 
+   /**
+    * \brief Returns a modifiable view of the array view.
+    */
+   __cuda_callable__
+   ViewType getView();
+
+   /**
+    * \brief Returns a non-modifiable view of the array view.
+    */
+   __cuda_callable__
+   ConstViewType getConstView() const;
+
 
    static String getType();
 
diff --git a/src/TNL/Containers/DistributedVectorView_impl.h b/src/TNL/Containers/DistributedVectorView_impl.h
index cd1fd1619bd1c167a32fb722f5eee37286ed5bd4..0639b2f8e1a68105b48bbca43def645d622f1580 100644
--- a/src/TNL/Containers/DistributedVectorView_impl.h
+++ b/src/TNL/Containers/DistributedVectorView_impl.h
@@ -42,6 +42,30 @@ getLocalVectorView() const
    return this->getLocalArrayView();
 }
 
+template< typename Value,
+          typename Device,
+          typename Index,
+          typename Communicator >
+__cuda_callable__
+typename DistributedVectorView< Value, Device, Index, Communicator >::ViewType
+DistributedVectorView< Value, Device, Index, Communicator >::
+getView()
+{
+   return *this;
+}
+
+template< typename Value,
+          typename Device,
+          typename Index,
+          typename Communicator >
+__cuda_callable__
+typename DistributedVectorView< Value, Device, Index, Communicator >::ConstViewType
+DistributedVectorView< Value, Device, Index, Communicator >::
+getConstView() const
+{
+   return *this;
+}
+
 
 template< typename Real,
           typename Device,
diff --git a/src/TNL/Containers/DistributedVector_impl.h b/src/TNL/Containers/DistributedVector_impl.h
index a44baa9363c21508534941d5e7b90fc00fc7f853..239239ead7f2b5b5f4b066a11d81648f389a77ae 100644
--- a/src/TNL/Containers/DistributedVector_impl.h
+++ b/src/TNL/Containers/DistributedVector_impl.h
@@ -42,6 +42,48 @@ getLocalVectorView() const
    return this->getLocalArrayView();
 }
 
+template< typename Value,
+          typename Device,
+          typename Index,
+          typename Communicator >
+typename DistributedVector< Value, Device, Index, Communicator >::ViewType
+DistributedVector< Value, Device, Index, Communicator >::
+getView()
+{
+   return ViewType( this->getLocalRange(), this->getSize(), this->getCommunicationGroup(), this->getLocalVectorView() );
+}
+
+template< typename Value,
+          typename Device,
+          typename Index,
+          typename Communicator >
+typename DistributedVector< Value, Device, Index, Communicator >::ConstViewType
+DistributedVector< Value, Device, Index, Communicator >::
+getConstView() const
+{
+   return ConstViewType( this->getLocalRange(), this->getSize(), this->getCommunicationGroup(), this->getLocalVectorView() );
+}
+
+template< typename Value,
+          typename Device,
+          typename Index,
+          typename Communicator >
+DistributedVector< Value, Device, Index, Communicator >::
+operator ViewType()
+{
+   return getView();
+}
+
+template< typename Value,
+          typename Device,
+          typename Index,
+          typename Communicator >
+DistributedVector< Value, Device, Index, Communicator >::
+operator ConstViewType() const
+{
+   return getConstView();
+}
+
 
 template< typename Real,
           typename Device,
diff --git a/src/TNL/Containers/List_impl.h b/src/TNL/Containers/List_impl.h
index 36fd5dbdc2c928d2feb07bf505eb5c441ab85101..a8bcb81158ad187b3a3573e2a4c34c758f64640f 100644
--- a/src/TNL/Containers/List_impl.h
+++ b/src/TNL/Containers/List_impl.h
@@ -282,9 +282,9 @@ void List< T >::DeepEraseAll()
 template< typename T >
 bool List< T >::Save( File& file ) const
 {
-   file.write( &size );
+   file.save( &size );
    for( int i = 0; i < size; i ++ )
-      if( ! file. write( &operator[]( i ), 1 ) )
+      if( ! file. save( &operator[]( i ), 1 ) )
          return false;
    return true;
 }
@@ -292,7 +292,7 @@ bool List< T >::Save( File& file ) const
 template< typename T >
 bool List< T >::DeepSave( File& file ) const
 {
-   file. write( &size );
+   file.save( &size );
    for( int i = 0; i < size; i ++ )
       if( ! operator[]( i ). save( file ) ) return false;
    return true;
@@ -303,7 +303,7 @@ bool List< T >::Load( File& file )
 {
    reset();
    int _size;
-   file. read( &_size, 1 );
+   file.load( &_size, 1 );
    if( _size < 0 )
    {
       std::cerr << "The curve size is negative." << std::endl;
@@ -312,7 +312,7 @@ bool List< T >::Load( File& file )
    T t;
    for( int i = 0; i < _size; i ++ )
    {
-      if( ! file. read( &t, 1 ) )
+      if( ! file.load( &t, 1 ) )
          return false;
       Append( t );
    }
@@ -324,7 +324,7 @@ bool List< T >::DeepLoad( File& file )
 {
    reset();
    int _size;
-   file. read( &_size );
+   file.load( &_size );
    if( _size < 0 )
    {
       std::cerr << "The list size is negative." << std::endl;
diff --git a/src/TNL/Containers/MultiArray.h b/src/TNL/Containers/MultiArray.h
deleted file mode 100644
index cdcda634bcf768759c44f486790a3511445392d4..0000000000000000000000000000000000000000
--- a/src/TNL/Containers/MultiArray.h
+++ /dev/null
@@ -1,371 +0,0 @@
-/***************************************************************************
-                          MultiArray.h  -  description
-                             -------------------
-    begin                : Nov 25, 2010
-    copyright            : (C) 2010 by Tomas Oberhuber
-    email                : tomas.oberhuber@fjfi.cvut.cz
- ***************************************************************************/
-
-/* See Copyright Notice in tnl/Copyright */
-
-#pragma once
-
-#include <iostream>
-#include <TNL/Containers/Array.h>
-#include <TNL/Containers/StaticVector.h>
-#include <TNL/Assert.h>
-
-namespace TNL {
-namespace Containers {   
-
-template< int Dimension, typename Value = double, typename Device = Devices::Host, typename Index = int >
-class MultiArray : public Array< Value, Device, Index >
-{
-};
-
-template< typename Value, typename Device, typename Index >
-class MultiArray< 1, Value, Device, Index > : public Array< Value, Device, Index >
-{
-   public:
-   enum { Dimension = 1};
-   typedef Value ValueType;
-   typedef Device DeviceType;
-   typedef Index IndexType;
-   typedef MultiArray< 1, Value, Devices::Host, Index > HostType;
-   typedef MultiArray< 1, Value, Devices::Cuda, Index > CudaType;
-
-
-   MultiArray();
-
-   static String getType();
-
-   virtual String getTypeVirtual() const;
-
-   static String getSerializationType();
-
-   virtual String getSerializationTypeVirtual() const;
-
-   void setDimensions( const Index iSize );
-
-   void setDimensions( const Containers::StaticVector< 1, Index >& dimensions );
-
-   __cuda_callable__ void getDimensions( Index& iSize ) const;
-
-   __cuda_callable__ const Containers::StaticVector< 1, Index >& getDimensions() const;
-
-   //! Set dimensions of the array using another array as a template
-   template< typename MultiArray >
-   void setLike( const MultiArray& v );
- 
-   void reset();
-
-   __cuda_callable__ Index getElementIndex( const Index i ) const;
-
-   void setElement( const Index i, Value value );
-
-   //! This method can be used for general access to the elements of the arrays.
-   /*! It does not return reference but value. So it can be used to access
-    *  arrays in different address space (usually GPU device).
-    *  See also operator().
-    */
-   Value getElement( const Index i ) const;
-
-   //! Operator for accessing elements of the array.
-   __cuda_callable__ Value& operator()( const Index i );
-
-   __cuda_callable__ const Value& operator()( const Index i ) const;
-
-
-   template< typename MultiArrayT >
-   bool operator == ( const MultiArrayT& array ) const;
-
-   template< typename MultiArrayT >
-   bool operator != ( const MultiArrayT& array ) const;
-
-   MultiArray< 1, Value, Device, Index >& operator = ( const MultiArray< 1, Value, Device, Index >& array );
-
-   template< typename MultiArrayT >
-   MultiArray< 1, Value, Device, Index >& operator = ( const MultiArrayT& array );
-
-   //! Method for saving the object to a file as a binary data
-   bool save( File& file ) const;
-
-   //! Method for restoring the object from a file
-   bool load( File& file );
-
-   bool save( const String& fileName ) const;
-
-   bool load( const String& fileName );
-
-   protected:
-
-   Containers::StaticVector< 1, Index > dimensions;
-};
-
-template< typename Value, typename Device, typename Index >
-class MultiArray< 2, Value, Device, Index > : public Array< Value, Device, Index >
-{
-   public:
-   enum { Dimension = 2 };
-   typedef Value ValueType;
-   typedef Device DeviceType;
-   typedef Index IndexType;
-   typedef MultiArray< 2, Value, Devices::Host, Index > HostType;
-   typedef MultiArray< 2, Value, Devices::Cuda, Index > CudaType;
-
-
-   MultiArray();
-
-   static String getType();
-
-   virtual String getTypeVirtual() const;
-
-   static String getSerializationType();
-
-   virtual String getSerializationTypeVirtual() const;
-
-   void setDimensions( const Index jSize, const Index iSize );
-
-   void setDimensions( const Containers::StaticVector< 2, Index >& dimensions );
-
-   __cuda_callable__ void getDimensions( Index& jSize, Index& iSize ) const;
-
-   __cuda_callable__ const Containers::StaticVector< 2, Index >& getDimensions() const;
-
-   //! Set dimensions of the array using another array as a template
-   template< typename MultiArray >
-   void setLike( const MultiArray& v );
-
-   void reset();
-
-   __cuda_callable__ Index getElementIndex( const Index j, const Index i ) const;
-
-   void setElement( const Index j, const Index i, Value value );
-
-   //! This method can be used for general access to the elements of the arrays.
-   /*! It does not return reference but value. So it can be used to access
-    *  arrays in different adress space (usualy GPU device).
-    *  See also operator().
-    */
-   Value getElement( const Index j, const Index i ) const;
-
-   //! Operator for accessing elements of the array.
-   /*! It returns reference to given elements so it cannot be
-    *  used to access elements of arrays in different address space
-    *  (GPU device usually).
-    */
-   __cuda_callable__ Value& operator()( const Index j, const Index i );
-
-   __cuda_callable__ const Value& operator()( const Index j, const Index i ) const;
-
-   template< typename MultiArrayT >
-   bool operator == ( const MultiArrayT& array ) const;
-
-   template< typename MultiArrayT >
-   bool operator != ( const MultiArrayT& array ) const;
-
-   MultiArray< 2, Value, Device, Index >& operator = ( const MultiArray< 2, Value, Device, Index >& array );
-
-   template< typename MultiArrayT >
-   MultiArray< 2, Value, Device, Index >& operator = ( const MultiArrayT& array );
-
-   //! Method for saving the object to a file as a binary data
-   bool save( File& file ) const;
-
-   //! Method for restoring the object from a file
-   bool load( File& file );
-
-   bool save( const String& fileName ) const;
-
-   bool load( const String& fileName );
-
-   protected:
-
-   Containers::StaticVector< 2, Index > dimensions;
-};
-
-template< typename Value, typename Device, typename Index >
-class MultiArray< 3, Value, Device, Index > : public Array< Value, Device, Index >
-{
-   public:
-
-   enum { Dimension = 3 };
-   typedef Value ValueType;
-   typedef Device DeviceType;
-   typedef Index IndexType;
-   typedef MultiArray< 3, Value, Devices::Host, Index > HostType;
-   typedef MultiArray< 3, Value, Devices::Cuda, Index > CudaType;
-
-
-   MultiArray();
-
-   static String getType();
-
-   virtual String getTypeVirtual() const;
-
-   static String getSerializationType();
-
-   virtual String getSerializationTypeVirtual() const;
-
-   void setDimensions( const Index k, const Index j, const Index iSize );
-
-   void setDimensions( const Containers::StaticVector< 3, Index >& dimensions );
-
-   __cuda_callable__ void getDimensions( Index& k, Index& j, Index& iSize ) const;
-
-   __cuda_callable__ const Containers::StaticVector< 3, Index >& getDimensions() const;
-
-   //! Set dimensions of the array using another array as a template
-   template< typename MultiArrayT >
-   void setLike( const MultiArrayT& v );
-
-   void reset();
-
-   __cuda_callable__ Index getElementIndex( const Index k, const Index j, const Index i ) const;
-
-   void setElement( const Index k, const Index j, const Index i, Value value );
-
-   //! This method can be used for general access to the elements of the arrays.
-   /*! It does not return reference but value. So it can be used to access
-    *  arrays in different adress space (usualy GPU device).
-    *  See also operator().
-    */
-   Value getElement( const Index k, const Index j, const Index i ) const;
-
-   //! Operator for accessing elements of the array.
-   /*! It returns reference to given elements so it cannot be
-    *  used to access elements of arrays in different adress space
-    *  (GPU device usualy).
-    */
-   __cuda_callable__ Value& operator()( const Index k, const Index j, const Index i );
-
-   __cuda_callable__ const Value& operator()( const Index k, const Index j, const Index i ) const;
-
-   template< typename MultiArrayT >
-   bool operator == ( const MultiArrayT& array ) const;
-
-   template< typename MultiArrayT >
-   bool operator != ( const MultiArrayT& array ) const;
-
-   MultiArray< 3, Value, Device, Index >& operator = ( const MultiArray< 3, Value, Device, Index >& array );
-
-   template< typename MultiArrayT >
-   MultiArray< 3, Value, Device, Index >& operator = ( const MultiArrayT& array );
-
-   //! Method for saving the object to a file as a binary data
-   bool save( File& file ) const;
-
-   //! Method for restoring the object from a file
-   bool load( File& file );
-
-   bool save( const String& fileName ) const;
-
-   bool load( const String& fileName );
-
-   protected:
-
-   Containers::StaticVector< 3, Index > dimensions;
-};
-
-template< typename Value, typename Device, typename Index >
-class MultiArray< 4, Value, Device, Index > : public Array< Value, Device, Index >
-{
-   public:
-
-   enum { Dimension = 4 };
-   typedef Value ValueType;
-   typedef Device DeviceType;
-   typedef Index IndexType;
-   typedef MultiArray< 4, Value, Devices::Host, Index > HostType;
-   typedef MultiArray< 4, Value, Devices::Cuda, Index > CudaType;
-
-
-   MultiArray();
-
-   static String getType();
-
-   virtual String getTypeVirtual() const;
-
-   static String getSerializationType();
-
-   virtual String getSerializationTypeVirtual() const;
-
-   void setDimensions( const Index l, const Index k, const Index j, const Index iSize );
-
-   void setDimensions( const Containers::StaticVector< 4, Index >& dimensions );
-
-   __cuda_callable__ void getDimensions( Index& l, Index& k, Index& j, Index& iSize ) const;
-
-   __cuda_callable__ const Containers::StaticVector< 4, Index >& getDimensions() const;
-
-   //! Set dimensions of the array using another array as a template
-   template< typename MultiArrayT >
-   void setLike( const MultiArrayT& v );
-
-   void reset();
-
-   __cuda_callable__ Index getElementIndex( const Index l, const Index k, const Index j, const Index i ) const;
-
-   void setElement( const Index l, const Index k, const Index j, const Index i, Value value );
-
-   //! This method can be used for general access to the elements of the arrays.
-   /*! It does not return reference but value. So it can be used to access
-    *  arrays in different adress space (usualy GPU device).
-    *  See also operator().
-    */
-   Value getElement( const Index l, const Index k, const Index j, const Index i ) const;
-
-   //! Operator for accessing elements of the array.
-   /*! It returns reference to given elements so it cannot be
-    *  used to access elements of arrays in different adress space
-    *  (GPU device usualy).
-    */
-   __cuda_callable__ Value& operator()( const Index l, const Index k, const Index j, const Index i );
-
-   __cuda_callable__ const Value& operator()( const Index l, const Index k, const Index j, const Index i ) const;
-
-   template< typename MultiArrayT >
-   bool operator == ( const MultiArrayT& array ) const;
-
-   template< typename MultiArrayT >
-   bool operator != ( const MultiArrayT& array ) const;
-
-   MultiArray< 4, Value, Device, Index >& operator = ( const MultiArray< 4, Value, Device, Index >& array );
-
-   template< typename MultiArrayT >
-   MultiArray< 4, Value, Device, Index >& operator = ( const MultiArrayT& array );
-
-   //! Method for saving the object to a file as a binary data
-   bool save( File& file ) const;
-
-   //! Method for restoring the object from a file
-   bool load( File& file );
-
-   bool save( const String& fileName ) const;
-
-   bool load( const String& fileName );
-
-   protected:
-
-   Containers::StaticVector< 4, Index > dimensions;
-};
-
-template< typename Value, typename device, typename Index >
-std::ostream& operator << ( std::ostream& str, const MultiArray< 1, Value, device, Index >& array );
-
-template< typename Value, typename device, typename Index >
-std::ostream& operator << ( std::ostream& str, const MultiArray< 2, Value, device, Index >& array );
-
-template< typename Value, typename device, typename Index >
-std::ostream& operator << ( std::ostream& str, const MultiArray< 3, Value, device, Index >& array );
-
-template< typename Value, typename device, typename Index >
-std::ostream& operator << ( std::ostream& str, const MultiArray< 4, Value, device, Index >& array );
-
-} // namespace Containers
-} // namespace TNL
-
-#include <TNL/Containers/MultiArray1D_impl.h>
-#include <TNL/Containers/MultiArray2D_impl.h>
-#include <TNL/Containers/MultiArray3D_impl.h>
-#include <TNL/Containers/MultiArray4D_impl.h>
diff --git a/src/TNL/Containers/MultiArray1D_impl.h b/src/TNL/Containers/MultiArray1D_impl.h
deleted file mode 100644
index 6c8f0b29ceefb37ea4bb237d0a920295603125c0..0000000000000000000000000000000000000000
--- a/src/TNL/Containers/MultiArray1D_impl.h
+++ /dev/null
@@ -1,241 +0,0 @@
-/***************************************************************************
-                          MultiArray1D_impl.h  -  description
-                             -------------------
-    begin                : Nov 13, 2012
-    copyright            : (C) 2012 by Tomas Oberhuber
-    email                : tomas.oberhuber@fjfi.cvut.cz
- ***************************************************************************/
-
-/* See Copyright Notice in tnl/Copyright */
-
-#pragma once 
-
-namespace TNL {
-namespace Containers {   
-
-template< typename Value, typename Device, typename Index >
-MultiArray< 1, Value, Device, Index > :: MultiArray()
-{
-}
-
-template< typename Value, typename Device, typename Index >
-String MultiArray< 1, Value, Device, Index > :: getType()
-{
-   return String( "Containers::MultiArray< ") +
-          String( Dimension ) +
-          String( ", " ) +
-          String( TNL::getType< Value >() ) +
-          String( ", " ) +
-          String( Device :: getDeviceType() ) +
-          String( ", " ) +
-          String( TNL::getType< Index >() ) +
-          String( " >" );
-}
-
-template< typename Value,
-          typename Device,
-          typename Index >
-String MultiArray< 1, Value, Device, Index > :: getTypeVirtual() const
-{
-   return this->getType();
-};
-
-template< typename Value,
-          typename Device,
-          typename Index >
-String MultiArray< 1, Value, Device, Index > :: getSerializationType()
-{
-   return HostType::getType();
-};
-
-template< typename Value,
-          typename Device,
-          typename Index >
-String MultiArray< 1, Value, Device, Index > :: getSerializationTypeVirtual() const
-{
-   return this->getSerializationType();
-};
-
-template< typename Value, typename Device, typename Index >
-void MultiArray< 1, Value, Device, Index > :: setDimensions( const Index iSize )
-{
-   TNL_ASSERT( iSize > 0,
-              std::cerr << "iSize = " << iSize );
-   dimensions[ 0 ] = iSize;
-   Array< Value, Device, Index >::setSize( iSize );
-}
-
-template< typename Value, typename Device, typename Index >
-void MultiArray< 1, Value, Device, Index > :: setDimensions( const Containers::StaticVector< 1, Index >& dimensions )
-{
-   TNL_ASSERT( dimensions[ 0 ] > 0,
-              std::cerr << " dimensions[ 0 ] = " << dimensions[ 0 ] );
-   this->dimensions = dimensions;
-   Array< Value, Device, Index >::setSize( this->dimensions[ 0 ] );
-}
-
-template< typename Value, typename Device, typename Index >
-   template< typename MultiArrayT >
-void MultiArray< 1, Value, Device, Index > :: setLike( const MultiArrayT& multiArray )
-{
-   setDimensions( multiArray. getDimensions() );
-}
-
-template< typename Value, typename Device, typename Index >
-void MultiArray< 1, Value, Device, Index >::reset()
-{
-   this->dimensions = Containers::StaticVector< 1, Index >( ( Index ) 0 );
-   Array< Value, Device, Index >::reset();
-}
-
-template< typename Value, typename Device, typename Index >
-__cuda_callable__
-void MultiArray< 1, Value, Device, Index > :: getDimensions( Index& xSize ) const
-{
-   xSize = this->dimensions[ 0 ];
-}
-
-template< typename Value, typename Device, typename Index >
-__cuda_callable__
-const Containers::StaticVector< 1, Index >& MultiArray< 1, Value, Device, Index > :: getDimensions() const
-{
-   return this->dimensions;
-}
-
-template< typename Value, typename Device, typename Index >
-__cuda_callable__
-Index MultiArray< 1, Value, Device, Index > :: getElementIndex( const Index i ) const
-{
-   TNL_ASSERT( i >= 0 && i < this->dimensions[ 0 ],
-              std::cerr << "i = " << i << " this->dimensions[ 0 ] = " <<  this->dimensions[ 0 ] );
-   return i;
-}
-
-template< typename Value, typename Device, typename Index >
-Value MultiArray< 1, Value, Device, Index > :: getElement( const Index i ) const
-{
-   return Array< Value, Device, Index > :: getElement( getElementIndex( i ) );
-}
-
-template< typename Value, typename Device, typename Index >
-void MultiArray< 1, Value, Device, Index > :: setElement( const Index i, Value value )
-{
-   Array< Value, Device, Index > :: setElement( getElementIndex( i ), value );
-}
-
-template< typename Value, typename Device, typename Index >
-__cuda_callable__
-Value& MultiArray< 1, Value, Device, Index > :: operator()( const Index element )
-{
-   return Array< Value, Device, Index > :: operator[]( getElementIndex( element ) );
-}
-
-template< typename Value, typename Device, typename Index >
-__cuda_callable__
-const Value& MultiArray< 1, Value, Device, Index > :: operator()( const Index element ) const
-{
-   return Array< Value, Device, Index > :: operator[]( getElementIndex( element ) );
-}
-
-template< typename Value, typename Device, typename Index >
-   template< typename MultiArrayT >
-bool MultiArray< 1, Value, Device, Index > :: operator == ( const MultiArrayT& array ) const
-{
-   // TODO: Static assert on dimensions
-   TNL_ASSERT( this->getDimensions() == array. getDimensions(),
-              std::cerr << "You are attempting to compare two arrays with different dimensions." << std::endl
-                   << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl
-                   << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; );
-   return Array< Value, Device, Index > :: operator == ( array );
-}
-
-template< typename Value, typename Device, typename Index >
-   template< typename MultiArrayT >
-bool MultiArray< 1, Value, Device, Index > :: operator != ( const MultiArrayT& array ) const
-{
-   return ! ( (* this ) == array );
-}
-
-template< typename Value, typename Device, typename Index >
-MultiArray< 1, Value, Device, Index >&
-   MultiArray< 1, Value, Device, Index > :: operator = ( const MultiArray< 1, Value, Device, Index >& array )
-{
-   // TODO: Static assert on dimensions
-   TNL_ASSERT( this->getDimensions() == array. getDimensions(),
-              std::cerr << "You are attempting to assign two arrays with different dimensions." << std::endl
-                   << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl
-                   << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; );
-   Array< Value, Device, Index > :: operator = ( array );
-   return ( *this );
-}
-
-template< typename Value, typename Device, typename Index >
-   template< typename MultiArrayT >
-MultiArray< 1, Value, Device, Index >&
-   MultiArray< 1, Value, Device, Index > :: operator = ( const MultiArrayT& array )
-{
-   // TODO: Static assert on dimensions
-   TNL_ASSERT( this->getDimensions() == array. getDimensions(),
-              std::cerr << "You are attempting to assign two arrays with different dimensions." << std::endl
-                   << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl
-                   << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; );
-   Array< Value, Device, Index > :: operator = ( array );
-   return ( *this );
-}
-
-template< typename Value, typename Device, typename Index >
-bool MultiArray< 1, Value, Device, Index > :: save( File& file ) const
-{
-   if( ! Array< Value, Device, Index > :: save( file ) )
-   {
-      std::cerr << "I was not able to write the Array of MultiArray." << std::endl;
-      return false;
-   }
-   if( ! dimensions. save( file ) )
-   {
-      std::cerr << "I was not able to write the dimensions of MultiArray." << std::endl;
-      return false;
-   }
-   return true;
-}
-
-template< typename Value, typename Device, typename Index >
-bool MultiArray< 1, Value, Device, Index > :: load( File& file )
-{
-   if( ! Array< Value, Device, Index > :: load( file ) )
-   {
-      std::cerr << "I was not able to read the Array of MultiArray." << std::endl;
-      return false;
-   }
-   if( ! dimensions. load( file ) )
-   {
-      std::cerr << "I was not able to read the dimensions of MultiArray." << std::endl;
-      return false;
-   }
-   return true;
-}
-
-template< typename Value, typename Device, typename Index >
-bool MultiArray< 1, Value, Device, Index > :: save( const String& fileName ) const
-{
-   return Object :: save( fileName );
-}
-
-template< typename Value, typename Device, typename Index >
-bool MultiArray< 1, Value, Device, Index > :: load( const String& fileName )
-{
-   return Object :: load( fileName );
-}
-
-template< typename Value, typename Device, typename Index >
-std::ostream& operator << ( std::ostream& str, const MultiArray< 1, Value, Device, Index >& array )
-{
-   for( Index i = 0; i < array. getDimensions()[ 0 ]; i ++ )
-   {
-      str << array. getElement( i ) << " ";
-   }
-   return str;
-}
-
-} // namespace Containers
-} // namespace TNL
diff --git a/src/TNL/Containers/MultiArray2D_impl.h b/src/TNL/Containers/MultiArray2D_impl.h
deleted file mode 100644
index 44d860167968df549a63ed089cad38f9c0919881..0000000000000000000000000000000000000000
--- a/src/TNL/Containers/MultiArray2D_impl.h
+++ /dev/null
@@ -1,255 +0,0 @@
-/***************************************************************************
-                          MultiArray2D_impl.h  -  description
-                             -------------------
-    begin                : Nov 13, 2012
-    copyright            : (C) 2012 by Tomas Oberhuber
-    email                : tomas.oberhuber@fjfi.cvut.cz
- ***************************************************************************/
-
-/* See Copyright Notice in tnl/Copyright */
-
-#pragma once
-
-namespace TNL {
-namespace Containers {   
-
-template< typename Value, typename Device, typename Index >
-MultiArray< 2, Value, Device, Index > :: MultiArray()
-{
-}
-
-template< typename Value, typename Device, typename Index >
-String MultiArray< 2, Value, Device, Index > :: getType()
-{
-   return String( "Containers::MultiArray< ") +
-          String( Dimension ) +
-          String( ", " ) +
-          String( TNL::getType< Value >() ) +
-          String( ", " ) +
-          String( Device :: getDeviceType() ) +
-          String( ", " ) +
-          String( TNL::getType< Index >() ) +
-          String( " >" );
-}
-
-template< typename Value,
-          typename Device,
-          typename Index >
-String MultiArray< 2, Value, Device, Index > :: getTypeVirtual() const
-{
-   return this->getType();
-};
-
-template< typename Value,
-          typename Device,
-          typename Index >
-String MultiArray< 2, Value, Device, Index > :: getSerializationType()
-{
-   return HostType::getType();
-};
-
-template< typename Value,
-          typename Device,
-          typename Index >
-String MultiArray< 2, Value, Device, Index > :: getSerializationTypeVirtual() const
-{
-   return this->getSerializationType();
-};
-
-template< typename Value, typename Device, typename Index >
-void MultiArray< 2, Value, Device, Index > :: setDimensions( const Index jSize,
-                                                                  const Index iSize )
-{
-   TNL_ASSERT( iSize > 0 && jSize > 0,
-              std::cerr << "iSize = " << iSize
-                   << "jSize = " << jSize );
-
-   dimensions[ 0 ] = iSize;
-   dimensions[ 1 ] = jSize;
-   Array< Value, Device, Index > :: setSize( iSize * jSize );
-}
-
-template< typename Value, typename Device, typename Index >
-void MultiArray< 2, Value, Device, Index > :: setDimensions( const Containers::StaticVector< 2, Index >& dimensions )
-{
-   TNL_ASSERT( dimensions[ 0 ] > 0 && dimensions[ 1 ] > 0,
-              std::cerr << "dimensions = " << dimensions );
-   /****
-    * Swap the dimensions in the tuple to be compatible with the previous method.
-    */
-   this->dimensions. x() = dimensions. y();
-   this->dimensions. y() = dimensions. x();
-   Array< Value, Device, Index > :: setSize( this->dimensions[ 1 ] * this->dimensions[ 0 ] );
-}
-
-template< typename Value, typename Device, typename Index >
-   template< typename MultiArrayT >
-void MultiArray< 2, Value, Device, Index > :: setLike( const MultiArrayT& multiArray )
-{
-   setDimensions( multiArray. getDimensions() );
-}
-
-template< typename Value, typename Device, typename Index >
-void MultiArray< 2, Value, Device, Index >::reset()
-{
-   this->dimensions = Containers::StaticVector< 2, Index >( ( Index ) 0 );
-   Array< Value, Device, Index >::reset();
-}
-
-template< typename Value, typename Device, typename Index >
-__cuda_callable__
-void MultiArray< 2, Value, Device, Index > :: getDimensions( Index& jSize, Index& iSize ) const
-{
-   iSize = this->dimensions[ 0 ];
-   jSize = this->dimensions[ 1 ];
-}
-
-template< typename Value, typename Device, typename Index >
-__cuda_callable__
-const Containers::StaticVector< 2, Index >& MultiArray< 2, Value, Device, Index > :: getDimensions() const
-{
-   return this->dimensions;
-}
-
-template< typename Value, typename Device, typename Index >
-__cuda_callable__
-Index MultiArray< 2, Value, Device, Index > :: getElementIndex( const Index j, const Index i ) const
-{
-   TNL_ASSERT( i >= 0 && i < this->dimensions[ 0 ] && j >= 0 && j < this->dimensions[ 1 ],
-              std::cerr << "i = " << i << " j = " << j << " this->dimensions[ 0 ] = " <<  this->dimensions[ 0 ]
-                   << " this->dimensions[ 1 ] = " << this->dimensions[ 1 ] );
-   return j * this->dimensions[ 0 ] + i;
-}
-
-template< typename Value, typename Device, typename Index >
-Value MultiArray< 2, Value, Device, Index > :: getElement( const Index j, const Index i ) const
-{
-   return Array< Value, Device, Index > :: getElement( getElementIndex( j, i ) );
-}
-
-template< typename Value, typename Device, typename Index >
-void MultiArray< 2, Value, Device, Index > :: setElement( const Index j, const Index i, Value value )
-{
-   Array< Value, Device, Index > :: setElement( getElementIndex( j, i ), value );
-}
-
-template< typename Value, typename Device, typename Index >
-__cuda_callable__
-Value& MultiArray< 2, Value, Device, Index > :: operator()( const Index j, const Index i )
-{
-   return Array< Value, Device, Index > :: operator[]( getElementIndex( j, i ) );
-}
-
-template< typename Value, typename Device, typename Index >
-__cuda_callable__
-const Value& MultiArray< 2, Value, Device, Index > :: operator()( const Index j, const Index i ) const
-{
-   return Array< Value, Device, Index > :: operator[]( getElementIndex( j, i ) );
-}
-
-template< typename Value, typename Device, typename Index >
-   template< typename MultiArrayT >
-bool MultiArray< 2, Value, Device, Index > :: operator == ( const MultiArrayT& array ) const
-{
-   // TODO: Static assert on dimensions
-   TNL_ASSERT( this->getDimensions() == array. getDimensions(),
-              std::cerr << "You are attempting to compare two arrays with different dimensions." << std::endl
-                   << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl
-                   << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; );
-   return Array< Value, Device, Index > :: operator == ( array );
-}
-
-template< typename Value, typename Device, typename Index >
-   template< typename MultiArrayT >
-bool MultiArray< 2, Value, Device, Index > :: operator != ( const MultiArrayT& array ) const
-{
-   return ! ( (* this ) == array );
-}
-
-template< typename Value, typename Device, typename Index >
-MultiArray< 2, Value, Device, Index >&
-   MultiArray< 2, Value, Device, Index > :: operator = ( const MultiArray< 2, Value, Device, Index >& array )
-{
-   // TODO: Static assert on dimensions
-   TNL_ASSERT( this->getDimensions() == array. getDimensions(),
-              std::cerr << "You are attempting to assign two arrays with different dimensions." << std::endl
-                   << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl
-                   << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; );
-   Array< Value, Device, Index > :: operator = ( array );
-   return ( *this );
-}
-
-template< typename Value, typename Device, typename Index >
-   template< typename MultiArrayT >
-MultiArray< 2, Value, Device, Index >&
-   MultiArray< 2, Value, Device, Index > :: operator = ( const MultiArrayT& array )
-{
-   // TODO: Static assert on dimensions
-   TNL_ASSERT( this->getDimensions() == array. getDimensions(),
-              std::cerr << "You are attempting to assign two arrays with different dimensions." << std::endl
-                   << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl
-                   << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; );
-   Array< Value, Device, Index > :: operator = ( array );
-   return ( *this );
-}
-
-template< typename Value, typename Device, typename Index >
-bool MultiArray< 2, Value, Device, Index > :: save( File& file ) const
-{
-   if( ! Array< Value, Device, Index > :: save( file ) )
-   {
-      std::cerr << "I was not able to write the Array of MultiArray." << std::endl;
-      return false;
-   }
-   if( ! dimensions. save( file ) )
-   {
-      std::cerr << "I was not able to write the dimensions of MultiArray." << std::endl;
-      return false;
-   }
-   return true;
-}
-
-template< typename Value, typename Device, typename Index >
-bool MultiArray< 2, Value, Device, Index > :: load( File& file )
-{
-   if( ! Array< Value, Device, Index > :: load( file ) )
-   {
-      std::cerr << "I was not able to read the Array of MultiArray." << std::endl;
-      return false;
-   }
-   if( ! dimensions. load( file ) )
-   {
-      std::cerr << "I was not able to read the dimensions of MultiArray." << std::endl;
-      return false;
-   }
-   return true;
-}
-
-template< typename Value, typename Device, typename Index >
-bool MultiArray< 2, Value, Device, Index > :: save( const String& fileName ) const
-{
-   return Object :: save( fileName );
-}
-
-template< typename Value, typename Device, typename Index >
-bool MultiArray< 2, Value, Device, Index > :: load( const String& fileName )
-{
-   return Object :: load( fileName );
-}
-
-template< typename Value, typename Device, typename Index >
-std::ostream& operator << ( std::ostream& str, const MultiArray< 2, Value, Device, Index >& array )
-{
-   for( Index j = 0; j < array. getDimensions()[ 1 ]; j ++ )
-   {
-      for( Index i = 0; i < array. getDimensions()[ 0 ]; i ++ )
-      {
-         str << array. getElement( j, i ) << " ";
-      }
-      str << std::endl;
-   }
-   return str;
-}
-
-} // namespace Containers
-} // namespace TNL
diff --git a/src/TNL/Containers/MultiArray3D_impl.h b/src/TNL/Containers/MultiArray3D_impl.h
deleted file mode 100644
index 9dc3c031795b2e4c5b68fa093512f81911d1abc2..0000000000000000000000000000000000000000
--- a/src/TNL/Containers/MultiArray3D_impl.h
+++ /dev/null
@@ -1,271 +0,0 @@
-/***************************************************************************
-                          MultiArray3D_impl.h  -  description
-                             -------------------
-    begin                : Nov 13, 2012
-    copyright            : (C) 2012 by Tomas Oberhuber
-    email                : tomas.oberhuber@fjfi.cvut.cz
- ***************************************************************************/
-
-/* See Copyright Notice in tnl/Copyright */
-
-#pragma once
-
-namespace TNL {
-namespace Containers {   
-
-template< typename Value, typename Device, typename Index >
-MultiArray< 3, Value, Device, Index > :: MultiArray()
-{
-}
-
-template< typename Value, typename Device, typename Index >
-String MultiArray< 3, Value, Device, Index > :: getType()
-{
-   return String( "Containers::MultiArray< ") +
-          String( Dimension ) +
-          String( ", " ) +
-          String( TNL::getType< Value >() ) +
-          String( ", " ) +
-          String( Device :: getDeviceType() ) +
-          String( ", " ) +
-          String( TNL::getType< Index >() ) +
-          String( " >" );
-}
-
-template< typename Value,
-          typename Device,
-          typename Index >
-String MultiArray< 3, Value, Device, Index > :: getTypeVirtual() const
-{
-   return this->getType();
-};
-
-template< typename Value,
-          typename Device,
-          typename Index >
-String MultiArray< 3, Value, Device, Index > :: getSerializationType()
-{
-   return HostType::getType();
-};
-
-template< typename Value,
-          typename Device,
-          typename Index >
-String MultiArray< 3, Value, Device, Index > :: getSerializationTypeVirtual() const
-{
-   return this->getSerializationType();
-};
-
-template< typename Value, typename Device, typename Index >
-void MultiArray< 3, Value, Device, Index > :: setDimensions( const Index kSize,
-                                                                       const Index jSize,
-                                                                       const Index iSize )
-{
-   TNL_ASSERT( iSize > 0 && jSize > 0 && kSize > 0,
-              std::cerr << "iSize = " << iSize
-                   << "jSize = " << jSize
-                   << "kSize = " << kSize );
-
-   dimensions[ 0 ] = iSize;
-   dimensions[ 1 ] = jSize;
-   dimensions[ 2 ] = kSize;
-   Array< Value, Device, Index > :: setSize( iSize * jSize * kSize );
-}
-
-template< typename Value, typename Device, typename Index >
-void MultiArray< 3, Value, Device, Index > :: setDimensions( const Containers::StaticVector< 3, Index >& dimensions )
-{
-   TNL_ASSERT( dimensions[ 0 ] > 0 && dimensions[ 1 ] > 0 && dimensions[ 2 ],
-              std::cerr << "dimensions = " << dimensions );
-   /****
-    * Swap the dimensions in the tuple to be compatible with the previous method.
-    */
-   this->dimensions. x() = dimensions. z();
-   this->dimensions. y() = dimensions. y();
-   this->dimensions. z() = dimensions. x();
-   Array< Value, Device, Index > :: setSize( this->dimensions[ 2 ] *
-                                               this->dimensions[ 1 ] *
-                                               this->dimensions[ 0 ] );
-}
-
-template< typename Value, typename Device, typename Index >
-   template< typename MultiArrayT >
-void MultiArray< 3, Value, Device, Index > :: setLike( const MultiArrayT& multiArray )
-{
-   setDimensions( multiArray. getDimensions() );
-}
-
-template< typename Value, typename Device, typename Index >
-void MultiArray< 3, Value, Device, Index >::reset()
-{
-   this->dimensions = Containers::StaticVector< 3, Index >( ( Index ) 0 );
-   Array< Value, Device, Index >::reset();
-}
-
-template< typename Value, typename Device, typename Index >
-__cuda_callable__
-void MultiArray< 3, Value, Device, Index > :: getDimensions( Index& kSize,
-                                                                  Index& jSize,
-                                                                  Index& iSize ) const
-{
-   iSize = this->dimensions[ 0 ];
-   jSize = this->dimensions[ 1 ];
-   kSize = this->dimensions[ 2 ];
-}
-
-template< typename Value, typename Device, typename Index >
-__cuda_callable__
-const Containers::StaticVector< 3, Index >& MultiArray< 3, Value, Device, Index > :: getDimensions() const
-{
-   return this->dimensions;
-}
-
-template< typename Value, typename Device, typename Index >
-__cuda_callable__
-Index MultiArray< 3, Value, Device, Index > :: getElementIndex( const Index k,
-                                                                     const Index j,
-                                                                     const Index i ) const
-{
-   TNL_ASSERT( i >= 0 && i < this->dimensions[ 0 ] &&
-              j >= 0 && j < this->dimensions[ 1 ] &&
-              k >= 0 && k < this->dimensions[ 2 ],
-              std::cerr << " i = " << i
-                   << " j = " << j
-                   << " k = " << k
-                   << " this->dimensions = " << this->dimensions );
-   return ( k * this->dimensions[ 1 ]  + j ) * this->dimensions[ 0 ] + i;
-}
-
-template< typename Value, typename Device, typename Index >
-Value MultiArray< 3, Value, Device, Index > :: getElement( const Index k,
-                                                                  const Index j,
-                                                                  const Index i ) const
-{
-   return Array< Value, Device, Index > :: getElement( getElementIndex( k, j, i ) );
-}
-
-template< typename Value, typename Device, typename Index >
-void MultiArray< 3, Value, Device, Index > :: setElement( const Index k,
-                                                                    const Index j,
-                                                                    const Index i, Value value )
-{
-   Array< Value, Device, Index > :: setElement( getElementIndex( k, j, i ), value );
-}
-
-
-template< typename Value, typename Device, typename Index >
-__cuda_callable__
-Value& MultiArray< 3, Value, Device, Index > :: operator()( const Index k,
-                                                                        const Index j,
-                                                                        const Index i )
-{
-   return Array< Value, Device, Index > :: operator[]( getElementIndex( k, j, i ) );
-}
-
-template< typename Value, typename Device, typename Index >
-__cuda_callable__
-const Value& MultiArray< 3, Value, Device, Index > :: operator()( const Index k,
-                                                                               const Index j,
-                                                                               const Index i ) const
-{
-   return Array< Value, Device, Index > :: operator[]( getElementIndex( k, j, i ) );
-}
-
-template< typename Value, typename Device, typename Index >
-   template< typename MultiArrayT >
-bool MultiArray< 3, Value, Device, Index > :: operator == ( const MultiArrayT& array ) const
-{
-   // TODO: Static assert on dimensions
-   TNL_ASSERT( this->getDimensions() == array. getDimensions(),
-              std::cerr << "You are attempting to compare two arrays with different dimensions." << std::endl
-                   << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl
-                   << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; );
-   return Array< Value, Device, Index > :: operator == ( array );
-}
-
-template< typename Value, typename Device, typename Index >
-   template< typename MultiArrayT >
-bool MultiArray< 3, Value, Device, Index > :: operator != ( const MultiArrayT& array ) const
-{
-   return ! ( (* this ) == array );
-}
-
-template< typename Value, typename Device, typename Index >
-MultiArray< 3, Value, Device, Index >&
-   MultiArray< 3, Value, Device, Index > :: operator = ( const MultiArray< 3, Value, Device, Index >& array )
-{
-   // TODO: Static assert on dimensions
-   TNL_ASSERT( this->getDimensions() == array. getDimensions(),
-              std::cerr << "You are attempting to assign two arrays with different dimensions." << std::endl
-                   << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl
-                   << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; );
-   Array< Value, Device, Index > :: operator = ( array );
-   return ( *this );
-}
-
-template< typename Value, typename Device, typename Index >
-   template< typename MultiArrayT >
-MultiArray< 3, Value, Device, Index >&
-   MultiArray< 3, Value, Device, Index > :: operator = ( const MultiArrayT& array )
-{
-   // TODO: Static assert on dimensions
-   TNL_ASSERT( this->getDimensions() == array. getDimensions(),
-              std::cerr << "You are attempting to assign two arrays with different dimensions." << std::endl
-                   << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl
-                   << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; );
-   Array< Value, Device, Index > :: operator = ( array );
-   return ( *this );
-}
-
-template< typename Value, typename Device, typename Index >
-bool MultiArray< 3, Value, Device, Index > :: save( File& file ) const
-{
-   if( ! Array< Value, Device, Index > :: save( file ) )
-   {
-      std::cerr << "I was not able to write the Array of MultiArray." << std::endl;
-      return false;
-   }
-   if( ! dimensions. save( file ) )
-   {
-      std::cerr << "I was not able to write the dimensions of MultiArray." << std::endl;
-      return false;
-   }
-   return true;
-}
-
-template< typename Value, typename Device, typename Index >
-bool MultiArray< 3, Value, Device, Index > :: load( File& file )
-{
-   if( ! Array< Value, Device, Index > :: load( file ) )
-   {
-      std::cerr << "I was not able to read the Array of MultiArray." << std::endl;
-      return false;
-   }
-   if( ! dimensions. load( file ) )
-   {
-      std::cerr << "I was not able to read the dimensions of MultiArray." << std::endl;
-      return false;
-   }
-   return true;
-}
-
-template< typename Value, typename Device, typename Index >
-std::ostream& operator << ( std::ostream& str, const MultiArray< 3, Value, Device, Index >& array )
-{
-   for( Index k = 0; k < array. getDimensions()[ 2 ]; k ++ )
-   {
-      for( Index j = 0; j < array. getDimensions()[ 1 ]; j ++ )
-      {
-         for( Index i = 0; i < array. getDimensions()[ 0 ]; i ++ )
-         {
-            str << array. getElement( k, j, i ) << " ";
-         }
-         str << std::endl;
-      }
-      str << std::endl;
-   }
-   return str;
-}
-
-} // namespace Containers
-} // namespace TNL
diff --git a/src/TNL/Containers/MultiArray4D_impl.h b/src/TNL/Containers/MultiArray4D_impl.h
deleted file mode 100644
index 2b35c1caaf5180645ca1999f69b08a6458cfe4c3..0000000000000000000000000000000000000000
--- a/src/TNL/Containers/MultiArray4D_impl.h
+++ /dev/null
@@ -1,290 +0,0 @@
-/***************************************************************************
-                          MultiArray4D_impl.h  -  description
-                             -------------------
-    begin                : Nov 13, 2012
-    copyright            : (C) 2012 by Tomas Oberhuber
-    email                : tomas.oberhuber@fjfi.cvut.cz
- ***************************************************************************/
-
-/* See Copyright Notice in tnl/Copyright */
-
-#pragma once
-
-namespace TNL {
-namespace Containers {   
-   
-
-template< typename Value, typename Device, typename Index >
-MultiArray< 4, Value, Device, Index > :: MultiArray()
-{
-}
-
-template< typename Value, typename Device, typename Index >
-String MultiArray< 4, Value, Device, Index > :: getType()
-{
-   return String( "Containers::MultiArray< ") +
-          String( Dimension ) +
-          String( ", " ) +
-          String( TNL::getType< Value >() ) +
-          String( ", " ) +
-          String( Device :: getDeviceType() ) +
-          String( ", " ) +
-          String( TNL::getType< Index >() ) +
-          String( " >" );
-}
-
-template< typename Value,
-          typename Device,
-          typename Index >
-String MultiArray< 4, Value, Device, Index > :: getTypeVirtual() const
-{
-   return this->getType();
-};
-
-template< typename Value,
-          typename Device,
-          typename Index >
-String MultiArray< 4, Value, Device, Index > :: getSerializationType()
-{
-   return HostType::getType();
-};
-
-template< typename Value,
-          typename Device,
-          typename Index >
-String MultiArray< 4, Value, Device, Index > :: getSerializationTypeVirtual() const
-{
-   return this->getSerializationType();
-};
-
-template< typename Value, typename Device, typename Index >
-void MultiArray< 4, Value, Device, Index > :: setDimensions( const Index lSize,
-                                                                       const Index kSize,
-                                                                       const Index jSize,
-                                                                       const Index iSize )
-{
-   TNL_ASSERT( iSize > 0 && jSize > 0 && kSize > 0 && lSize > 0,
-              std::cerr << "iSize = " << iSize
-                   << "jSize = " << jSize
-                   << "kSize = " << kSize
-                   << "lSize = " << lSize );
-
-   dimensions[ 0 ] = iSize;
-   dimensions[ 1 ] = jSize;
-   dimensions[ 2 ] = kSize;
-   dimensions[ 3 ] = lSize;
-   Array< Value, Device, Index > :: setSize( iSize * jSize * kSize * lSize );
-}
-
-template< typename Value, typename Device, typename Index >
-void MultiArray< 4, Value, Device, Index > :: setDimensions( const Containers::StaticVector< 4, Index >& dimensions )
-{
-   TNL_ASSERT( dimensions[ 0 ] > 0 && dimensions[ 1 ] > 0 && dimensions[ 2 ] && dimensions[ 3 ] > 0,
-              std::cerr << "dimensions = " << dimensions );
-   /****
-    * Swap the dimensions in the tuple to be compatible with the previous method.
-    */
-   this->dimensions[ 0 ] = dimensions[ 3 ];
-   this->dimensions[ 1 ] = dimensions[ 2 ];
-   this->dimensions[ 2 ] = dimensions[ 1 ];
-   this->dimensions[ 3 ] = dimensions[ 0 ];
-   Array< Value, Device, Index > :: setSize( this->dimensions[ 3 ] *
-                                               this->dimensions[ 2 ] *
-                                               this->dimensions[ 1 ] *
-                                               this->dimensions[ 0 ] );
-}
-
-template< typename Value, typename Device, typename Index >
-   template< typename MultiArrayT >
-void MultiArray< 4, Value, Device, Index > :: setLike( const MultiArrayT& multiArray )
-{
-   setDimensions( multiArray. getDimensions() );
-}
-
-template< typename Value, typename Device, typename Index >
-void MultiArray< 4, Value, Device, Index >::reset()
-{
-   this->dimensions = Containers::StaticVector< 4, Index >( ( Index ) 0 );
-   Array< Value, Device, Index >::reset();
-}
-
-template< typename Value, typename Device, typename Index >
-__cuda_callable__
-void MultiArray< 4, Value, Device, Index > :: getDimensions( Index& lSize,
-                                                                       Index& kSize,
-                                                                       Index& jSize,
-                                                                       Index& iSize ) const
-{
-   iSize = this->dimensions[ 0 ];
-   jSize = this->dimensions[ 1 ];
-   kSize = this->dimensions[ 2 ];
-   lSize = this->dimensions[ 3 ];
-}
-
-template< typename Value, typename Device, typename Index >
-__cuda_callable__
-const Containers::StaticVector< 4, Index >& MultiArray< 4, Value, Device, Index > :: getDimensions() const
-{
-   return this->dimensions;
-}
-
-template< typename Value, typename Device, typename Index >
-__cuda_callable__
-Index MultiArray< 4, Value, Device, Index > :: getElementIndex( const Index l,
-                                                                     const Index k,
-                                                                     const Index j,
-                                                                     const Index i ) const
-{
-   TNL_ASSERT( i >= 0 && i < this->dimensions[ 0 ] &&
-              j >= 0 && j < this->dimensions[ 1 ] &&
-              k >= 0 && k < this->dimensions[ 2 ] &&
-              l >= 0 && l < this->dimensions[ 3 ],
-              std::cerr << " i = " << i
-                   << " j = " << j
-                   << " k = " << k
-                   << " l = " << l
-                   << " this->dimensions = " << this->dimensions );
-   return ( ( l * this->dimensions[ 2 ] + k ) * this->dimensions[ 1 ]  + j ) * this->dimensions[ 0 ] + i;
-}
-
-template< typename Value, typename Device, typename Index >
-Value MultiArray< 4, Value, Device, Index > :: getElement( const Index l,
-                                                                       const Index k,
-                                                                       const Index j,
-                                                                       const Index i ) const
-{
-   return Array< Value, Device, Index > :: getElement( getElementIndex( l, k, j, i ) );
-}
-
-template< typename Value, typename Device, typename Index >
-void MultiArray< 4, Value, Device, Index > :: setElement( const Index l,
-                                                                    const Index k,
-                                                                    const Index j,
-                                                                    const Index i, Value value )
-{
-   Array< Value, Device, Index > :: setElement( getElementIndex( l, k, j, i ), value );
-}
-
-
-template< typename Value, typename Device, typename Index >
-__cuda_callable__
-Value& MultiArray< 4, Value, Device, Index > :: operator()( const Index l,
-                                                                        const Index k,
-                                                                        const Index j,
-                                                                        const Index i )
-{
-   return Array< Value, Device, Index > :: operator[]( getElementIndex( l, k, j, i ) );
-}
-
-template< typename Value, typename Device, typename Index >
-__cuda_callable__
-const Value& MultiArray< 4, Value, Device, Index > :: operator()( const Index l,
-                                                                               const Index k,
-                                                                               const Index j,
-                                                                               const Index i ) const
-{
-   return Array< Value, Device, Index > :: operator[]( getElementIndex( l, k, j, i ) );
-}
-
-template< typename Value, typename Device, typename Index >
-   template< typename MultiArrayT >
-bool MultiArray< 4, Value, Device, Index > :: operator == ( const MultiArrayT& array ) const
-{
-   // TODO: Static assert on dimensions
-   TNL_ASSERT( this->getDimensions() == array. getDimensions(),
-              std::cerr << "You are attempting to compare two arrays with different dimensions." << std::endl
-                   << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl
-                   << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; );
-   return Array< Value, Device, Index > :: operator == ( array );
-}
-
-template< typename Value, typename Device, typename Index >
-   template< typename MultiArrayT >
-bool MultiArray< 4, Value, Device, Index > :: operator != ( const MultiArrayT& array ) const
-{
-   return ! ( (* this ) == array );
-}
-
-template< typename Value, typename Device, typename Index >
-MultiArray< 4, Value, Device, Index >&
-   MultiArray< 4, Value, Device, Index > :: operator = ( const MultiArray< 4, Value, Device, Index >& array )
-{
-   // TODO: Static assert on dimensions
-   TNL_ASSERT( this->getDimensions() == array. getDimensions(),
-              std::cerr << "You are attempting to assign two arrays with different dimensions." << std::endl
-                   << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl
-                   << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; );
-   Array< Value, Device, Index > :: operator = ( array );
-   return ( *this );
-}
-
-template< typename Value, typename Device, typename Index >
-   template< typename MultiArrayT >
-MultiArray< 4, Value, Device, Index >&
-   MultiArray< 4, Value, Device, Index > :: operator = ( const MultiArrayT& array )
-{
-   // TODO: Static assert on dimensions
-   TNL_ASSERT( this->getDimensions() == array. getDimensions(),
-              std::cerr << "You are attempting to assign two arrays with different dimensions." << std::endl
-                   << "First array dimensions are ( " << this->getDimensions() << " )" << std::endl
-                   << "Second array dimensions are ( " << array. getDimensions() << " )" << std::endl; );
-   Array< Value, Device, Index > :: operator = ( array );
-   return ( *this );
-}
-
-template< typename Value, typename Device, typename Index >
-bool MultiArray< 4, Value, Device, Index > :: save( File& file ) const
-{
-   if( ! Array< Value, Device, Index > :: save( file ) )
-   {
-      std::cerr << "I was not able to write the Array of MultiArray." << std::endl;
-      return false;
-   }
-   if( ! dimensions. save( file ) )
-   {
-      std::cerr << "I was not able to write the dimensions of MultiArray." << std::endl;
-      return false;
-   }
-   return true;
-}
-
-template< typename Value, typename Device, typename Index >
-bool MultiArray< 4, Value, Device, Index > :: load( File& file )
-{
-   if( ! Array< Value, Device, Index > :: load( file ) )
-   {
-      std::cerr << "I was not able to read the Array of MultiArray." << std::endl;
-      return false;
-   }
-   if( ! dimensions. load( file ) )
-   {
-      std::cerr << "I was not able to read the dimensions of MultiArray." << std::endl;
-      return false;
-   }
-   return true;
-}
-
-template< typename Value, typename Device, typename Index >
-std::ostream& operator << ( std::ostream& str, const MultiArray< 4, Value, Device, Index >& array )
-{
-   for( Index l = 0; l < array. getDimensions()[ 3 ]; l ++ )
-   {
-      for( Index k = 0; k < array. getDimensions()[ 2 ]; k ++ )
-      {
-         for( Index j = 0; j < array. getDimensions()[ 1 ]; j ++ )
-         {
-            for( Index i = 0; i < array. getDimensions()[ 0 ]; i ++ )
-            {
-               str << array. getElement( l, k, j, i ) << " ";
-            }
-            str << std::endl;
-         }
-         str << std::endl;
-      }
-      str << std::endl;
-   }
-   return str;
-}
-
-} // namespace Containers
-} // namespace TNL
diff --git a/src/TNL/Containers/MultiVector.h b/src/TNL/Containers/MultiVector.h
deleted file mode 100644
index aa30db976ac35087ae1648c898695fb208e5abbc..0000000000000000000000000000000000000000
--- a/src/TNL/Containers/MultiVector.h
+++ /dev/null
@@ -1,369 +0,0 @@
-/***************************************************************************
-                          MultiVector.h  -  description
-                             -------------------
-    begin                : Nov 25, 2010
-    copyright            : (C) 2010 by Tomas Oberhuber
-    email                : tomas.oberhuber@fjfi.cvut.cz
- ***************************************************************************/
-
-/* See Copyright Notice in tnl/Copyright */
-
-#pragma once 
-
-#include <TNL/Containers/Vector.h>
-#include <TNL/Containers/StaticVector.h>
-#include <TNL/Assert.h>
-
-namespace TNL {
-namespace Containers {   
-   
-template< int Dimension, typename Real = double, typename Device = Devices::Host, typename Index = int >
-class MultiVector : public Vector< Real, Device, Index >
-{
-};
-
-template< typename Real, typename Device, typename Index >
-class MultiVector< 1, Real, Device, Index > : public Vector< Real, Device, Index >
-{
-   public:
-   enum { Dimension = 1};
-   typedef Real RealType;
-   typedef Device DeviceType;
-   typedef Index IndexType;
-   typedef MultiVector< Dimension, Real, Devices::Host, Index > HostType;
-   typedef MultiVector< Dimension, Real, Devices::Cuda, Index > CudaType;
-
-   MultiVector();
-
-   MultiVector( const String& name );
-
-   static String getType();
-
-   virtual String getTypeVirtual() const;
-
-   static String getSerializationType();
-
-   virtual String getSerializationTypeVirtual() const;
-
-   void setDimensions( const Index iSize );
-
-   void setDimensions( const StaticVector< Dimension, Index >& dimensions );
-
-   void getDimensions( Index& iSize ) const;
-
-   const StaticVector< 1, Index >& getDimensions() const;
-
-   //! Set dimensions of the Vector using another Vector as a template
-   template< typename MultiVector >
-   void setLike( const MultiVector& v );
- 
-   Index getElementIndex( const Index i ) const;
-
-   void setElement( const Index i, Real value );
-
-   //! This method can be used for general access to the elements of the Vectors.
-   /*! It does not return reference but value. So it can be used to access
-    *  Vectors in different adress space (usualy GPU device).
-    *  See also operator().
-    */
-   Real getElement( const Index i ) const;
-
-   //! Operator for accessing elements of the Vector.
-   /*! It returns reference to given elements so it cannot be
-    *  used to access elements of Vectors in different adress space
-    *  (GPU device usualy).
-    */
-   Real& operator()( const Index i );
-
-   const Real& operator()( const Index i ) const;
-
-   template< typename MultiVector >
-   bool operator == ( const MultiVector& Vector ) const;
-
-   template< typename MultiVector >
-   bool operator != ( const MultiVector& Vector ) const;
-
-   MultiVector< 1, Real, Device, Index >& operator = ( const MultiVector< 1, Real, Device, Index >& Vector );
-
-   template< typename MultiVectorT >
-   MultiVector< 1, Real, Device, Index >& operator = ( const MultiVectorT& Vector );
-
-   //! Method for saving the object to a file as a binary data
-   bool save( File& file ) const;
-
-   //! Method for restoring the object from a file
-   bool load( File& file );
-
-   bool save( const String& fileName ) const;
-
-   bool load( const String& fileName );
-
-   protected:
-
-   StaticVector< Dimension, Index > dimensions;
-};
-
-template< typename Real, typename Device, typename Index >
-class MultiVector< 2, Real, Device, Index > : public Vector< Real, Device, Index >
-{
-   public:
-   enum { Dimension = 2 };
-   typedef Real RealType;
-   typedef Device DeviceType;
-   typedef Index IndexType;
-   typedef MultiVector< Dimension, Real, Devices::Host, Index > HostType;
-   typedef MultiVector< Dimension, Real, Devices::Cuda, Index > CudaType;
-
-   MultiVector();
-
-   MultiVector( const String& name );
-
-   static String getType();
-
-   virtual String getTypeVirtual() const;
-
-   static String getSerializationType();
-
-   virtual String getSerializationTypeVirtual() const;
-
-   void setDimensions( const Index jSize, const Index iSize );
-
-   void setDimensions( const StaticVector< 2, Index >& dimensions );
-
-   void getDimensions( Index& jSize, Index& iSize ) const;
-
-   const StaticVector< 2, Index >& getDimensions() const;
-
-   //! Set dimensions of the Vector using another Vector as a template
-   template< typename MultiVector >
-   void setLike( const MultiVector& v );
-
-   Index getElementIndex( const Index j, const Index i ) const;
-
-   void setElement( const Index j, const Index i, Real value );
-
-   //! This method can be used for general access to the elements of the Vectors.
-   /*! It does not return reference but value. So it can be used to access
-    *  Vectors in different adress space (usualy GPU device).
-    *  See also operator().
-    */
-   Real getElement( const Index j, const Index i ) const;
-
-   //! Operator for accessing elements of the Vector.
-   /*! It returns reference to given elements so it cannot be
-    *  used to access elements of Vectors in different adress space
-    *  (GPU device usualy).
-    */
-   Real& operator()( const Index j, const Index i );
-
-   const Real& operator()( const Index j, const Index i ) const;
-
-   template< typename MultiVector >
-   bool operator == ( const MultiVector& Vector ) const;
-
-   template< typename MultiVector >
-   bool operator != ( const MultiVector& Vector ) const;
-
-   MultiVector< 2, Real, Device, Index >& operator = ( const MultiVector< 2, Real, Device, Index >& Vector );
-
-   template< typename MultiVectorT >
-   MultiVector< 2, Real, Device, Index >& operator = ( const MultiVectorT& Vector );
-
-   //! Method for saving the object to a file as a binary data
-   bool save( File& file ) const;
-
-   //! Method for restoring the object from a file
-   bool load( File& file );
-
-   bool save( const String& fileName ) const;
-
-   bool load( const String& fileName );
-
-   protected:
-
-   StaticVector< 2, Index > dimensions;
-};
-
-template< typename Real, typename Device, typename Index >
-class MultiVector< 3, Real, Device, Index > : public Vector< Real, Device, Index >
-{
-   public:
-
-   enum { Dimension = 3 };
-   typedef Real RealType;
-   typedef Device DeviceType;
-   typedef Index IndexType;
-   typedef MultiVector< Dimension, Real, Devices::Host, Index > HostType;
-   typedef MultiVector< Dimension, Real, Devices::Cuda, Index > CudaType;
-
-   MultiVector();
-
-   MultiVector( const String& name );
-
-   static String getType();
-
-   virtual String getTypeVirtual() const;
-
-   static String getSerializationType();
-
-   virtual String getSerializationTypeVirtual() const;
-
-   void setDimensions( const Index k, const Index j, const Index iSize );
-
-   void setDimensions( const StaticVector< 3, Index >& dimensions );
-
-   void getDimensions( Index& k, Index& j, Index& iSize ) const;
-
-   const StaticVector< 3, Index >& getDimensions() const;
-
-   //! Set dimensions of the Vector using another Vector as a template
-   template< typename MultiVector >
-   void setLike( const MultiVector& v );
-
-   Index getElementIndex( const Index k, const Index j, const Index i ) const;
-
-   void setElement( const Index k, const Index j, const Index i, Real value );
-
-   //! This method can be used for general access to the elements of the Vectors.
-   /*! It does not return reference but value. So it can be used to access
-    *  Vectors in different adress space (usualy GPU device).
-    *  See also operator().
-    */
-   Real getElement( const Index k, const Index j, const Index i ) const;
-
-   //! Operator for accessing elements of the Vector.
-   /*! It returns reference to given elements so it cannot be
-    *  used to access elements of Vectors in different adress space
-    *  (GPU device usualy).
-    */
-   Real& operator()( const Index k, const Index j, const Index i );
-
-   const Real& operator()( const Index k, const Index j, const Index i ) const;
-
-   template< typename MultiVector >
-   bool operator == ( const MultiVector& Vector ) const;
-
-   template< typename MultiVector >
-   bool operator != ( const MultiVector& Vector ) const;
-
-   MultiVector< 3, Real, Device, Index >& operator = ( const MultiVector< 3, Real, Device, Index >& Vector );
-
-   template< typename MultiVectorT >
-   MultiVector< 3, Real, Device, Index >& operator = ( const MultiVectorT& Vector );
-
-   //! Method for saving the object to a file as a binary data
-   bool save( File& file ) const;
-
-   //! Method for restoring the object from a file
-   bool load( File& file );
-
-   bool save( const String& fileName ) const;
-
-   bool load( const String& fileName );
-
-   protected:
-
-   StaticVector< 3, Index > dimensions;
-};
-
-template< typename Real, typename Device, typename Index >
-class MultiVector< 4, Real, Device, Index > : public Vector< Real, Device, Index >
-{
-   public:
-
-   enum { Dimension = 4 };
-   typedef Real RealType;
-   typedef Device DeviceType;
-   typedef Index IndexType;
-   typedef MultiVector< Dimension, Real, Devices::Host, Index > HostType;
-   typedef MultiVector< Dimension, Real, Devices::Cuda, Index > CudaType;
-
-   MultiVector();
-
-   MultiVector( const String& name );
-
-   static String getType();
-
-   virtual String getTypeVirtual() const;
-
-   static String getSerializationType();
-
-   virtual String getSerializationTypeVirtual() const;
-
-   void setDimensions( const Index l, const Index k, const Index j, const Index iSize );
-
-   void setDimensions( const StaticVector< 4, Index >& dimensions );
-
-   void getDimensions( Index& l, Index& k, Index& j, Index& iSize ) const;
-
-   const StaticVector< 4, Index >& getDimensions() const;
-
-   //! Set dimensions of the Vector using another Vector as a template
-   template< typename MultiVector >
-   void setLike( const MultiVector& v );
-
-   Index getElementIndex( const Index l, const Index k, const Index j, const Index i ) const;
-
-   void setElement( const Index l, const Index k, const Index j, const Index i, Real value );
-
-   //! This method can be used for general access to the elements of the Vectors.
-   /*! It does not return reference but value. So it can be used to access
-    *  Vectors in different adress space (usualy GPU device).
-    *  See also operator().
-    */
-   Real getElement( const Index l, const Index k, const Index j, const Index i ) const;
-
-   //! Operator for accessing elements of the Vector.
-   /*! It returns reference to given elements so it cannot be
-    *  used to access elements of Vectors in different adress space
-    *  (GPU device usualy).
-    */
-   Real& operator()( const Index l, const Index k, const Index j, const Index i );
-
-   const Real& operator()( const Index l, const Index k, const Index j, const Index i ) const;
-
-   template< typename MultiVector >
-   bool operator == ( const MultiVector& Vector ) const;
-
-   template< typename MultiVector >
-   bool operator != ( const MultiVector& Vector ) const;
-
-   MultiVector< 4, Real, Device, Index >& operator = ( const MultiVector< 4, Real, Device, Index >& Vector );
-
-   template< typename MultiVectorT >
-   MultiVector< 4, Real, Device, Index >& operator = ( const MultiVectorT& Vector );
-
-   //! Method for saving the object to a file as a binary data
-   bool save( File& file ) const;
-
-   //! Method for restoring the object from a file
-   bool load( File& file );
-
-   bool save( const String& fileName ) const;
-
-   bool load( const String& fileName );
-
-   protected:
-
-   StaticVector< 4, Index > dimensions;
-};
-
-template< typename Real, typename device, typename Index >
-std::ostream& operator << ( std::ostream& str, const MultiVector< 1, Real, device, Index >& Vector );
-
-template< typename Real, typename device, typename Index >
-std::ostream& operator << ( std::ostream& str, const MultiVector< 2, Real, device, Index >& Vector );
-
-template< typename Real, typename device, typename Index >
-std::ostream& operator << ( std::ostream& str, const MultiVector< 3, Real, device, Index >& Vector );
-
-template< typename Real, typename device, typename Index >
-std::ostream& operator << ( std::ostream& str, const MultiVector< 4, Real, device, Index >& Vector );
-
-} // namespace Containers
-} // namespace TNL
-
-#include <TNL/Containers/MultiVector1D_impl.h>
-#include <TNL/Containers/MultiVector2D_impl.h>
-#include <TNL/Containers/MultiVector3D_impl.h>
-#include <TNL/Containers/MultiVector4D_impl.h>
diff --git a/src/TNL/Containers/MultiVector1D_impl.h b/src/TNL/Containers/MultiVector1D_impl.h
deleted file mode 100644
index 5ac452c2929a5717d37d726aa1778bf13db77921..0000000000000000000000000000000000000000
--- a/src/TNL/Containers/MultiVector1D_impl.h
+++ /dev/null
@@ -1,231 +0,0 @@
-/***************************************************************************
-                          MultiVector1D_impl.h  -  description
-                             -------------------
-    begin                : Nov 13, 2012
-    copyright            : (C) 2012 by Tomas Oberhuber
-    email                : tomas.oberhuber@fjfi.cvut.cz
- ***************************************************************************/
-
-/* See Copyright Notice in tnl/Copyright */
-
-#pragma once
-
-namespace TNL {
-namespace Containers {   
-
-template< typename Real, typename Device, typename Index >
-MultiVector< 1, Real, Device, Index > :: MultiVector()
-{
-}
-
-template< typename Real, typename Device, typename Index >
-String MultiVector< 1, Real, Device, Index > :: getType()
-{
-   return String( "Containers::MultiVector< ") +
-          convertToString( Dimension ) +
-          String( ", " ) +
-          String( TNL::getType< Real >() ) +
-          String( ", " ) +
-          String( Device :: getDeviceType() ) +
-          String( ", " ) +
-          String( TNL::getType< Index >() ) +
-          String( " >" );
-}
-
-template< typename Real,
-          typename Device,
-          typename Index >
-String MultiVector< 1, Real, Device, Index > :: getTypeVirtual() const
-{
-   return this->getType();
-};
-
-template< typename Real,
-          typename Device,
-          typename Index >
-String MultiVector< 1, Real, Device, Index > :: getSerializationType()
-{
-   return HostType::getType();
-};
-
-template< typename Real,
-          typename Device,
-          typename Index >
-String MultiVector< 1, Real, Device, Index > :: getSerializationTypeVirtual() const
-{
-   return this->getSerializationType();
-};
-
-template< typename Real, typename Device, typename Index >
-void MultiVector< 1, Real, Device, Index > :: setDimensions( const Index iSize )
-{
-   TNL_ASSERT( iSize > 0,
-              std::cerr << "iSize = " << iSize );
-   dimensions[ 0 ] = iSize;
-   Vector< Real, Device, Index > :: setSize( iSize );
-}
-
-template< typename Real, typename Device, typename Index >
-void MultiVector< 1, Real, Device, Index > :: setDimensions( const StaticVector< Dimension, Index >& dimensions )
-{
-   TNL_ASSERT( dimensions[ 0 ] > 0,
-              std::cerr << " dimensions[ 0 ] = " << dimensions[ 0 ] );
-   this->dimensions = dimensions;
-   Vector< Real, Device, Index > :: setSize( this->dimensions[ 0 ] );
-}
-
-template< typename Real, typename Device, typename Index >
-   template< typename MultiVectorT >
-void MultiVector< 1, Real, Device, Index > :: setLike( const MultiVectorT& multiVector )
-{
-   setDimensions( multiVector. getDimensions() );
-}
-
-template< typename Real, typename Device, typename Index >
-void MultiVector< 1, Real, Device, Index > :: getDimensions( Index& xSize ) const
-{
-   xSize = this->dimensions[ 0 ];
-}
-
-template< typename Real, typename Device, typename Index >
-const StaticVector< 1, Index >& MultiVector< 1, Real, Device, Index > :: getDimensions() const
-{
-   return this->dimensions;
-}
-
-template< typename Real, typename Device, typename Index >
-Index MultiVector< 1, Real, Device, Index > :: getElementIndex( const Index i ) const
-{
-   TNL_ASSERT( i >= 0 && i < this->dimensions[ 0 ],
-              std::cerr << "i = " << i
-                   << "this->dimensions[ 0 ] " << this->dimensions[ 0 ] );
-   return i;
-}
-
-template< typename Real, typename Device, typename Index >
-Real MultiVector< 1, Real, Device, Index > :: getElement( const Index i ) const
-{
-   return Vector< Real, Device, Index > :: getElement( getElementIndex( i ) );
-}
-
-template< typename Real, typename Device, typename Index >
-void MultiVector< 1, Real, Device, Index > :: setElement( const Index i, Real value )
-{
-   Vector< Real, Device, Index > :: setElement( getElementIndex( i ), value );
-}
-
-
-template< typename Real, typename Device, typename Index >
-Real& MultiVector< 1, Real, Device, Index > :: operator()( const Index element )
-{
-   return Vector< Real, Device, Index > :: operator[]( getElementIndex( element ) );
-}
-
-template< typename Real, typename Device, typename Index >
-const Real& MultiVector< 1, Real, Device, Index > :: operator()( const Index element ) const
-{
-   return Vector< Real, Device, Index > :: operator[]( getElementIndex( element ) );
-}
-
-template< typename Real, typename Device, typename Index >
-   template< typename MultiVectorT >
-bool MultiVector< 1, Real, Device, Index > :: operator == ( const MultiVectorT& vector ) const
-{
-   // TODO: Static assert on dimensions
-   TNL_ASSERT( this->getDimensions() == vector. getDimensions(),
-              std::cerr << "You are attempting to compare two Vectors with different dimensions." << std::endl
-                   << "First Vector name dimensions are ( " << this->getDimensions() << " )" << std::endl
-                   << "Second Vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; );
-   return Vector< Real, Device, Index > :: operator == ( vector );
-}
-
-template< typename Real, typename Device, typename Index >
-   template< typename MultiVectorT >
-bool MultiVector< 1, Real, Device, Index > :: operator != ( const MultiVectorT& vector ) const
-{
-   return ! ( (* this ) == vector );
-}
-
-template< typename Real, typename Device, typename Index >
-MultiVector< 1, Real, Device, Index >&
-   MultiVector< 1, Real, Device, Index > :: operator = ( const MultiVector< 1, Real, Device, Index >& vector )
-{
-   // TODO: Static assert on dimensions
-   TNL_ASSERT( this->getDimensions() == vector. getDimensions(),
-              std::cerr << "You are attempting to assign two Vectors with different dimensions." << std::endl
-                   << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl
-                   << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; );
-   Vector< Real, Device, Index > :: operator = ( vector );
-   return ( *this );
-}
-
-template< typename Real, typename Device, typename Index >
-   template< typename MultiVectorT >
-MultiVector< 1, Real, Device, Index >&
-   MultiVector< 1, Real, Device, Index > :: operator = ( const MultiVectorT& vector )
-{
-   // TODO: Static assert on dimensions
-   TNL_ASSERT( this->getDimensions() == vector. getDimensions(),
-              std::cerr << "You are attempting to assign two Vectors with different dimensions." << std::endl
-                   << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl
-                   << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; );
-   Vector< Real, Device, Index > :: operator = ( vector );
-   return ( *this );
-}
-
-template< typename Real, typename Device, typename Index >
-bool MultiVector< 1, Real, Device, Index > :: save( File& file ) const
-{
-   if( ! Vector< Real, Device, Index > :: save( file ) )
-   {
-      std::cerr << "I was not able to write the Vector of MultiVector." << std::endl;
-      return false;
-   }
-   if( ! dimensions. save( file ) )
-   {
-      std::cerr << "I was not able to write the dimensions of MultiVector." << std::endl;
-      return false;
-   }
-   return true;
-}
-
-template< typename Real, typename Device, typename Index >
-bool MultiVector< 1, Real, Device, Index > :: load( File& file )
-{
-   if( ! Vector< Real, Device, Index > :: load( file ) )
-   {
-      std::cerr << "I was not able to read the Vector of MultiVector." << std::endl;
-      return false;
-   }
-   if( ! dimensions. load( file ) )
-   {
-      std::cerr << "I was not able to read the dimensions of MultiVector." << std::endl;
-      return false;
-   }
-   return true;
-}
-
-template< typename Real, typename Device, typename Index >
-std::ostream& operator << ( std::ostream& str, const MultiVector< 1, Real, Device, Index >& Vector )
-{
-   for( Index i = 0; i < Vector. getDimensions()[ 0 ]; i ++ )
-   {
-      str << Vector. getElement( i ) << " ";
-   }
-   return str;
-}
-
-template< typename Real, typename Device, typename Index >
-bool MultiVector< 1, Real, Device, Index > :: save( const String& fileName ) const
-{
-   return Object :: save( fileName );
-}
-
-template< typename Real, typename Device, typename Index >
-bool MultiVector< 1, Real, Device, Index > :: load( const String& fileName )
-{
-   return Object :: load( fileName );
-}
-
-} // namespace Containers
-} // namespace TNL
diff --git a/src/TNL/Containers/MultiVector2D_impl.h b/src/TNL/Containers/MultiVector2D_impl.h
deleted file mode 100644
index 7f061ad06cf9e0288d465ab3aa775855374ddd98..0000000000000000000000000000000000000000
--- a/src/TNL/Containers/MultiVector2D_impl.h
+++ /dev/null
@@ -1,242 +0,0 @@
-/***************************************************************************
-                          MultiVector2D_impl.h  -  description
-                             -------------------
-    begin                : Nov 13, 2012
-    copyright            : (C) 2012 by Tomas Oberhuber
-    email                : tomas.oberhuber@fjfi.cvut.cz
- ***************************************************************************/
-
-/* See Copyright Notice in tnl/Copyright */
-
-#pragma once
-
-namespace TNL {
-namespace Containers {   
-
-template< typename Real, typename Device, typename Index >
-MultiVector< 2, Real, Device, Index > :: MultiVector()
-{
-}
-
-template< typename Real, typename Device, typename Index >
-String MultiVector< 2, Real, Device, Index > :: getType()
-{
-   return String( "Containers::MultiVector< ") +
-          convertToString( Dimension ) +
-          String( ", " ) +
-          String( TNL::getType< Real >() ) +
-          String( ", " ) +
-          String( Device :: getDeviceType() ) +
-          String( ", " ) +
-          String( TNL::getType< Index >() ) +
-          String( " >" );
-}
-
-template< typename Real,
-          typename Device,
-          typename Index >
-String MultiVector< 2, Real, Device, Index > :: getTypeVirtual() const
-{
-   return this->getType();
-};
-
-template< typename Real,
-          typename Device,
-          typename Index >
-String MultiVector< 2, Real, Device, Index > :: getSerializationType()
-{
-   return HostType::getType();
-};
-
-template< typename Real,
-          typename Device,
-          typename Index >
-String MultiVector< 2, Real, Device, Index > :: getSerializationTypeVirtual() const
-{
-   return this->getSerializationType();
-};
-
-template< typename Real, typename Device, typename Index >
-void MultiVector< 2, Real, Device, Index > :: setDimensions( const Index jSize,
-                                                             const Index iSize )
-{
-   TNL_ASSERT( iSize > 0 && jSize > 0,
-              std::cerr << "iSize = " << iSize
-                   << "jSize = " << jSize );
-
-   dimensions[ 0 ] = iSize;
-   dimensions[ 1 ] = jSize;
-   Vector< Real, Device, Index > :: setSize( iSize * jSize );
-}
-
-template< typename Real, typename Device, typename Index >
-void MultiVector< 2, Real, Device, Index > :: setDimensions( const StaticVector< 2, Index >& dimensions )
-{
-   TNL_ASSERT( dimensions[ 0 ] > 0 && dimensions[ 1 ] > 0,
-              std::cerr << "dimensions = " << dimensions );
-   this->dimensions = dimensions;
-   Vector< Real, Device, Index > :: setSize( this->dimensions[ 1 ] * this->dimensions[ 0 ] );
-}
-
-template< typename Real, typename Device, typename Index >
-   template< typename MultiVectorT >
-void MultiVector< 2, Real, Device, Index > :: setLike( const MultiVectorT& multiVector )
-{
-   setDimensions( multiVector. getDimensions() );
-}
-
-template< typename Real, typename Device, typename Index >
-void MultiVector< 2, Real, Device, Index > :: getDimensions( Index& jSize, Index& iSize ) const
-{
-   iSize = this->dimensions[ 0 ];
-   jSize = this->dimensions[ 1 ];
-}
-
-template< typename Real, typename Device, typename Index >
-const StaticVector< 2, Index >& MultiVector< 2, Real, Device, Index > :: getDimensions() const
-{
-   return this->dimensions;
-}
-
-template< typename Real, typename Device, typename Index >
-Index MultiVector< 2, Real, Device, Index > :: getElementIndex( const Index j, const Index i ) const
-{
-   TNL_ASSERT( i >= 0 && i < this->dimensions[ 0 ] && j >= 0 && j < this->dimensions[ 1 ],
-              std::cerr << "i = " << i
-                   << "j = " << j
-                   << "this->dimensions[ 0 ] = " << this->dimensions[ 0 ]
-                   << "this->dimensions[ 1 ] = " << this->dimensions[ 1 ] );
-   return j * this->dimensions[ 0 ] + i;
-}
-
-template< typename Real, typename Device, typename Index >
-Real MultiVector< 2, Real, Device, Index > :: getElement( const Index j, const Index i ) const
-{
-   return Vector< Real, Device, Index > :: getElement( getElementIndex( j, i ) );
-}
-
-template< typename Real, typename Device, typename Index >
-void MultiVector< 2, Real, Device, Index > :: setElement( const Index j, const Index i, Real value )
-{
-   Vector< Real, Device, Index > :: setElement( getElementIndex( j, i ), value );
-}
-
-
-template< typename Real, typename Device, typename Index >
-Real& MultiVector< 2, Real, Device, Index > :: operator()( const Index j, const Index i )
-{
-   return Vector< Real, Device, Index > :: operator[]( getElementIndex( j, i ) );
-}
-
-template< typename Real, typename Device, typename Index >
-const Real& MultiVector< 2, Real, Device, Index > :: operator()( const Index j, const Index i ) const
-{
-   return Vector< Real, Device, Index > :: operator[]( getElementIndex( j, i ) );
-}
-
-template< typename Real, typename Device, typename Index >
-   template< typename MultiVectorT >
-bool MultiVector< 2, Real, Device, Index > :: operator == ( const MultiVectorT& vector ) const
-{
-   // TODO: Static assert on dimensions
-   TNL_ASSERT( this->getDimensions() == vector. getDimensions(),
-              std::cerr << "You are attempting to compare two Vectors with different dimensions." << std::endl
-                   << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl
-                   << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; );
-   return Vector< Real, Device, Index > :: operator == ( vector );
-}
-
-template< typename Real, typename Device, typename Index >
-   template< typename MultiVectorT >
-bool MultiVector< 2, Real, Device, Index > :: operator != ( const MultiVectorT& vector ) const
-{
-   return ! ( (* this ) == vector );
-}
-
-template< typename Real, typename Device, typename Index >
-MultiVector< 2, Real, Device, Index >&
-   MultiVector< 2, Real, Device, Index > :: operator = ( const MultiVector< 2, Real, Device, Index >& vector )
-{
-   // TODO: Static assert on dimensions
-   TNL_ASSERT( this->getDimensions() == vector. getDimensions(),
-              std::cerr << "You are attempting to assign two Vectors with different dimensions." << std::endl
-                   << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl
-                   << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; );
-   Vector< Real, Device, Index > :: operator = ( vector );
-   return ( *this );
-}
-
-template< typename Real, typename Device, typename Index >
-   template< typename MultiVectorT >
-MultiVector< 2, Real, Device, Index >&
-   MultiVector< 2, Real, Device, Index > :: operator = ( const MultiVectorT& vector )
-{
-   // TODO: Static assert on dimensions
-   TNL_ASSERT( this->getDimensions() == vector. getDimensions(),
-              std::cerr << "You are attempting to assign two Vectors with different dimensions." << std::endl
-                   << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl
-                   << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; );
-   Vector< Real, Device, Index > :: operator = ( vector );
-   return ( *this );
-}
-
-template< typename Real, typename Device, typename Index >
-bool MultiVector< 2, Real, Device, Index > :: save( File& file ) const
-{
-   if( ! Vector< Real, Device, Index > :: save( file ) )
-   {
-      std::cerr << "I was not able to write the Vector of MultiVector."  << std::endl;
-      return false;
-   }
-   if( ! dimensions. save( file ) )
-   {
-      std::cerr << "I was not able to write the dimensions of MultiVector." << std::endl;
-      return false;
-   }
-   return true;
-}
-
-template< typename Real, typename Device, typename Index >
-bool MultiVector< 2, Real, Device, Index > :: load( File& file )
-{
-   if( ! Vector< Real, Device, Index > :: load( file ) )
-   {
-      std::cerr << "I was not able to read the Vector of MultiVector." << std::endl;
-      return false;
-   }
-   if( ! dimensions. load( file ) )
-   {
-      std::cerr << "I was not able to read the dimensions of MultiVector." << std::endl;
-      return false;
-   }
-   return true;
-}
-
-template< typename Real, typename Device, typename Index >
-bool MultiVector< 2, Real, Device, Index > :: save( const String& fileName ) const
-{
-   return Object :: save( fileName );
-}
-
-template< typename Real, typename Device, typename Index >
-bool MultiVector< 2, Real, Device, Index > :: load( const String& fileName )
-{
-   return Object :: load( fileName );
-}
-
-template< typename Real, typename Device, typename Index >
-std::ostream& operator << ( std::ostream& str, const MultiVector< 2, Real, Device, Index >& Vector )
-{
-   for( Index j = 0; j < Vector. getDimensions()[ 1 ]; j ++ )
-   {
-      for( Index i = 0; i < Vector. getDimensions()[ 0 ]; i ++ )
-      {
-         str << Vector. getElement( j, i ) << " ";
-      }
-      str << std::endl;
-   }
-   return str;
-}
-
-} // namespace Containers
-} // namespace TNL
diff --git a/src/TNL/Containers/MultiVector3D_impl.h b/src/TNL/Containers/MultiVector3D_impl.h
deleted file mode 100644
index c7949014d7233bc14d744457201d14e7923a70fe..0000000000000000000000000000000000000000
--- a/src/TNL/Containers/MultiVector3D_impl.h
+++ /dev/null
@@ -1,266 +0,0 @@
-/***************************************************************************
-                          MultiVector3D_impl.h  -  description
-                             -------------------
-    begin                : Nov 13, 2012
-    copyright            : (C) 2012 by Tomas Oberhuber
-    email                : tomas.oberhuber@fjfi.cvut.cz
- ***************************************************************************/
-
-/* See Copyright Notice in tnl/Copyright */
-
-#pragma once
-
-namespace TNL {
-namespace Containers {   
-
-template< typename Real, typename Device, typename Index >
-MultiVector< 3, Real, Device, Index > :: MultiVector()
-{
-}
-
-template< typename Real, typename Device, typename Index >
-String MultiVector< 3, Real, Device, Index > :: getType()
-{
-   return String( "Containers::MultiVector< ") +
-          convertToString( Dimension ) +
-          String( ", " ) +
-          String( TNL::getType< Real >() ) +
-          String( ", " ) +
-          String( Device :: getDeviceType() ) +
-          String( ", " ) +
-          String( TNL::getType< Index >() ) +
-          String( " >" );
-}
-
-template< typename Real,
-          typename Device,
-          typename Index >
-String MultiVector< 3, Real, Device, Index > :: getTypeVirtual() const
-{
-   return this->getType();
-};
-
-template< typename Real,
-          typename Device,
-          typename Index >
-String MultiVector< 3, Real, Device, Index > :: getSerializationType()
-{
-   return HostType::getType();
-};
-
-template< typename Real,
-          typename Device,
-          typename Index >
-String MultiVector< 3, Real, Device, Index > :: getSerializationTypeVirtual() const
-{
-   return this->getSerializationType();
-};
-
-template< typename Real, typename Device, typename Index >
-void MultiVector< 3, Real, Device, Index > :: setDimensions( const Index kSize,
-                                                             const Index jSize,
-                                                             const Index iSize )
-{
-   TNL_ASSERT( iSize > 0 && jSize > 0 && kSize > 0,
-              std::cerr << "iSize = " << iSize
-                   << "jSize = " << jSize
-                   << "kSize = " << kSize );
-
-   dimensions[ 0 ] = iSize;
-   dimensions[ 1 ] = jSize;
-   dimensions[ 2 ] = kSize;
-   return Vector< Real, Device, Index > :: setSize( iSize * jSize * kSize );
-}
-
-template< typename Real, typename Device, typename Index >
-void MultiVector< 3, Real, Device, Index > :: setDimensions( const StaticVector< 3, Index >& dimensions )
-{
-   TNL_ASSERT( dimensions[ 0 ] > 0 && dimensions[ 1 ] > 0 && dimensions[ 2 ],
-              std::cerr << "dimensions = " << dimensions );
-   this->dimensions = dimensions;
-   Vector< Real, Device, Index > :: setSize( this->dimensions[ 2 ] *
-                                             this->dimensions[ 1 ] *
-                                             this->dimensions[ 0 ] );
-}
-
-template< typename Real, typename Device, typename Index >
-   template< typename MultiVectorT >
-void MultiVector< 3, Real, Device, Index > :: setLike( const MultiVectorT& multiVector )
-{
-   setDimensions( multiVector. getDimensions() );
-}
-
-template< typename Real, typename Device, typename Index >
-void MultiVector< 3, Real, Device, Index > :: getDimensions( Index& kSize,
-                                                             Index& jSize,
-                                                             Index& iSize ) const
-{
-   iSize = this->dimensions[ 0 ];
-   jSize = this->dimensions[ 1 ];
-   kSize = this->dimensions[ 2 ];
-}
-
-template< typename Real, typename Device, typename Index >
-const StaticVector< 3, Index >& MultiVector< 3, Real, Device, Index > :: getDimensions() const
-{
-   return this->dimensions;
-}
-
-template< typename Real, typename Device, typename Index >
-Index MultiVector< 3, Real, Device, Index > :: getElementIndex( const Index k,
-                                                                     const Index j,
-                                                                     const Index i ) const
-{
-   TNL_ASSERT( i >= 0 && i < this->dimensions[ 0 ] &&
-              j >= 0 && j < this->dimensions[ 1 ] &&
-              k >= 0 && k < this->dimensions[ 2 ],
-              std::cerr << " i = " << i
-                   << " j = " << j
-                   << " k = " << k
-                   << " this->dimensions = " << this->dimensions );
-   return ( k * this->dimensions[ 1 ]  + j ) * this->dimensions[ 0 ] + i;
-}
-
-template< typename Real, typename Device, typename Index >
-Real MultiVector< 3, Real, Device, Index > :: getElement( const Index k,
-                                                                  const Index j,
-                                                                  const Index i ) const
-{
-   return Vector< Real, Device, Index > :: getElement( getElementIndex( k, j, i ) );
-}
-
-template< typename Real, typename Device, typename Index >
-void MultiVector< 3, Real, Device, Index > :: setElement( const Index k,
-                                                                    const Index j,
-                                                                    const Index i, Real value )
-{
-   Vector< Real, Device, Index > :: setElement( getElementIndex( k, j, i ), value );
-}
-
-
-template< typename Real, typename Device, typename Index >
-Real& MultiVector< 3, Real, Device, Index > :: operator()( const Index k,
-                                                                        const Index j,
-                                                                        const Index i )
-{
-   return Vector< Real, Device, Index > :: operator[]( getElementIndex( k, j, i ) );
-}
-
-template< typename Real, typename Device, typename Index >
-const Real& MultiVector< 3, Real, Device, Index > :: operator()( const Index k,
-                                                                               const Index j,
-                                                                               const Index i ) const
-{
-   return Vector< Real, Device, Index > :: operator[]( getElementIndex( k, j, i ) );
-}
-
-template< typename Real, typename Device, typename Index >
-   template< typename MultiVectorT >
-bool MultiVector< 3, Real, Device, Index > :: operator == ( const MultiVectorT& vector ) const
-{
-   // TODO: Static assert on dimensions
-   TNL_ASSERT( this->getDimensions() == vector. getDimensions(),
-              std::cerr << "You are attempting to compare two Vectors with different dimensions." << std::endl
-                   << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl
-                   << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; );
-   return Vector< Real, Device, Index > :: operator == ( vector );
-}
-
-template< typename Real, typename Device, typename Index >
-   template< typename MultiVectorT >
-bool MultiVector< 3, Real, Device, Index > :: operator != ( const MultiVectorT& vector ) const
-{
-   return ! ( (* this ) == vector );
-}
-
-template< typename Real, typename Device, typename Index >
-MultiVector< 3, Real, Device, Index >&
-   MultiVector< 3, Real, Device, Index > :: operator = ( const MultiVector< 3, Real, Device, Index >& vector )
-{
-   // TODO: Static assert on dimensions
-   TNL_ASSERT( this->getDimensions() == vector. getDimensions(),
-              std::cerr << "You are attempting to assign two Vectors with different dimensions." << std::endl
-                   << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl
-                   << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; );
-   Vector< Real, Device, Index > :: operator = ( vector );
-   return ( *this );
-}
-
-template< typename Real, typename Device, typename Index >
-   template< typename MultiVectorT >
-MultiVector< 3, Real, Device, Index >&
-   MultiVector< 3, Real, Device, Index > :: operator = ( const MultiVectorT& vector )
-{
-   // TODO: Static assert on dimensions
-   TNL_ASSERT( this->getDimensions() == vector. getDimensions(),
-              std::cerr << "You are attempting to assign two Vectors with different dimensions." << std::endl
-                   << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl
-                   << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; );
-   Vector< Real, Device, Index > :: operator = ( vector );
-   return ( *this );
-}
-
-template< typename Real, typename Device, typename Index >
-bool MultiVector< 3, Real, Device, Index > :: save( File& file ) const
-{
-   if( ! Vector< Real, Device, Index > :: save( file ) )
-   {
-      std::cerr << "I was not able to write the Vector of MultiVector." << std::endl;
-      return false;
-   }
-   if( ! dimensions. save( file ) )
-   {
-      std::cerr << "I was not able to write the dimensions of MultiVector." << std::endl;
-      return false;
-   }
-   return true;
-}
-
-template< typename Real, typename Device, typename Index >
-bool MultiVector< 3, Real, Device, Index > :: load( File& file )
-{
-   if( ! Vector< Real, Device, Index > :: load( file ) )
-   {
-      std::cerr << "I was not able to read the Vector of MultiVector." << std::endl;
-      return false;
-   }
-   if( ! dimensions. load( file ) )
-   {
-      std::cerr << "I was not able to read the dimensions of MultiVector." << std::endl;
-      return false;
-   }
-   return true;
-}
-
-template< typename Real, typename Device, typename Index >
-std::ostream& operator << ( std::ostream& str, const MultiVector< 3, Real, Device, Index >& Vector )
-{
-   for( Index k = 0; k < Vector. getDimensions()[ 2 ]; k ++ )
-   {
-      for( Index j = 0; j < Vector. getDimensions()[ 1 ]; j ++ )
-      {
-         for( Index i = 0; i < Vector. getDimensions()[ 0 ]; i ++ )
-         {
-            str << Vector. getElement( k, j, i ) << " ";
-         }
-         str << std::endl;
-      }
-      str << std::endl;
-   }
-   return str;
-}
-
-template< typename Real, typename Device, typename Index >
-bool MultiVector< 3, Real, Device, Index > :: save( const String& fileName ) const
-{
-   return Object :: save( fileName );
-}
-
-template< typename Real, typename Device, typename Index >
-bool MultiVector< 3, Real, Device, Index > :: load( const String& fileName )
-{
-   return Object :: load( fileName );
-}
-
-} // namespace Containers
-} // namespace TNL
diff --git a/src/TNL/Containers/MultiVector4D_impl.h b/src/TNL/Containers/MultiVector4D_impl.h
deleted file mode 100644
index 14708ec20c6d7c4daa5cb1424843bb34fcd78aa9..0000000000000000000000000000000000000000
--- a/src/TNL/Containers/MultiVector4D_impl.h
+++ /dev/null
@@ -1,287 +0,0 @@
-/***************************************************************************
-                          MultiVector4D_impl.h  -  description
-                             -------------------
-    begin                : Nov 13, 2012
-    copyright            : (C) 2012 by Tomas Oberhuber
-    email                : tomas.oberhuber@fjfi.cvut.cz
- ***************************************************************************/
-
-/* See Copyright Notice in tnl/Copyright */
-
-#pragma once
-
-namespace TNL {
-namespace Containers {   
-
-template< typename Real, typename Device, typename Index >
-MultiVector< 4, Real, Device, Index > :: MultiVector()
-{
-}
-
-template< typename Real, typename Device, typename Index >
-String MultiVector< 4, Real, Device, Index > :: getType()
-{
-   return String( "Containers::MultiVector< ") +
-          convertToString( Dimension ) +
-          String( ", " ) +
-          String( TNL::getType< Real >() ) +
-          String( ", " ) +
-          String( Device :: getDeviceType() ) +
-          String( ", " ) +
-          String( TNL::getType< Index >() ) +
-          String( " >" );
-}
-
-template< typename Real,
-          typename Device,
-          typename Index >
-String MultiVector< 4, Real, Device, Index > :: getTypeVirtual() const
-{
-   return this->getType();
-};
-
-template< typename Real,
-          typename Device,
-          typename Index >
-String MultiVector< 4, Real, Device, Index > :: getSerializationType()
-{
-   return HostType::getType();
-};
-
-template< typename Real,
-          typename Device,
-          typename Index >
-String MultiVector< 4, Real, Device, Index > :: getSerializationTypeVirtual() const
-{
-   return this->getSerializationType();
-};
-
-template< typename Real, typename Device, typename Index >
-void MultiVector< 4, Real, Device, Index > :: setDimensions( const Index lSize,
-                                                             const Index kSize,
-                                                             const Index jSize,
-                                                             const Index iSize )
-{
-   TNL_ASSERT( iSize > 0 && jSize > 0 && kSize > 0 && lSize > 0,
-              std::cerr << "iSize = " << iSize
-                   << "jSize = " << jSize
-                   << "kSize = " << kSize
-                   << "lSize = " << lSize );
-
-   dimensions[ 0 ] = iSize;
-   dimensions[ 1 ] = jSize;
-   dimensions[ 2 ] = kSize;
-   dimensions[ 3 ] = lSize;
-   Vector< Real, Device, Index > :: setSize( iSize * jSize * kSize * lSize );
-}
-
-template< typename Real, typename Device, typename Index >
-void MultiVector< 4, Real, Device, Index > :: setDimensions( const StaticVector< 4, Index >& dimensions )
-{
-   TNL_ASSERT( dimensions[ 0 ] > 0 && dimensions[ 1 ] > 0 && dimensions[ 2 ] && dimensions[ 3 ] > 0,
-              std::cerr << "dimensions = " << dimensions );
-   this->dimensions = dimensions;
-   Vector< Real, Device, Index > :: setSize( this->dimensions[ 3 ] *
-                                             this->dimensions[ 2 ] *
-                                             this->dimensions[ 1 ] *
-                                             this->dimensions[ 0 ] );
-}
-
-template< typename Real, typename Device, typename Index >
-   template< typename MultiVectorT >
-void MultiVector< 4, Real, Device, Index > :: setLike( const MultiVectorT& multiVector )
-{
-   setDimensions( multiVector. getDimensions() );
-}
-
-template< typename Real, typename Device, typename Index >
-void MultiVector< 4, Real, Device, Index > :: getDimensions( Index& lSize,
-                                                                       Index& kSize,
-                                                                       Index& jSize,
-                                                                       Index& iSize ) const
-{
-   iSize = this->dimensions[ 0 ];
-   jSize = this->dimensions[ 1 ];
-   kSize = this->dimensions[ 2 ];
-   lSize = this->dimensions[ 3 ];
-}
-
-template< typename Real, typename Device, typename Index >
-const StaticVector< 4, Index >& MultiVector< 4, Real, Device, Index > :: getDimensions() const
-{
-   return this->dimensions;
-}
-
-template< typename Real, typename Device, typename Index >
-Index MultiVector< 4, Real, Device, Index > :: getElementIndex( const Index l,
-                                                                          const Index k,
-                                                                          const Index j,
-                                                                          const Index i ) const
-{
-   TNL_ASSERT( i >= 0 && i < this->dimensions[ 0 ] &&
-              j >= 0 && j < this->dimensions[ 1 ] &&
-              k >= 0 && k < this->dimensions[ 2 ] &&
-              l >= 0 && l < this->dimensions[ 3 ],
-              std::cerr << " i = " << i
-                   << " j = " << j
-                   << " k = " << k
-                   << " l = " << l
-                   << " this->dimensions = " << this->dimensions );
-   return ( ( l * this->dimensions[ 2 ] + k ) * this->dimensions[ 1 ]  + j ) * this->dimensions[ 0 ] + i;
-}
-
-template< typename Real, typename Device, typename Index >
-Real
-MultiVector< 4, Real, Device, Index >::
-getElement( const Index l,
-            const Index k,
-            const Index j,
-            const Index i ) const
-{
-   return Vector< Real, Device, Index > :: getElement( getElementIndex( l, k, j, i ) );
-}
-
-template< typename Real, typename Device, typename Index >
-void MultiVector< 4, Real, Device, Index > :: setElement( const Index l,
-                                                                    const Index k,
-                                                                    const Index j,
-                                                                    const Index i, Real value )
-{
-   Vector< Real, Device, Index > :: setElement( getElementIndex( l, k, j, i ), value );
-}
-
-
-template< typename Real, typename Device, typename Index >
-Real&
-MultiVector< 4, Real, Device, Index >::
-operator()( const Index l,
-            const Index k,
-            const Index j,
-            const Index i )
-{
-   return Vector< Real, Device, Index > :: operator[]( getElementIndex( l, k, j, i ) );
-}
-
-template< typename Real, typename Device, typename Index >
-const Real& MultiVector< 4, Real, Device, Index > :: operator()( const Index l,
-                                                                               const Index k,
-                                                                               const Index j,
-                                                                               const Index i ) const
-{
-   return Vector< Real, Device, Index > :: operator[]( getElementIndex( l, k, j, i ) );
-}
-
-template< typename Real, typename Device, typename Index >
-   template< typename MultiVectorT >
-bool MultiVector< 4, Real, Device, Index > :: operator == ( const MultiVectorT& vector ) const
-{
-   // TODO: Static assert on dimensions
-   TNL_ASSERT( this->getDimensions() == vector. getDimensions(),
-              std::cerr << "You are attempting to compare two Vectors with different dimensions." << std::endl
-                   << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl
-                   << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; );
-   return Vector< Real, Device, Index > :: operator == ( vector );
-}
-
-template< typename Real, typename Device, typename Index >
-   template< typename MultiVectorT >
-bool MultiVector< 4, Real, Device, Index > :: operator != ( const MultiVectorT& vector ) const
-{
-   return ! ( (* this ) == vector );
-}
-
-template< typename Real, typename Device, typename Index >
-MultiVector< 4, Real, Device, Index >&
-   MultiVector< 4, Real, Device, Index > :: operator = ( const MultiVector< 4, Real, Device, Index >& vector )
-{
-   // TODO: Static assert on dimensions
-   TNL_ASSERT( this->getDimensions() == vector. getDimensions(),
-              std::cerr << "You are attempting to assign two Vectors with different dimensions." << std::endl
-                   << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl
-                   << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; );
-   Vector< Real, Device, Index > :: operator = ( vector );
-   return ( *this );
-}
-
-template< typename Real, typename Device, typename Index >
-   template< typename MultiVectorT >
-MultiVector< 4, Real, Device, Index >&
-   MultiVector< 4, Real, Device, Index > :: operator = ( const MultiVectorT& vector )
-{
-   // TODO: Static assert on dimensions
-   TNL_ASSERT( this->getDimensions() == vector. getDimensions(),
-              std::cerr << "You are attempting to assign two Vectors with different dimensions." << std::endl
-                   << "First vector dimensions are ( " << this->getDimensions() << " )" << std::endl
-                   << "Second vector dimensions are ( " << vector. getDimensions() << " )" << std::endl; );
-   Vector< Real, Device, Index > :: operator = ( vector );
-   return ( *this );
-}
-
-template< typename Real, typename Device, typename Index >
-bool MultiVector< 4, Real, Device, Index > :: save( File& file ) const
-{
-   if( ! Vector< Real, Device, Index > :: save( file ) )
-   {
-      std::cerr << "I was not able to write the Vector of MultiVector." << std::endl;
-      return false;
-   }
-   if( ! dimensions. save( file ) )
-   {
-      std::cerr << "I was not able to write the dimensions of MultiVector." << std::endl;
-      return false;
-   }
-   return true;
-}
-
-template< typename Real, typename Device, typename Index >
-bool MultiVector< 4, Real, Device, Index > :: load( File& file )
-{
-   if( ! Vector< Real, Device, Index > :: load( file ) )
-   {
-      std::cerr << "I was not able to read the Vector of MultiVector." << std::endl;
-      return false;
-   }
-   if( ! dimensions. load( file ) )
-   {
-      std::cerr << "I was not able to read the dimensions of MultiVector." << std::endl;
-      return false;
-   }
-   return true;
-}
-
-template< typename Real, typename Device, typename Index >
-std::ostream& operator << ( std::ostream& str, const MultiVector< 4, Real, Device, Index >& Vector )
-{
-   for( Index l = 0; l < Vector. getDimensions()[ 3 ]; l ++ )
-   {
-      for( Index k = 0; k < Vector. getDimensions()[ 2 ]; k ++ )
-      {
-         for( Index j = 0; j < Vector. getDimensions()[ 1 ]; j ++ )
-         {
-            for( Index i = 0; i < Vector. getDimensions()[ 0 ]; i ++ )
-            {
-               str << Vector. getElement( l, k, j, i ) << " ";
-            }
-            str << std::endl;
-         }
-         str << std::endl;
-      }
-      str << std::endl;
-   }
-   return str;
-}
-
-template< typename Real, typename Device, typename Index >
-bool MultiVector< 4, Real, Device, Index > :: save( const String& fileName ) const
-{
-   return Object :: save( fileName );
-}
-
-template< typename Real, typename Device, typename Index >
-bool MultiVector< 4, Real, Device, Index > :: load( const String& fileName )
-{
-   return Object :: load( fileName );
-}
-
-} // namespace Containers
-} // namespace TNL
diff --git a/src/TNL/Containers/Multimaps/EllpackIndexMultimap.h b/src/TNL/Containers/Multimaps/EllpackIndexMultimap.h
index feac869e51ea0800cd96f1b1c6f6d5d7ccadea81..822b7abb4d533ba10de88d3bb24111e3b8888086 100644
--- a/src/TNL/Containers/Multimaps/EllpackIndexMultimap.h
+++ b/src/TNL/Containers/Multimaps/EllpackIndexMultimap.h
@@ -76,9 +76,9 @@ class EllpackIndexMultimap
 
       bool operator==( const EllpackIndexMultimap& other ) const;
 
-      bool save( File& file ) const;
+      void save( File& file ) const;
 
-      bool load( File& file );
+      void load( File& file );
 
       using Object::load;
 
diff --git a/src/TNL/Containers/Multimaps/EllpackIndexMultimap_impl.h b/src/TNL/Containers/Multimaps/EllpackIndexMultimap_impl.h
index 52182ad06f02f8e1add8318da3cf980ffc772447..2d145d377245ae8e0c92560aeaf9d8389bda2bd4 100644
--- a/src/TNL/Containers/Multimaps/EllpackIndexMultimap_impl.h
+++ b/src/TNL/Containers/Multimaps/EllpackIndexMultimap_impl.h
@@ -238,42 +238,30 @@ template< typename Index,
           typename Device,
           typename LocalIndex,
           int SliceSize >
-bool
+void
 EllpackIndexMultimap< Index, Device, LocalIndex, SliceSize >::
 save( File& file ) const
 {
-   if( ! Object::save( file ) )
-      return false;
-   if( ! file.write( &this->keysRange ) )
-      return false;
-   if( ! file.write( &this->maxValuesCount ) )
-      return false;
-   if( ! this->values.save( file ) )
-      return false;
-   if( ! this->valuesCounts.save( file ) )
-      return false;
-   return true;
+   Object::save( file );
+   file.save( &this->keysRange );
+   file.save( &this->maxValuesCount );
+   this->values.save( file );
+   this->valuesCounts.save( file );
 }
 
 template< typename Index,
           typename Device,
           typename LocalIndex,
           int SliceSize >
-bool
+void
 EllpackIndexMultimap< Index, Device, LocalIndex, SliceSize >::
 load( File& file )
 {
-   if( ! Object::load( file ) )
-      return false;
-   if( ! file.read( &this->keysRange ) )
-      return false;
-   if( ! file.read( &this->maxValuesCount ) )
-      return false;
-   if( ! this->values.load( file ) )
-      return false;
-   if( ! this->valuesCounts.load( file ) )
-      return false;
-   return true;
+   Object::load( file );
+   file.load( &this->keysRange );
+   file.load( &this->maxValuesCount );
+   this->values.load( file );
+   this->valuesCounts.load( file );
 }
 
 template< typename Index,
diff --git a/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimap.h b/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimap.h
index 4811a763d145f1a922e64dfc27968b8dd9f10521..1af67bd3b165b419065f06eb1673f0f9e69bf2a0 100644
--- a/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimap.h
+++ b/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimap.h
@@ -74,9 +74,9 @@ class StaticEllpackIndexMultimap
 
       bool operator==( const StaticEllpackIndexMultimap& other ) const;
 
-      bool save( File& file ) const;
+      void save( File& file ) const;
 
-      bool load( File& file );
+      void load( File& file );
 
       using Object::load;
 
diff --git a/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimap_impl.h b/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimap_impl.h
index 9a9309635c27d79c823516d3a621f4426cc2cbbd..95cb75d5db4069319c9bbd7bcbc138e102285ec5 100644
--- a/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimap_impl.h
+++ b/src/TNL/Containers/Multimaps/StaticEllpackIndexMultimap_impl.h
@@ -197,17 +197,13 @@ template< int ValuesCount,
           typename Device,
           typename LocalIndex,
           int SliceSize >
-bool
+void
 StaticEllpackIndexMultimap< ValuesCount, Index, Device, LocalIndex, SliceSize >::
 save( File& file ) const
 {
-   if( ! Object::save( file ) )
-      return false;
-   if( ! file.write( &this->keysRange ) )
-      return false;
-   if( ! this->values.save( file ) )
-      return false;
-   return true;
+   Object::save( file );
+   file.save( &this->keysRange );
+   this->values.save( file );
 }
 
 template< int ValuesCount,
@@ -215,17 +211,13 @@ template< int ValuesCount,
           typename Device,
           typename LocalIndex,
           int SliceSize >
-bool
+void
 StaticEllpackIndexMultimap< ValuesCount, Index, Device, LocalIndex, SliceSize >::
 load( File& file )
 {
-   if( ! Object::load( file ) )
-      return false;
-   if( ! file.read( &this->keysRange ) )
-      return false;
-   if( ! this->values.load( file ) )
-      return false;
-   return true;
+   Object::load( file );
+   file.load( &this->keysRange );
+   this->values.load( file );
 }
 
 template< int ValuesCount,
diff --git a/src/TNL/Containers/StaticArray1D_impl.h b/src/TNL/Containers/StaticArray1D_impl.h
index e9b1fbc1d0726dcdb03414b8e0ad0ff0fa8c29bc..98963dcf350b5ebb7dd7323a73122a30b60dcb6d 100644
--- a/src/TNL/Containers/StaticArray1D_impl.h
+++ b/src/TNL/Containers/StaticArray1D_impl.h
@@ -162,22 +162,14 @@ inline void StaticArray< 1, Value >::setValue( const ValueType& val )
 template< typename Value >
 bool StaticArray< 1, Value >::save( File& file ) const
 {
-   if( ! file. write< Value, Devices::Host >( data, size ) )
-   {
-      std::cerr << "Unable to write " << getType() << "." << std::endl;
-      return false;
-   }
+   file.save< Value, Value, Devices::Host >( data, size );
    return true;
 }
 
 template< typename Value >
 bool StaticArray< 1, Value >::load( File& file)
 {
-   if( ! file.read( data, size ) )
-   {
-      std::cerr << "Unable to read " << getType() << "." << std::endl;
-      return false;
-   }
+   file.load< Value, Value, Devices::Host >( data, size );
    return true;
 }
 
diff --git a/src/TNL/Containers/StaticArray2D_impl.h b/src/TNL/Containers/StaticArray2D_impl.h
index 664a938d79f4df5259609f74d5a379e26927b770..29dcbee5993e7f4a1b00b687e817f4323e0b936f 100644
--- a/src/TNL/Containers/StaticArray2D_impl.h
+++ b/src/TNL/Containers/StaticArray2D_impl.h
@@ -192,22 +192,14 @@ inline void StaticArray< 2, Value >::setValue( const ValueType& val )
 template< typename Value >
 bool StaticArray< 2, Value >::save( File& file ) const
 {
-   if( ! file. write< Value, Devices::Host >( data, size ) )
-   {
-      std::cerr << "Unable to write " << getType() << "." << std::endl;
-      return false;
-   }
+   file.save< Value, Value, Devices::Host >( data, size );
    return true;
 }
 
 template< typename Value >
 bool StaticArray< 2, Value >::load( File& file)
 {
-   if( ! file.read< Value, Devices::Host >( data, size ) )
-   {
-      std::cerr << "Unable to read " << getType() << "." << std::endl;
-      return false;
-   }
+   file.load< Value, Value, Devices::Host >( data, size );
    return true;
 }
 
diff --git a/src/TNL/Containers/StaticArray3D_impl.h b/src/TNL/Containers/StaticArray3D_impl.h
index 2489196c05f91c294507fc9dd105b4da36f7a2bb..69c1998a471ae993d452ba684ac056aee6dfaf5e 100644
--- a/src/TNL/Containers/StaticArray3D_impl.h
+++ b/src/TNL/Containers/StaticArray3D_impl.h
@@ -213,22 +213,14 @@ void StaticArray< 3, Value >::setValue( const ValueType& val )
 template< typename Value >
 bool StaticArray< 3, Value >::save( File& file ) const
 {
-   if( ! file. write< Value, Devices::Host >( data, size ) )
-   {
-      std::cerr << "Unable to write " << getType() << "." << std::endl;
-      return false;
-   }
+   file.save< Value, Value, Devices::Host >( data, size );
    return true;
 }
 
 template< typename Value >
 bool StaticArray< 3, Value >::load( File& file)
 {
-   if( ! file.read< Value, Devices::Host >( data, size ) )
-   {
-      std::cerr << "Unable to read " << getType() << "." << std::endl;
-      return false;
-   }
+   file.load< Value, Value, Devices::Host >( data, size );
    return true;
 }
 
diff --git a/src/TNL/Containers/StaticArray_impl.h b/src/TNL/Containers/StaticArray_impl.h
index a154ebc480ea8ba0529f3f452652fe5cc426f134..9c7835ce82c47b62057c0ba1ee519102112f4db9 100644
--- a/src/TNL/Containers/StaticArray_impl.h
+++ b/src/TNL/Containers/StaticArray_impl.h
@@ -160,22 +160,14 @@ inline void StaticArray< Size, Value >::setValue( const ValueType& val )
 template< int Size, typename Value >
 bool StaticArray< Size, Value >::save( File& file ) const
 {
-   if( ! file. write< Value, Devices::Host >( data, size ) )
-   {
-      std::cerr << "Unable to write " << getType() << "." << std::endl;
-      return false;
-   }
+   file.save< Value, Value, Devices::Host >( data, size );
    return true;
 }
 
 template< int Size, typename Value >
 bool StaticArray< Size, Value >::load( File& file)
 {
-   if( ! file.read< Value, Devices::Host >( data, size ) )
-   {
-      std::cerr << "Unable to read " << getType() << "." << std::endl;
-      return false;
-   }
+   file.load< Value, Value, Devices::Host >( data, size );
    return true;
 }
 
diff --git a/src/TNL/Containers/Vector.h b/src/TNL/Containers/Vector.h
index e116508ba3a54571e718938e4961233a73d98499..30e399312afc584d5f053de6d8792e4bd0064d13 100644
--- a/src/TNL/Containers/Vector.h
+++ b/src/TNL/Containers/Vector.h
@@ -11,12 +11,17 @@
 #pragma once
 
 #include <TNL/Containers/Array.h>
+#include <TNL/Containers/VectorView.h>
 
 namespace TNL {
 namespace Containers {
 
 /**
- * \brief Class for storing vector elements and handling vector operations.
+ * \brief This class extends TNL::Array with algebraic operations.
+ *
+ * \tparam Real is numeric type usually float or double.
+ * \tparam Device is device where the array is going to be allocated - some of \ref Devices::Host and \ref Devices::Cuda.
+ * \tparam Index is indexing type.
  *
  * \par Example
  * \include VectorExample.cpp
@@ -27,13 +32,14 @@ template< typename Real = double,
 class Vector
 : public Array< Real, Device, Index >
 {
-   public:
-
-   typedef Real RealType;
-   typedef Device DeviceType;
-   typedef Index IndexType;
-   typedef Vector< Real, TNL::Devices::Host, Index > HostType;
-   typedef Vector< Real, TNL::Devices::Cuda, Index > CudaType;
+public:
+   using RealType = Real;
+   using DeviceType = Device;
+   using IndexType = Index;
+   using HostType = Vector< Real, TNL::Devices::Host, Index >;
+   using CudaType = Vector< Real, TNL::Devices::Cuda, Index >;
+   using ViewType = VectorView< Real, Device, Index >;
+   using ConstViewType = VectorView< typename std::add_const< Real >::type, Device, Index >;
 
    /** Constructors and assignment operators are inherited from the class \ref Array. */
    using Array< Real, Device, Index >::Array;
@@ -51,6 +57,26 @@ class Vector
    /** \brief Returns (host) type of vector Real value, Device type and the type of Index. */
    virtual String getSerializationTypeVirtual() const;
 
+   /**
+    * \brief Returns a modifiable view of the vector.
+    */
+   ViewType getView();
+
+   /**
+    * \brief Returns a non-modifiable view of the vector.
+    */
+   ConstViewType getConstView() const;
+
+   /**
+    * \brief Conversion operator to a modifiable view of the vector.
+    */
+   operator ViewType();
+
+   /**
+    * \brief Conversion operator to a non-modifiable view of the vector.
+    */
+   operator ConstViewType() const;
+
    /**
     * \brief Adds another element to this vector.
     *
@@ -282,4 +308,4 @@ class Vector
 } // namespace Containers
 } // namespace TNL
 
-#include <TNL/Containers/Vector_impl.h>
+#include <TNL/Containers/Vector.hpp>
diff --git a/src/TNL/Containers/Vector_impl.h b/src/TNL/Containers/Vector.hpp
similarity index 91%
rename from src/TNL/Containers/Vector_impl.h
rename to src/TNL/Containers/Vector.hpp
index 6838215144393e8a69f5771d8109c4a36b8d6e2c..5f15d9bae5fc6d0527943f8b4245b6f94379fec3 100644
--- a/src/TNL/Containers/Vector_impl.h
+++ b/src/TNL/Containers/Vector.hpp
@@ -59,6 +59,44 @@ getSerializationTypeVirtual() const
    return this->getSerializationType();
 }
 
+template< typename Real,
+          typename Device,
+          typename Index >
+typename Vector< Real, Device, Index >::ViewType
+Vector< Real, Device, Index >::
+getView()
+{
+   return ViewType( this->getData(), this->getSize() );
+}
+
+template< typename Real,
+          typename Device,
+          typename Index >
+typename Vector< Real, Device, Index >::ConstViewType
+Vector< Real, Device, Index >::
+getConstView() const
+{
+   return ConstViewType( this->getData(), this->getSize() );
+}
+
+template< typename Value,
+          typename Device,
+          typename Index >
+Vector< Value, Device, Index >::
+operator ViewType()
+{
+   return getView();
+}
+
+template< typename Value,
+          typename Device,
+          typename Index >
+Vector< Value, Device, Index >::
+operator ConstViewType() const
+{
+   return getConstView();
+}
+
 template< typename Real,
           typename Device,
           typename Index >
@@ -174,7 +212,6 @@ ResultType Vector< Real, Device, Index >::lpNorm( const Scalar p ) const
    return Algorithms::VectorOperations< Device >::template getVectorLpNorm< Vector, ResultType >( *this, p );
 }
 
-
 template< typename Real,
           typename Device,
           typename Index >
@@ -184,7 +221,6 @@ ResultType Vector< Real, Device, Index >::sum() const
    return Algorithms::VectorOperations< Device >::template getVectorSum< Vector, ResultType >( *this );
 }
 
-
 template< typename Real,
           typename Device,
           typename Index >
@@ -194,7 +230,6 @@ Real Vector< Real, Device, Index >::differenceMax( const VectorT& v ) const
    return Algorithms::VectorOperations< Device >::getVectorDifferenceMax( *this, v );
 }
 
-
 template< typename Real,
           typename Device,
           typename Index >
diff --git a/src/TNL/Containers/VectorView.h b/src/TNL/Containers/VectorView.h
index 6ae0bcb816aff7feec18ef84b0e15c6c3e98cb13..1e5f070486052b6e52bc01da6d5ce5ff88d3edab 100644
--- a/src/TNL/Containers/VectorView.h
+++ b/src/TNL/Containers/VectorView.h
@@ -37,6 +37,8 @@ public:
    using IndexType = Index;
    using HostType = VectorView< Real, Devices::Host, Index >;
    using CudaType = VectorView< Real, Devices::Cuda, Index >;
+   using ViewType = VectorView< Real, Device, Index >;
+   using ConstViewType = VectorView< typename std::add_const< Real >::type, Device, Index >;
 
    // inherit all ArrayView's constructors
 #ifndef __NVCC__
@@ -62,6 +64,18 @@ public:
    VectorView( const ArrayView< Real_, Device, Index >& view )
    : BaseType::ArrayView( view ) {}
 
+   /**
+    * \brief Returns a modifiable view of the array view.
+    */
+   __cuda_callable__
+   ViewType getView();
+
+   /**
+    * \brief Returns a non-modifiable view of the array view.
+    */
+   __cuda_callable__
+   ConstViewType getConstView() const;
+
 
    static String getType();
 
diff --git a/src/TNL/Containers/VectorView_impl.h b/src/TNL/Containers/VectorView_impl.h
index 39b6f703e9035d0ad5ab029be7b3e2b71aafba54..af4df853738c7520510bd4fa5a47c8ec5e56acda 100644
--- a/src/TNL/Containers/VectorView_impl.h
+++ b/src/TNL/Containers/VectorView_impl.h
@@ -16,6 +16,26 @@
 namespace TNL {
 namespace Containers {
 
+template< typename Value,
+          typename Device,
+          typename Index >
+typename VectorView< Value, Device, Index >::ViewType
+VectorView< Value, Device, Index >::
+getView()
+{
+   return *this;
+}
+
+template< typename Value,
+          typename Device,
+          typename Index >
+typename VectorView< Value, Device, Index >::ConstViewType
+VectorView< Value, Device, Index >::
+getConstView() const
+{
+   return *this;
+}
+
 template< typename Real,
           typename Device,
           typename Index >
diff --git a/src/TNL/Devices/Cuda.h b/src/TNL/Devices/Cuda.h
index 0ba22cb00a433d3346d4429823c75cb6dfe002d6..7831014155e9a730c1be101c47cb2602cd8d3179 100644
--- a/src/TNL/Devices/Cuda.h
+++ b/src/TNL/Devices/Cuda.h
@@ -29,6 +29,9 @@ class Cuda
 
    static inline String getDeviceType();
 
+   // TODO: Remove getDeviceType();
+   static inline String getType() { return getDeviceType();};
+
    static inline void configSetup( Config::ConfigDescription& config, const String& prefix = "" );
 
    static inline bool setup( const Config::ParameterContainer& parameters,
@@ -169,6 +172,15 @@ class Cuda
 
    static inline Timer& getSmartPointersSynchronizationTimer();
 
+   ////
+   // When we transfer data between the GPU and the CPU we use 5 MB buffer. This
+   // size should ensure good performance -- see.
+   // http://wiki.accelereyes.com/wiki/index.php/GPU_Memory_Transfer .
+   // We use the same buffer size even for retyping data during IO operations.
+   //
+   static constexpr std::size_t TransferBufferSize = 5 * 2<<20;
+
+
    protected:
 
    static inline Pointers::SmartPointersRegister& getSmartPointersRegister();
diff --git a/src/TNL/Devices/CudaCallable.h b/src/TNL/Devices/CudaCallable.h
index e0a86a3e4f01a8ae112a45c7528f77e152289b04..f9311443f12a0c85fb6fba9ebaf07ca47736b030 100644
--- a/src/TNL/Devices/CudaCallable.h
+++ b/src/TNL/Devices/CudaCallable.h
@@ -16,6 +16,12 @@
 // For example, the implementation of Devices::Cuda needs TNL_ASSERT_*
 // macros, which need __cuda_callable__ functions.
 
+/***
+ * This macro serves for definition of function which are supposed to be called
+ * even from device. If HAVE_CUDA is defined, the __cuda_callable__ function
+ * is compiled for both CPU and GPU. If HAVE_CUDA is not defined, this macro has
+ * no effect. Support for Intel Xeon Phi is now in "hibernated" state.
+ */
 #ifdef HAVE_MIC 
    #define __cuda_callable__ __attribute__((target(mic)))
 #elif HAVE_CUDA
diff --git a/src/TNL/Devices/Cuda_impl.h b/src/TNL/Devices/Cuda_impl.h
index c9828c66deab37b889b8e738ec5eabfe1ab26352..234f45b720fcfa9502b6f4c5c14debfb48ecca64 100644
--- a/src/TNL/Devices/Cuda_impl.h
+++ b/src/TNL/Devices/Cuda_impl.h
@@ -23,7 +23,7 @@ namespace Devices {
 
 inline String Cuda::getDeviceType()
 {
-   return String( "Cuda" );
+   return String( "Devices::Cuda" );
 }
 
 inline void
diff --git a/src/TNL/Devices/Host.h b/src/TNL/Devices/Host.h
index 6b56302a248d98182c030ed3eb1c846a051ccd7f..98b95f2f659d364897910c96461f52a42a45ca91 100644
--- a/src/TNL/Devices/Host.h
+++ b/src/TNL/Devices/Host.h
@@ -30,6 +30,9 @@ public:
       return String( "Devices::Host" );
    }
 
+   // TODO: Remove getDeviceType();
+   static inline String getType() { return getDeviceType();};
+
    static void disableOMP()
    {
       ompEnabled = false;
diff --git a/src/TNL/Devices/MIC.h b/src/TNL/Devices/MIC.h
index 373e838f72634a8f34440556ff66b7ac51ddeb0a..db1a238097f12cdaf3a2076b030baebe50d94eaf 100644
--- a/src/TNL/Devices/MIC.h
+++ b/src/TNL/Devices/MIC.h
@@ -69,11 +69,14 @@ class MIC
 {
    public:
 
-        static String getDeviceType()
-        {
-            return String( "Devices::MIC" );
-        };
-
+      static String getDeviceType()
+      {
+         return String( "Devices::MIC" );
+      };
+
+      // TODO: Remove getDeviceType();
+      static inline String getType() { return getDeviceType(); };
+        
 #ifdef HAVE_MIC
 
        //useful debuging -- but produce warning
diff --git a/src/TNL/Exceptions/ArrayWrongSize.h b/src/TNL/Exceptions/ArrayWrongSize.h
new file mode 100644
index 0000000000000000000000000000000000000000..8181b3c557e176ab530d8b5f33a8c53896e09a73
--- /dev/null
+++ b/src/TNL/Exceptions/ArrayWrongSize.h
@@ -0,0 +1,32 @@
+/***************************************************************************
+                          ArrayWrongSize.h  -  description
+                             -------------------
+    begin                : Mar 8, 2019
+    copyright            : (C) 2019 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Tomas Oberhuber
+
+#pragma once
+
+#include <string>
+#include <stdexcept>
+#include <TNL/String.h>
+
+namespace TNL {
+namespace Exceptions {
+
+class ArrayWrongSize
+   : public std::runtime_error
+{
+public:
+   ArrayWrongSize( std::size_t size, const String& mesg = "" )
+   : std::runtime_error( "Wrong array size " + convertToString( size ) + ". " + mesg )
+   {}
+};
+
+} // namespace Exceptions
+} // namespace TNL
diff --git a/src/TNL/Exceptions/MeshFunctionDataMismatch.h b/src/TNL/Exceptions/MeshFunctionDataMismatch.h
new file mode 100644
index 0000000000000000000000000000000000000000..6106db872a3eacb5edbc73290f192a2e1e40d392
--- /dev/null
+++ b/src/TNL/Exceptions/MeshFunctionDataMismatch.h
@@ -0,0 +1,32 @@
+/***************************************************************************
+                          MeshFunctionDataMismatch.h  -  description
+                             -------------------
+    begin                : Mar 8, 2019
+    copyright            : (C) 2019 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Tomas Oberhuber
+
+#pragma once
+
+#include <string>
+#include <stdexcept>
+#include <TNL/String.h>
+
+namespace TNL {
+namespace Exceptions {
+
+class MeshFunctionDataMismatch
+   : public std::runtime_error
+{
+public:
+   MeshFunctionDataMismatch( std::size_t size, const String& mesg = "" )
+   : std::runtime_error( "Mesh function data size " + convertToString( size ) + " mismatch." + mesg )
+   {}
+};
+
+} // namespace Exceptions
+} // namespace TNL
diff --git a/src/TNL/Exceptions/NotTNLFile.h b/src/TNL/Exceptions/NotTNLFile.h
new file mode 100644
index 0000000000000000000000000000000000000000..ce2d756a533133a068254ad2428fc49c243dd4b5
--- /dev/null
+++ b/src/TNL/Exceptions/NotTNLFile.h
@@ -0,0 +1,31 @@
+/***************************************************************************
+                          NotTNLFile.h  -  description
+                             -------------------
+    begin                : Mar 4, 2019
+    copyright            : (C) 2019 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Tomas Oberhuber
+
+#pragma once
+
+#include <string>
+#include <stdexcept>
+
+namespace TNL {
+namespace Exceptions {
+
+class NotTNLFile
+   : public std::runtime_error
+{
+public:
+   NotTNLFile()
+   : std::runtime_error( "Wrong magic number found in a binary file. It is not TNL compatible file." )
+   {}
+};
+
+} // namespace Exceptions
+} // namespace TNL
diff --git a/src/TNL/Exceptions/ObjectTypeDetectionFailure.h b/src/TNL/Exceptions/ObjectTypeDetectionFailure.h
new file mode 100644
index 0000000000000000000000000000000000000000..6381c2fd73f36287b7585f1f067aad5af0deeb41
--- /dev/null
+++ b/src/TNL/Exceptions/ObjectTypeDetectionFailure.h
@@ -0,0 +1,31 @@
+/***************************************************************************
+                          ObjectTypeDetectionFailure.h  -  description
+                             -------------------
+    begin                : Mar 4, 2019
+    copyright            : (C) 2019 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Tomas Oberhuber
+
+#pragma once
+
+#include <string>
+#include <stdexcept>
+
+namespace TNL {
+namespace Exceptions {
+
+class ObjectTypeDetectionFailure
+   : public std::runtime_error
+{
+public:
+   ObjectTypeDetectionFailure( const String& fileName, const String& objectType )
+   : std::runtime_error( "Failed to detect " + objectType + " in file " + fileName + "." )
+   {}
+};
+
+} // namespace Exceptions
+} // namespace TNL
diff --git a/src/TNL/Exceptions/ObjectTypeMismatch.h b/src/TNL/Exceptions/ObjectTypeMismatch.h
new file mode 100644
index 0000000000000000000000000000000000000000..9b48fd0ea3a0fcfcb12d804bc41485a9f342e261
--- /dev/null
+++ b/src/TNL/Exceptions/ObjectTypeMismatch.h
@@ -0,0 +1,32 @@
+/***************************************************************************
+                          ObjectTypeMismatch.h  -  description
+                             -------------------
+    begin                : Mar 8, 2019
+    copyright            : (C) 2019 by Tomas Oberhuber et al.
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+// Implemented by: Tomas Oberhuber
+
+#pragma once
+
+#include <string>
+#include <stdexcept>
+#include <TNL/String.h>
+
+namespace TNL {
+namespace Exceptions {
+
+class ObjectTypeMismatch
+   : public std::runtime_error
+{
+public:
+   ObjectTypeMismatch( const String& expected, const String& detected )
+   : std::runtime_error( "Object type mismatch. Expected object type is " + expected + " but " + detected + " was detcted." )
+   {}
+};
+
+} // namespace Exceptions
+} // namespace TNL
diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalProblem_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalProblem_impl.h
index 7c65ef94d4818c2fe6b5b703dfe390f23ea37d21..7437803e262b517632d43c590f485b5e923b2698 100644
--- a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalProblem_impl.h
+++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalProblem_impl.h
@@ -128,9 +128,15 @@ setInitialCondition( const Config::ParameterContainer& parameters,
   }
   else
   {
-    if( !this->initialData->boundLoad( inputFile ) )
-      std::cerr << "I am not able to load the initial condition from the file " << inputFile << "." << std::endl;
-    return false;
+      try
+      {
+          this->initialData->boundLoad( inputFile );
+      }
+      catch(...)
+      {
+         std::cerr << "I am not able to load the initial condition from the file " << inputFile << "." << std::endl;
+         return false;
+      }
   }
   return true;
 }
diff --git a/src/TNL/File.h b/src/TNL/File.h
index 178ce95858a50954ea05c34649084dd368fc9243..120d7342dd2d3151c864e3c68daf864a81679e37 100644
--- a/src/TNL/File.h
+++ b/src/TNL/File.h
@@ -20,143 +20,193 @@
 
 namespace TNL {
 
-/// \brief Supported modes for opening \ref TNL::File "files".
-enum class IOMode
-{
-//   undefined = 0,
-   read = 1,
-   write = 2
-};
-
-/* When we need to transfer data between the GPU and the CPU we use
- * 5 MB buffer. This size should ensure good performance -- see.
- * http://wiki.accelereyes.com/wiki/index.php/GPU_Memory_Transfer
- * Similar constant is defined in tnlLonegVectorCUDA
+/**
+ * \brief This class serves for binary IO. It allows to do IO even for data allocated on GPU together with on-the-fly data type conversion.
+ *
+ * \par Example
+ * \include FileExample.cpp
+ * \par Output
+ * \include FileExample.out
  */
-static constexpr std::streamsize FileGPUvsCPUTransferBufferSize = 5 * 2<<20;
-
-
-///\brief Class file is aimed mainly for saving and loading binary data.
-///
-/// \par Example
-/// \include FileExample.cpp
-// \par Output
-// \include FileExample.out
 class File
 {
-   std::fstream file;
-   String fileName;
-
-public:
-   /// \brief Basic constructor.
-   File() = default;
-
-   /////
-   /// \brief Attempts to open given file and returns \e true after the file is
-   /// successfully opened. Otherwise returns \e false.
-   ///
-   /// Opens file with given \e fileName and returns true/false based on the success in opening the file.
-   /// \param fileName String which indicates name of the file user wants to open.
-   /// \param mode Indicates what user needs to do with opened file.
-   bool open( const String& fileName,
-              const IOMode mode );
-
-   /// \brief Attempts to close given file and returns \e true when the file is
-   /// successfully closed. Otherwise returns \e false.
-   bool close();
-
-   /// \brief Returns name of given file.
-   const String& getFileName() const
-   {
-      return this->fileName;
-   }
-
-   /// \brief Method that can write particular data type from given file into GPU. (Function that gets particular elements from given file.)
-   ///
-   /// Returns \e true when the elements are successfully read from given file. Otherwise returns \e false.
-   ///
-   /// Throws \ref std::ios_base::failure on failure.
-   ///
-   /// \tparam Type Type of data.
-   /// \tparam Device Place where data are stored after reading from file. For example \ref Devices::Host or \ref Devices::Cuda.
-   /// \tparam Index Type of index by which the elements are indexed.
-   /// \param buffer Pointer in memory where the elements are loaded and stored after reading.
-   /// \param elements Number of elements the user wants to get (read) from given file.
-   template< typename Type, typename Device = Devices::Host >
-   bool read( Type* buffer, std::streamsize elements );
-
-   // Toto je treba??
-   template< typename Type, typename Device = Devices::Host >
-   bool read( Type* buffer );
-
-   /// \brief Method that can write particular data type from CPU into given file. (Function that writes particular elements into given file.)
-   ///
-   /// Returns \e true when the elements are successfully written into given file. Otherwise returns \e false.
-   ///
-   /// Throws \ref std::ios_base::failure on failure.
-   ///
-   /// \tparam Type Type of data.
-   /// \tparam Device Place from where the data are loaded before writing into file. For example \ref Devices::Host or \ref Devices::Cuda.
-   /// \tparam Index Type of index by which the elements are indexed.
-   /// \param buffer Pointer in memory where the elements are loaded from before writing into file.
-   /// \param elements Number of elements the user wants to write into the given file.
-   template< typename Type, typename Device = Devices::Host >
-   bool write( const Type* buffer, std::streamsize elements );
-
-   // Toto je treba?
-   template< typename Type, typename Device = Devices::Host >
-   bool write( const Type* buffer );
-
-protected:
-   template< typename Type,
-             typename Device,
-             typename = typename std::enable_if< std::is_same< Device, Devices::Host >::value >::type >
-   bool read_impl( Type* buffer, std::streamsize elements );
-
-   template< typename Type,
-             typename Device,
-             typename = typename std::enable_if< std::is_same< Device, Devices::Cuda >::value >::type,
-             typename = void >
-   bool read_impl( Type* buffer, std::streamsize elements );
-
-   template< typename Type,
-             typename Device,
-             typename = typename std::enable_if< std::is_same< Device, Devices::MIC >::value >::type,
-             typename = void,
-             typename = void >
-   bool read_impl( Type* buffer, std::streamsize elements );
-
-   template< typename Type,
-             typename Device,
-             typename = typename std::enable_if< std::is_same< Device, Devices::Host >::value >::type >
-   bool write_impl( const Type* buffer, std::streamsize elements );
-
-   template< typename Type,
-             typename Device,
-             typename = typename std::enable_if< std::is_same< Device, Devices::Cuda >::value >::type,
-             typename = void >
-   bool write_impl( const Type* buffer, std::streamsize elements );
-
-   template< typename Type,
-             typename Device,
-             typename = typename std::enable_if< std::is_same< Device, Devices::MIC >::value >::type,
-             typename = void,
-             typename = void >
-   bool write_impl( const Type* buffer, std::streamsize elements );
+   public:
+
+      /**
+       * This enum defines mode for opening files.
+       */
+      enum class Mode
+      {
+         In = 1,       ///< Open for input.
+         Out = 2,      ///< Open for output.
+         Append = 4,   ///< Output operations are appended at the end of file.
+         AtEnd = 8,    ///< Set the initial position at the end.
+         Truncate = 16 ///< If the file is opened for ouptput, its previous content is deleted.
+      };
+      
+      /**
+       * \brief Basic constructor.
+       */
+      File() = default;
+
+      /**
+       * \brief Open given file.
+       *
+       * Opens file with given \e fileName in some \e mode from \ref File::Mode.
+       * 
+       * Throws \ref std::ios_base::failure on failure.
+       * 
+       * \param fileName String which indicates file name.
+       * \param mode Indicates in what mode the file will be opened - see. \ref File::Mode.
+       */
+      void open( const String& fileName,
+                 Mode mode = static_cast< Mode >( static_cast< int >( Mode::In ) | static_cast< int >( Mode::Out ) ) );
+
+      /**
+       * \brief Closes the file.
+       * 
+       * Throws \ref std::ios_base::failure on failure.
+       */
+      void close();
+
+      /**
+       * \brief Returns name of the file.
+       */
+      const String& getFileName() const
+      {
+         return this->fileName;
+      }
+
+      /**
+       * \brief Method for loading data from the file.
+       *
+       * The data will be stored in \e buffer allocated on device given by the
+       * \e Device parameter. The data type of the buffer is given by the
+       * template parameter \e Type. The second template parameter 
+       * \e SourceType defines the type of data in the source file. If both
+       * types are different, on-the-fly conversion takes place during the
+       * data loading.
+       *
+       * Throws \ref std::ios_base::failure on failure.
+       *
+       * \tparam Type type of data to be loaded to the \e buffer.
+       * \tparam SourceType type of data stored on the file,
+       * \tparam Device device where the data are stored after reading. For example \ref Devices::Host or \ref Devices::Cuda.
+       * \param buffer Pointer in memory where the elements are loaded and stored after reading.
+       * \param elements number of elements to be loaded from the file.
+       * 
+       * The following example shows how to load data directly to GPU.
+       * 
+       * \par Example
+       * \include FileExampleCuda.cpp
+       * \par Output
+       * \include FileExampleCuda.out
+       * The following example shows how to do on-the-fly data conversion.
+       * 
+       * \par Example
+       * \include FileExampleSaveAndLoad.cpp
+       * \par Output
+       * \include FileExampleSaveAndLoad.out
+       */
+      template< typename Type, typename SourceType = Type, typename Device = Devices::Host >
+      void load( Type* buffer, std::streamsize elements = 1 );
+
+      /**
+       * \brief Method for saving data to the file.
+       *
+       * The data from the \e buffer (with type \e Type) allocated on the device
+       * \e Device will be saved into the file. \e TargetType defines as what
+       * data type the buffer shall be saved. If the type is different from the
+       * data type, on-the-fly data type conversion takes place during the data
+       * saving.
+       *
+       * Throws \ref std::ios_base::failure on failure.
+       *
+       * \tparam Type type of data in the \e buffer.
+       * \tparam TargetType tells as what type data the buffer shall be saved.
+       * \tparam Device device from where the data are loaded before writing into file. For example \ref Devices::Host or \ref Devices::Cuda.
+       * \tparam Index type of index by which the elements are indexed.
+       * \param buffer buffer that is going to be saved to the file.
+       * \param elements number of elements saved to the file.
+       * 
+       * See \ref File::load for examples.
+       */
+      template< typename Type, typename TargetType = Type, typename Device = Devices::Host >
+      void save( const Type* buffer, std::streamsize elements = 1 );
+
+   protected:
+      template< typename Type,
+                typename SourceType,
+                typename Device,
+                typename = typename std::enable_if< std::is_same< Device, Devices::Host >::value >::type >
+      void load_impl( Type* buffer, std::streamsize elements );
+
+      template< typename Type,
+                typename SourceType,
+                typename Device,
+                typename = typename std::enable_if< std::is_same< Device, Devices::Cuda >::value >::type,
+                typename = void >
+      void load_impl( Type* buffer, std::streamsize elements );
+
+      template< typename Type,
+                typename SourceType,
+                typename Device,
+                typename = typename std::enable_if< std::is_same< Device, Devices::MIC >::value >::type,
+                typename = void,
+                typename = void >
+      void load_impl( Type* buffer, std::streamsize elements );
+
+      template< typename Type,
+                typename TargetType,
+                typename Device,
+                typename = typename std::enable_if< std::is_same< Device, Devices::Host >::value >::type >
+      void save_impl( const Type* buffer, std::streamsize elements );
+
+      template< typename Type,
+                typename TargetType,
+                typename Device,
+                typename = typename std::enable_if< std::is_same< Device, Devices::Cuda >::value >::type,
+                typename = void >
+      void save_impl( const Type* buffer, std::streamsize elements );
+
+      template< typename Type,
+                typename TargetType,
+                typename Device,
+                typename = typename std::enable_if< std::is_same< Device, Devices::MIC >::value >::type,
+                typename = void,
+                typename = void >
+      void save_impl( const Type* buffer, std::streamsize elements );
+
+      std::fstream file;
+      String fileName;
+
+      ////
+      // When we transfer data between the GPU and the CPU we use 5 MB buffer. This
+      // size should ensure good performance -- see.
+      // http://wiki.accelereyes.com/wiki/index.php/GPU_Memory_Transfer .
+      // We use the same buffer size even for retyping data during IO operations.
+      //
+      static constexpr std::streamsize TransferBufferSize = 5 * 2<<20;
 };
 
-/// Returns true if the file exists and false otherwise.
-///
-/// Finds out if the file \e fileName exists.
-/// \param fileName Name of the file that user wants to find in the PC.
+/**
+ * \brief Returns true if the file exists and false otherwise.
+ *
+ * Finds out if the file \e fileName exists.
+ * \param fileName Name of the file to check.
+ * \return returns true if the file exists and false othervise
+ */
 bool fileExists( const String& fileName );
 
-// serialization of strings
+/**
+ * \brief Serialization of strings
+ */
 File& operator<<( File& file, const std::string& str );
 
-// deserialization of strings
+/**
+ * \brief Deserialization of strings.
+ */
 File& operator>>( File& file, std::string& str );
-
 } // namespace TNL
 
-#include <TNL/File_impl.h>
+#include <TNL/File.hpp>
diff --git a/src/TNL/File.hpp b/src/TNL/File.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..df1181af7e1a13238418d23562c7377982f347d1
--- /dev/null
+++ b/src/TNL/File.hpp
@@ -0,0 +1,426 @@
+/***************************************************************************
+                          File_impl.h  -  description
+                             -------------------
+    begin                : Mar 5, Oct 2016
+    copyright            : (C) 2016 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <memory>
+#include <iostream>
+#include <ios>
+#include <sstream>
+
+#include <TNL/File.h>
+#include <TNL/Assert.h>
+#include <TNL/Exceptions/CudaSupportMissing.h>
+#include <TNL/Exceptions/MICSupportMissing.h>
+#include <TNL/Exceptions/FileSerializationError.h>
+#include <TNL/Exceptions/FileDeserializationError.h>
+
+namespace TNL {
+
+inline File::Mode operator|( File::Mode m1, File::Mode m2 );
+
+inline bool operator&( File::Mode m1, File::Mode m2 );
+
+inline void File::open( const String& fileName, Mode mode )
+{
+   // enable exceptions
+   file.exceptions( std::fstream::failbit | std::fstream::badbit | std::fstream::eofbit );
+
+   close();
+
+   auto ios_mode = std::ios::binary;
+   if( mode & Mode::In ) ios_mode |= std::ios::in;
+   if( mode & Mode::Out ) ios_mode |= std::ios::out;
+   if( mode & Mode::Append ) ios_mode |= std::ios::app;
+   if( mode & Mode::AtEnd ) ios_mode |= std::ios::ate;
+   if( mode & Mode::Truncate ) ios_mode |= std::ios::trunc;
+   try
+   {
+      file.open( fileName.getString(), ios_mode );
+   }
+   catch( std::ios_base::failure& )
+   {
+      std::stringstream msg;
+      msg <<  "Unable to open file " << fileName << " ";
+      if( mode & Mode::In )
+         msg << " for reading.";
+      if( mode & Mode::Out )
+         msg << " for writing.";
+
+      throw std::ios_base::failure( msg.str() );
+   }
+
+   this->fileName = fileName;
+}
+
+inline void File::close()
+{
+   if( file.is_open() )
+   {
+      try
+      {
+         file.close();
+      }
+      catch( std::ios_base::failure& )
+      {
+         std::stringstream msg;
+         msg <<  "Unable to close file " << fileName << ".";
+
+         throw std::ios_base::failure( msg.str() );
+      }
+   }
+   // reset file name
+   fileName = "";
+}
+
+template< typename Type,
+          typename SourceType,
+          typename Device >
+void File::load( Type* buffer, std::streamsize elements )
+{
+   TNL_ASSERT_GE( elements, 0, "Number of elements to load must be non-negative." );
+
+   if( ! elements )
+      return;
+
+   load_impl< Type, SourceType, Device >( buffer, elements );
+}
+
+// Host
+template< typename Type,
+          typename SourceType,
+          typename Device,
+          typename >
+void File::load_impl( Type* buffer, std::streamsize elements )
+{
+   if( std::is_same< Type, SourceType >::value )
+      file.read( reinterpret_cast<char*>(buffer), sizeof(Type) * elements );
+   else
+   {
+      const std::streamsize cast_buffer_size = std::min( TransferBufferSize / (std::streamsize) sizeof(SourceType), elements );
+      using BaseType = typename std::remove_cv< SourceType >::type;
+      std::unique_ptr< BaseType[] > cast_buffer{ new BaseType[ cast_buffer_size ] };
+      std::streamsize readElements = 0;
+      while( readElements < elements )
+      {
+         const std::streamsize transfer = std::min( elements - readElements, cast_buffer_size );
+         file.read( reinterpret_cast<char*>(cast_buffer.get()), sizeof(SourceType) * transfer );
+         for( std::streamsize i = 0; i < transfer; i++ )
+            buffer[ readElements ++ ] = static_cast< Type >( cast_buffer[ i ] );
+         readElements += transfer;
+      }
+   }
+}
+
+// Cuda
+template< typename Type,
+          typename SourceType,
+          typename Device,
+          typename, typename >
+void File::load_impl( Type* buffer, std::streamsize elements )
+{
+#ifdef HAVE_CUDA
+   const std::streamsize host_buffer_size = std::min( TransferBufferSize / (std::streamsize) sizeof(Type), elements );
+   using BaseType = typename std::remove_cv< Type >::type;
+   std::unique_ptr< BaseType[] > host_buffer{ new BaseType[ host_buffer_size ] };
+
+   std::streamsize readElements = 0;
+   if( std::is_same< Type, SourceType >::value )
+   {
+      while( readElements < elements )
+      {
+         const std::streamsize transfer = std::min( elements - readElements, host_buffer_size );
+         file.read( reinterpret_cast<char*>(host_buffer.get()), sizeof(Type) * transfer );
+         cudaMemcpy( (void*) &buffer[ readElements ],
+                     (void*) host_buffer.get(),
+                     transfer * sizeof( Type ),
+                     cudaMemcpyHostToDevice );
+         TNL_CHECK_CUDA_DEVICE;
+         readElements += transfer;
+      }
+   }
+   else
+   {
+      const std::streamsize cast_buffer_size = std::min( TransferBufferSize / (std::streamsize) sizeof(SourceType), elements );
+      using BaseType = typename std::remove_cv< SourceType >::type;
+      std::unique_ptr< BaseType[] > cast_buffer{ new BaseType[ cast_buffer_size ] };
+
+      while( readElements < elements )
+      {
+         const std::streamsize transfer = std::min( elements - readElements, cast_buffer_size );
+         file.read( reinterpret_cast<char*>(cast_buffer.get()), sizeof(SourceType) * transfer );
+         for( std::streamsize i = 0; i < transfer; i++ )
+            host_buffer[ i ] = static_cast< Type >( cast_buffer[ i ] );
+         cudaMemcpy( (void*) &buffer[ readElements ],
+                     (void*) host_buffer.get(),
+                     transfer * sizeof( Type ),
+                     cudaMemcpyHostToDevice );
+         TNL_CHECK_CUDA_DEVICE;
+         readElements += transfer;
+      }
+   }
+#else
+   throw Exceptions::CudaSupportMissing();
+#endif
+}
+
+// MIC
+template< typename Type,
+          typename SourceType,
+          typename Device,
+          typename, typename, typename >
+void File::load_impl( Type* buffer, std::streamsize elements )
+{
+#ifdef HAVE_MIC
+   const std::streamsize host_buffer_size = std::min( TransferBufferSize / (std::streamsize) sizeof(Type), elements );
+   using BaseType = typename std::remove_cv< Type >::type;
+   std::unique_ptr< BaseType[] > host_buffer{ new BaseType[ host_buffer_size ] };
+
+   std::streamsize readElements = 0;
+   if( std::is_same< Type, SourceType >::value )
+   {
+      while( readElements < elements )
+      {
+         const std::streamsize transfer = std::min( elements - readElements, host_buffer_size );
+         file.read( reinterpret_cast<char*>(host_buffer.get()), sizeof(Type) * transfer );
+
+         Devices::MICHider<Type> device_buff;
+         device_buff.pointer=buffer;
+         #pragma offload target(mic) in(device_buff,readElements) in(host_buffer:length(transfer))
+         {
+            /*
+            for(int i=0;i<transfer;i++)
+                 device_buff.pointer[readElements+i]=host_buffer[i];
+             */
+            memcpy(&(device_buff.pointer[readElements]), host_buffer.get(), transfer*sizeof(Type) );
+         }
+
+         readElements += transfer;
+      }
+      free( host_buffer );
+   }
+   else
+   {
+      std::cerr << "Type conversion during loading is not implemented for MIC." << std::endl;
+      abort();
+   }
+#else
+   throw Exceptions::MICSupportMissing();
+#endif
+}
+
+template< typename Type,
+          typename TargetType,
+          typename Device >
+void File::save( const Type* buffer, std::streamsize elements )
+{
+   TNL_ASSERT_GE( elements, 0, "Number of elements to save must be non-negative." );
+
+   if( ! elements )
+      return;
+
+   save_impl< Type, TargetType, Device >( buffer, elements );
+}
+
+// Host
+template< typename Type,
+          typename TargetType,
+          typename Device,
+          typename >
+void File::save_impl( const Type* buffer, std::streamsize elements )
+{
+   if( std::is_same< Type, TargetType >::value )
+      file.write( reinterpret_cast<const char*>(buffer), sizeof(Type) * elements );
+   else
+   {
+      const std::streamsize cast_buffer_size = std::min( TransferBufferSize / (std::streamsize) sizeof(TargetType), elements );
+      using BaseType = typename std::remove_cv< TargetType >::type;
+      std::unique_ptr< BaseType[] > cast_buffer{ new BaseType[ cast_buffer_size ] };
+      std::streamsize writtenElements = 0;
+      while( writtenElements < elements )
+      {
+         const std::streamsize transfer = std::min( elements - writtenElements, cast_buffer_size );
+         for( std::streamsize i = 0; i < transfer; i++ )
+            cast_buffer[ i ] = static_cast< TargetType >( buffer[ writtenElements ++ ] );
+         file.write( reinterpret_cast<char*>(cast_buffer.get()), sizeof(TargetType) * transfer );
+         writtenElements += transfer;
+      }
+
+   }
+}
+
+// Cuda
+template< typename Type,
+          typename TargetType,
+          typename Device,
+          typename, typename >
+void File::save_impl( const Type* buffer, std::streamsize elements )
+{
+#ifdef HAVE_CUDA
+   const std::streamsize host_buffer_size = std::min( TransferBufferSize / (std::streamsize) sizeof(Type), elements );
+   using BaseType = typename std::remove_cv< Type >::type;
+   std::unique_ptr< BaseType[] > host_buffer{ new BaseType[ host_buffer_size ] };
+
+   std::streamsize writtenElements = 0;
+   if( std::is_same< Type, TargetType >::value )
+   {
+      while( writtenElements < elements )
+      {
+         const std::streamsize transfer = std::min( elements - writtenElements, host_buffer_size );
+         cudaMemcpy( (void*) host_buffer.get(),
+                     (void*) &buffer[ writtenElements ],
+                     transfer * sizeof(Type),
+                     cudaMemcpyDeviceToHost );
+         TNL_CHECK_CUDA_DEVICE;
+         file.write( reinterpret_cast<const char*>(host_buffer.get()), sizeof(Type) * transfer );
+         writtenElements += transfer;
+      }
+   }
+   else
+   {
+      const std::streamsize cast_buffer_size = std::min( TransferBufferSize / (std::streamsize) sizeof(TargetType), elements );
+      using BaseType = typename std::remove_cv< TargetType >::type;
+      std::unique_ptr< BaseType[] > cast_buffer{ new BaseType[ cast_buffer_size ] };
+
+      while( writtenElements < elements )
+      {
+         const std::streamsize transfer = std::min( elements - writtenElements, host_buffer_size );
+         cudaMemcpy( (void*) host_buffer.get(),
+                     (void*) &buffer[ writtenElements ],
+                     transfer * sizeof(Type),
+                     cudaMemcpyDeviceToHost );
+         TNL_CHECK_CUDA_DEVICE;
+         for( std::streamsize i = 0; i < transfer; i++ )
+            cast_buffer[ i ] = static_cast< TargetType >( host_buffer[ i ] );
+
+         file.write( reinterpret_cast<const char*>(cast_buffer.get()), sizeof(TargetType) * transfer );
+         writtenElements += transfer;
+      }
+   }
+#else
+   throw Exceptions::CudaSupportMissing();
+#endif
+}
+
+// MIC
+template< typename Type,
+          typename TargetType,
+          typename Device,
+          typename, typename, typename >
+void File::save_impl( const Type* buffer, std::streamsize elements )
+{
+#ifdef HAVE_MIC
+   const std::streamsize host_buffer_size = std::min( TransferBufferSize / (std::streamsize) sizeof(Type), elements );
+   using BaseType = typename std::remove_cv< Type >::type;
+   std::unique_ptr< BaseType[] > host_buffer{ new BaseType[ host_buffer_size ] };
+
+   std::streamsize writtenElements = 0;
+   if( std::is_same< Type, TargetType >::value )
+   {
+      while( this->writtenElements < elements )
+      {
+         const std::streamsize transfer = std::min( elements - writtenElements, host_buffer_size );
+
+         Devices::MICHider<const Type> device_buff;
+         device_buff.pointer=buffer;
+         #pragma offload target(mic) in(device_buff,writtenElements) out(host_buffer:length(transfer))
+         {
+            //THIS SHOULD WORK... BUT NOT WHY?
+            /*for(int i=0;i<transfer;i++)
+                 host_buffer[i]=device_buff.pointer[writtenElements+i];
+             */
+
+            memcpy(host_buffer.get(), &(device_buff.pointer[writtenElements]), transfer*sizeof(Type) );
+         }
+
+         file.write( reinterpret_cast<const char*>(host_buffer.get()), sizeof(Type) * transfer );
+         writtenElements += transfer;
+      }
+   }
+   else
+   {
+      std::cerr << "Type conversion during saving is not implemented for MIC." << std::endl;
+      abort();
+   }
+#else
+   throw Exceptions::MICSupportMissing();
+#endif
+}
+
+inline bool fileExists( const String& fileName )
+{
+   std::fstream file;
+   file.open( fileName.getString(), std::ios::in );
+   return ! file.fail();
+}
+
+
+// serialization of strings
+inline File& operator<<( File& file, const std::string& str )
+{
+   const int len = str.size();
+   try
+   {
+       file.save( &len );
+   }
+   catch(...)
+   {
+      throw Exceptions::FileSerializationError( getType< int >(), file.getFileName() );
+   }
+   try
+   {
+      file.save( str.c_str(), len );
+   }
+   catch(...)
+   {
+      throw Exceptions::FileSerializationError( "String", file.getFileName() );
+   }
+   return file;
+}
+
+// deserialization of strings
+inline File& operator>>( File& file, std::string& str )
+{
+   int length;
+   try
+   {
+      file.load( &length );
+   }
+   catch(...)
+   {
+      throw Exceptions::FileDeserializationError( getType< int >(), file.getFileName() );
+   }
+   char buffer[ length ];
+   if( length )
+   {
+      try
+      {
+         file.load( buffer, length );
+      }
+      catch(...)
+      {
+         throw Exceptions::FileDeserializationError( "String", file.getFileName() );
+      }
+   }
+   str.assign( buffer, length );
+   return file;
+}
+
+inline File::Mode operator|( File::Mode m1, File::Mode m2 )
+{
+   return static_cast< File::Mode >( static_cast< int >( m1 ) | static_cast< int >( m2 ) );
+}
+
+inline bool operator&( File::Mode m1, File::Mode m2 )
+{
+   return static_cast< bool >( static_cast< int >( m1 ) & static_cast< int >( m2 ) );
+}
+
+} // namespace TNL
diff --git a/src/TNL/FileName.h b/src/TNL/FileName.h
index 2c860770d47b4a2f55a7c23d1ad4d5b5d3627cbc..0f4950ae82ffec79f2c7f314d71c1921706913dc 100644
--- a/src/TNL/FileName.h
+++ b/src/TNL/FileName.h
@@ -14,70 +14,144 @@
 
 namespace TNL {
 
-String getFileExtension( const String fileName );
-
-void removeFileExtension( String& file_name );
-
-/// \brief Class for the construction of file names from multiple parts.
-///
-/// Merges base name, index number and extention to create the full name of a file.
+/**
+ * \brief Helper class for the construction of file names based on name, index and extension.
+ *
+ * Optionally, the file name can also handle node ID for distributed systems.
+ * 
+ * The following example demonstrates the use of FileName.
+ * 
+ * \par Example
+ * \include FileNameExample.cpp
+ * \par Output
+ * \include FileNameExample.out
+ */
 class FileName
 {
    public:
 
-      /// \brief Basic constructor.
-      ///
-      /// Constructs an empty filename object.
+      /**
+       * \brief Basic constructor.
+       *
+       * Sets no file name base, index to zero and index digits count to five;
+       */
       FileName();
-      
+
+      /**
+       * \brief Constructor with file name base parameter.
+       * 
+       * The index is set to zero and index digits count to five.
+       * 
+       * @param fileNameBase File name base.
+       */
       FileName( const String& fileNameBase );
-      
-      FileName( const String& fileNameBase, 
+
+      /**
+       * \brief Constructor with file name base and file name extension.
+       * 
+       * The index is set to zero and index digits count to five.
+       * 
+       * @param fileNameBase File name base.
+       * @param extension File name extension.
+       */
+      FileName( const String& fileNameBase,
                 const String& extension );
-      
-      /// \brief Sets the base name of given file.
-      ///
-      /// Sets \e fileNameBase as the base name of given file.
-      /// @param fileNameBase String that specifies new name of file.
+
+      /**
+       * \brief Sets the file name base.
+       *
+       * @param fileNameBase String that specifies the new file name base.
+       */
       void setFileNameBase( const String& fileNameBase );
 
-      /// \brief Sets the extension of given file.
-      ///
-      /// Sets \e extension as suffix of a file name.
-      /// @param extension A String that specifies extension of file (without dot).
-      /// Suffix of a file name. E.g. doc, xls, tnl.
+      /**
+       *  \brief Sets the file name extension.
+       *
+       * @param extension A String that specifies the new extension of file without dot.
+       */
       void setExtension( const String& extension );
 
-      /// \brief Sets index for given file.
-      ///
-      /// Sets \e index after the base name of given file.
-      /// @param index Integer - number of maximum 5(default) digits.
-      /// (Number of digits can be changed with \ref setDigitsCount).
-      void setIndex( const int index );
-
-      /// \brief Sets number of digits for index of given file.
-      ///
-      /// @param digitsCount Integer - number of digits.
-      void setDigitsCount( const int digitsCount );
-      
-      void setDistributedSystemNodeId( int nodeId );
-      
+      /**
+       * \brief Sets index of the file name.
+       *
+       * @param index Index of the file name.
+       */
+      void setIndex( const size_t index );
+
+      /**
+       * \brief Sets number of digits for index of the file name.
+       *
+       * @param digitsCount Number of digits. It is 5 by default.
+       */
+      void setDigitsCount( const size_t digitsCount );
+
+      /**
+       * \brief Sets the distributed system node ID as integer, for example MPI process ID.
+       * 
+       * @param nodeId Node ID.
+       * 
+       * See the following example:
+       * 
+       * \par Example
+       * \include FileNameExampleDistributedSystemNodeId.cpp
+       * \par Output
+       * \include FileNameExampleDistributedSystemNodeId.out
+       */
+      void setDistributedSystemNodeId( size_t nodeId );
+
+      /**
+       * \brief Sets the distributed system node ID in a form of Cartesian coordinates.
+       * 
+       * @tparam Coordinates Type of Cartesian coordinates. It is Containers::StaticVector usually.
+       * @param nodeId Node ID in a form of Cartesian coordinates.
+       * 
+       * See the following example:
+       * 
+       * \par Example
+       * \include FileNameExampleDistributedSystemNodeCoordinates.cpp
+       * \par Output
+       * \include FileNameExampleDistributedSystemNodeCoordinates.out
+       * 
+       */
       template< typename Coordinates >
-      void setDistributedSystemNodeId( const Coordinates& nodeId );
-      
-      /// \brief Creates appropriate name for given file.
-      ///
-      /// Creates particular file name using \e fileNameBase, \e digitsCount,
-      /// \e index and \e extension.
+      void setDistributedSystemNodeCoordinates( const Coordinates& nodeId );
+
+      /**
+       * \brief Resets the distributed system node ID.
+       */
+      void resetDistributedSystemNodeId();
+
+      /**
+       * \brief Returns complete file name.
+       *
+       * @return String with the complete file name.
+       */
       String getFileName();
 
    protected:
-   
+
       String fileNameBase, extension, distributedSystemNodeId;
-      
-      int index, digitsCount;
+
+      size_t index, digitsCount;
 };
 
+/**
+ * \brief Returns extension of given file name, i.e. part after the last dot.
+ * 
+ * @param fileName Input file name.
+ * 
+ * @return Extension of the given file name.
+ */
+String getFileExtension( const String fileName );
+
+/**
+ * \brief Cuts off the file extension.
+ * 
+ * @param file_name Input file name.
+ * @return String with the file name without extension.
+ */
+String removeFileNameExtension( String fileName );
+
 } // namespace TNL
 
 #include <TNL/FileName.hpp>
diff --git a/src/TNL/FileName.hpp b/src/TNL/FileName.hpp
index 4cda1fda29d5b4f74c7368ec55efc60321fdac43..5fdbf1b3f21debfd672d0e63f7ebf5c27c0b6e57 100644
--- a/src/TNL/FileName.hpp
+++ b/src/TNL/FileName.hpp
@@ -17,6 +17,8 @@
 #include <TNL/String.h>
 #include <TNL/Math.h>
 
+#include "FileName.h"
+
 namespace TNL {
 
 inline FileName::FileName()
@@ -50,28 +52,28 @@ inline void FileName::setExtension( const String& extension )
    this->extension = extension;
 }
 
-inline void FileName::setIndex( const int index )
+inline void FileName::setIndex( const size_t index )
 {
    this->index = index;
 }
 
-inline void FileName::setDigitsCount( const int digitsCount )
+inline void FileName::setDigitsCount( const size_t digitsCount )
 {
    this->digitsCount = digitsCount;
 }
 
-inline void FileName::setDistributedSystemNodeId( int nodeId )
+inline void FileName::setDistributedSystemNodeId( size_t nodeId )
 {
-   this->distributedSystemNodeId = "-";
+   this->distributedSystemNodeId = "-@";
    this->distributedSystemNodeId += convertToString( nodeId );
 }
 
 template< typename Coordinates >
 void
 FileName::
-setDistributedSystemNodeId( const Coordinates& nodeId )
+setDistributedSystemNodeCoordinates( const Coordinates& nodeId )
 {
-   this->distributedSystemNodeId = "-";
+   this->distributedSystemNodeId = "-@";
    this->distributedSystemNodeId += convertToString( nodeId[ 0 ] );
    for( int i = 1; i < nodeId.getSize(); i++ )
    {
@@ -80,6 +82,13 @@ setDistributedSystemNodeId( const Coordinates& nodeId )
    }
 }
 
+void
+FileName::
+resetDistributedSystemNodeId()
+{
+   this->distributedSystemNodeId = "";
+}
+
 inline String FileName::getFileName()
 {
    std::stringstream stream;
@@ -96,16 +105,17 @@ inline String getFileExtension( const String fileName )
 {
    const int size = fileName.getLength();
    int i = 1;
-   while( fileName[ size - i ] != '.' && size > i ) i++;
+   while( fileName[ size - i ] != '.' && i < size ) i++;
    return fileName.substr( size - i + 1 );
 }
 
-inline void removeFileExtension( String& fileName )
+inline String removeFileNameExtension( String fileName )
 {
    const int size = fileName.getLength();
    int i = 1;
    while( fileName[ size - i ] != '.' && size > i ) i++;
    fileName = fileName.substr( 0, size - i + 1 );
+   return fileName;
 }
 
 } // namespace TNL
diff --git a/src/TNL/File_impl.h b/src/TNL/File_impl.h
deleted file mode 100644
index 03c3f0d4a23cb8ba7a4972e09c0846f03bb39503..0000000000000000000000000000000000000000
--- a/src/TNL/File_impl.h
+++ /dev/null
@@ -1,277 +0,0 @@
-/***************************************************************************
-                          File_impl.h  -  description
-                             -------------------
-    begin                : Mar 5, Oct 2016
-    copyright            : (C) 2016 by Tomas Oberhuber
-    email                : tomas.oberhuber@fjfi.cvut.cz
- ***************************************************************************/
-
-/* See Copyright Notice in tnl/Copyright */
-
-#pragma once
-
-#include <memory>
-#include <iostream>
-
-#include <TNL/File.h>
-#include <TNL/Assert.h>
-#include <TNL/Exceptions/CudaSupportMissing.h>
-#include <TNL/Exceptions/MICSupportMissing.h>
-#include <TNL/Exceptions/FileSerializationError.h>
-#include <TNL/Exceptions/FileDeserializationError.h>
-
-namespace TNL {
-
-inline bool File::open( const String& fileName, const IOMode mode )
-{
-   // enable exceptions
-   file.exceptions( std::fstream::failbit | std::fstream::badbit | std::fstream::eofbit );
-
-   close();
-
-   if( mode == IOMode::read )
-      file.open( fileName.getString(), std::ios::binary | std::ios::in );
-   else
-      file.open( fileName.getString(), std::ios::binary | std::ios::out );
-
-   this->fileName = fileName;
-   if( ! file.good() ) {
-      std::cerr << "I am not able to open the file " << fileName << ". ";
-      return false;
-   }
-   return true;
-}
-
-inline bool File::close()
-{
-   if( file.is_open() ) {
-      file.close();
-      if( ! file.good() ) {
-         std::cerr << "I was not able to close the file " << fileName << " properly!" << std::endl;
-         return false;
-      }
-   }
-   // reset all attributes
-   fileName = "";
-   return true;
-}
-
-template< typename Type, typename Device >
-bool File::read( Type* buffer )
-{
-   return read< Type, Device >( buffer, 1 );
-}
-
-template< typename Type, typename Device >
-bool File::write( const Type* buffer )
-{
-   return write< Type, Device >( buffer, 1 );
-}
-
-template< typename Type, typename Device >
-bool File::read( Type* buffer, std::streamsize elements )
-{
-   TNL_ASSERT_GE( elements, 0, "Number of elements to read must be non-negative." );
-
-   if( ! elements )
-      return true;
-
-   return read_impl< Type, Device >( buffer, elements );
-}
-
-// Host
-template< typename Type,
-          typename Device,
-          typename >
-bool File::read_impl( Type* buffer, std::streamsize elements )
-{
-   file.read( reinterpret_cast<char*>(buffer), sizeof(Type) * elements );
-   return true;
-}
-
-// Cuda
-template< typename Type,
-          typename Device,
-          typename, typename >
-bool File::read_impl( Type* buffer, std::streamsize elements )
-{
-#ifdef HAVE_CUDA
-   const std::streamsize host_buffer_size = std::min( FileGPUvsCPUTransferBufferSize / (std::streamsize) sizeof(Type), elements );
-   using BaseType = typename std::remove_cv< Type >::type;
-   std::unique_ptr< BaseType[] > host_buffer{ new BaseType[ host_buffer_size ] };
-
-   std::streamsize readElements = 0;
-   while( readElements < elements )
-   {
-      const std::streamsize transfer = std::min( elements - readElements, host_buffer_size );
-      file.read( reinterpret_cast<char*>(host_buffer.get()), sizeof(Type) * transfer );
-      cudaMemcpy( (void*) &buffer[ readElements ],
-                  (void*) host_buffer.get(),
-                  transfer * sizeof( Type ),
-                  cudaMemcpyHostToDevice );
-      TNL_CHECK_CUDA_DEVICE;
-      readElements += transfer;
-   }
-   return true;
-#else
-   throw Exceptions::CudaSupportMissing();
-#endif
-}
-
-// MIC
-template< typename Type,
-          typename Device,
-          typename, typename, typename >
-bool File::read_impl( Type* buffer, std::streamsize elements )
-{
-#ifdef HAVE_MIC
-   const std::streamsize host_buffer_size = std::min( FileGPUvsCPUTransferBufferSize / (std::streamsize) sizeof(Type), elements );
-   using BaseType = typename std::remove_cv< Type >::type;
-   std::unique_ptr< BaseType[] > host_buffer{ new BaseType[ host_buffer_size ] };
-
-   std::streamsize readElements = 0;
-   while( readElements < elements )
-   {
-      const std::streamsize transfer = std::min( elements - readElements, host_buffer_size );
-      file.read( reinterpret_cast<char*>(host_buffer.get()), sizeof(Type) * transfer );
-
-      Devices::MICHider<Type> device_buff;
-      device_buff.pointer=buffer;
-      #pragma offload target(mic) in(device_buff,readElements) in(host_buffer:length(transfer))
-      {
-         /*
-         for(int i=0;i<transfer;i++)
-              device_buff.pointer[readElements+i]=host_buffer[i];
-          */
-         memcpy(&(device_buff.pointer[readElements]), host_buffer.get(), transfer*sizeof(Type) );
-      }
-
-      readElements += transfer;
-   }
-   free( host_buffer );
-   return true;
-#else
-   throw Exceptions::MICSupportMissing();
-#endif
-}
-
-template< class Type, typename Device >
-bool File::write( const Type* buffer, std::streamsize elements )
-{
-   TNL_ASSERT_GE( elements, 0, "Number of elements to write must be non-negative." );
-
-   if( ! elements )
-      return true;
-
-   return write_impl< Type, Device >( buffer, elements );
-}
-
-// Host
-template< typename Type,
-          typename Device,
-          typename >
-bool File::write_impl( const Type* buffer, std::streamsize elements )
-{
-   file.write( reinterpret_cast<const char*>(buffer), sizeof(Type) * elements );
-   return true;
-}
-
-// Cuda
-template< typename Type,
-          typename Device,
-          typename, typename >
-bool File::write_impl( const Type* buffer, std::streamsize elements )
-{
-#ifdef HAVE_CUDA
-   const std::streamsize host_buffer_size = std::min( FileGPUvsCPUTransferBufferSize / (std::streamsize) sizeof(Type), elements );
-   using BaseType = typename std::remove_cv< Type >::type;
-   std::unique_ptr< BaseType[] > host_buffer{ new BaseType[ host_buffer_size ] };
-
-   std::streamsize writtenElements = 0;
-   while( writtenElements < elements )
-   {
-      const std::streamsize transfer = std::min( elements - writtenElements, host_buffer_size );
-      cudaMemcpy( (void*) host_buffer.get(),
-                  (void*) &buffer[ writtenElements ],
-                  transfer * sizeof(Type),
-                  cudaMemcpyDeviceToHost );
-      TNL_CHECK_CUDA_DEVICE;
-      file.write( reinterpret_cast<const char*>(host_buffer.get()), sizeof(Type) * transfer );
-      writtenElements += transfer;
-   }
-   return true;
-#else
-   throw Exceptions::CudaSupportMissing();
-#endif
-}
-
-// MIC
-template< typename Type,
-          typename Device,
-          typename, typename, typename >
-bool File::write_impl( const Type* buffer, std::streamsize elements )
-{
-#ifdef HAVE_MIC
-   const std::streamsize host_buffer_size = std::min( FileGPUvsCPUTransferBufferSize / (std::streamsize) sizeof(Type), elements );
-   using BaseType = typename std::remove_cv< Type >::type;
-   std::unique_ptr< BaseType[] > host_buffer{ new BaseType[ host_buffer_size ] };
-
-   std::streamsize writtenElements = 0;
-   while( this->writtenElements < elements )
-   {
-      const std::streamsize transfer = std::min( elements - writtenElements, host_buffer_size );
-
-      Devices::MICHider<const Type> device_buff;
-      device_buff.pointer=buffer;
-      #pragma offload target(mic) in(device_buff,writtenElements) out(host_buffer:length(transfer))
-      {
-         //THIS SHOULD WORK... BUT NOT WHY?
-         /*for(int i=0;i<transfer;i++)
-              host_buffer[i]=device_buff.pointer[writtenElements+i];
-          */
-
-         memcpy(host_buffer.get(), &(device_buff.pointer[writtenElements]), transfer*sizeof(Type) );
-      }
-
-      file.write( reinterpret_cast<const char*>(host_buffer.get()), sizeof(Type) * transfer );
-      writtenElements += transfer;
-   }
-   return true;
-#else
-   throw Exceptions::MICSupportMissing();
-#endif
-}
-
-inline bool fileExists( const String& fileName )
-{
-   std::fstream file;
-   file.open( fileName.getString(), std::ios::in );
-   return ! file.fail();
-}
-
-
-// serialization of strings
-inline File& operator<<( File& file, const std::string& str )
-{
-   const int len = str.size();
-   if( ! file.write( &len ) )
-      throw Exceptions::FileSerializationError( getType< int >(), file.getFileName() );
-   if( ! file.write( str.c_str(), len ) )
-      throw Exceptions::FileSerializationError( "String", file.getFileName() );
-   return file;
-}
-
-// deserialization of strings
-inline File& operator>>( File& file, std::string& str )
-{
-   int length;
-   if( ! file.read( &length ) )
-      throw Exceptions::FileDeserializationError( getType< int >(), file.getFileName() );
-   char buffer[ length ];
-   if( length && ! file.read( buffer, length ) )
-      throw Exceptions::FileDeserializationError( "String", file.getFileName() );
-   str.assign( buffer, length );
-   return file;
-}
-
-} // namespace TNL
diff --git a/src/TNL/Functions/MeshFunction.h b/src/TNL/Functions/MeshFunction.h
index 9d67808e1ec2f5b827bc346fe531841195ffee57..1850f4fb200ab43c3360385fe7ac9d321ed6d88f 100644
--- a/src/TNL/Functions/MeshFunction.h
+++ b/src/TNL/Functions/MeshFunction.h
@@ -147,11 +147,11 @@ class MeshFunction :
 
       RealType getMaxNorm() const;
 
-      bool save( File& file ) const;
+      void save( File& file ) const;
 
-      bool load( File& file );
+      void load( File& file );
 
-      bool boundLoad( File& file );
+      void boundLoad( File& file );
 
       bool write( const String& fileName,
                   const String& format = "vtk",
diff --git a/src/TNL/Functions/MeshFunction_impl.h b/src/TNL/Functions/MeshFunction_impl.h
index e9426084e0de39ff4a5cecb69f478310583477db..107503ca4c97e5c59db73bfdae7f6f95f2922a63 100644
--- a/src/TNL/Functions/MeshFunction_impl.h
+++ b/src/TNL/Functions/MeshFunction_impl.h
@@ -15,6 +15,7 @@
 #include <TNL/Functions/MeshFunctionNormGetter.h>
 #include <TNL/Functions/MeshFunctionGnuplotWriter.h>
 #include <TNL/Functions/MeshFunctionVTKWriter.h>
+#include <TNL/Exceptions/MeshFunctionDataMismatch.h>
 
 #pragma once
 
@@ -164,8 +165,7 @@ setup( const MeshPointer& meshPointer,
    if( parameters.checkParameter( prefix + "file" ) )
    {
       String fileName = parameters.getParameter< String >( prefix + "file" );
-      if( ! this->load( fileName ) )
-         return false;
+      this->load( fileName );
    }
    else
    {
@@ -468,47 +468,39 @@ getMaxNorm() const
 template< typename Mesh,
           int MeshEntityDimension,
           typename Real >
-bool
+void
 MeshFunction< Mesh, MeshEntityDimension, Real >::
 save( File& file ) const
 {
    TNL_ASSERT_EQ( this->data.getSize(), this->getMesh().template getEntitiesCount< typename MeshType::template EntityType< MeshEntityDimension > >(),
                   "Size of the mesh function data does not match the mesh." );
-   if( ! Object::save( file ) )
-      return false;
-   return this->data.save( file );
+   Object::save( file );
+   this->data.save( file );
 }
 
 template< typename Mesh,
           int MeshEntityDimension,
           typename Real >
-bool
+void
 MeshFunction< Mesh, MeshEntityDimension, Real >::
 load( File& file )
 {
-   if( ! Object::load( file ) )
-      return false;
-   if( ! this->data.load( file ) )
-      return false;
+   Object::load( file );
+   this->data.load( file );
    const IndexType meshSize = this->getMesh().template getEntitiesCount< typename MeshType::template EntityType< MeshEntityDimension > >();
    if( this->data.getSize() != meshSize )
-   {
-      std::cerr << "Size of the data loaded to the mesh function (" << this->data.getSize() << ") does not fit with the mesh size (" << meshSize << ")." << std::endl;
-      return false;
-   }
-   return true;
+      throw Exceptions::MeshFunctionDataMismatch( this->data.getSize(), " Does not fit with mesh size " + convertToString( meshSize ) + "." );
 }
 
 template< typename Mesh,
           int MeshEntityDimension,
           typename Real >
-bool
+void
 MeshFunction< Mesh, MeshEntityDimension, Real >::
 boundLoad( File& file )
 {
-   if( ! Object::load( file ) )
-      return false;
-   return this->data.boundLoad( file );
+   Object::load( file );
+   this->data.boundLoad( file );
 }
 
 template< typename Mesh,
diff --git a/src/TNL/Functions/VectorField.h b/src/TNL/Functions/VectorField.h
index 46fdffcba1ffe34d1a57f75ad8b6b1474fbefb5e..c7d5bf553ac01cf55a63c0cff75d5d0a323d5d3b 100644
--- a/src/TNL/Functions/VectorField.h
+++ b/src/TNL/Functions/VectorField.h
@@ -270,34 +270,25 @@ class VectorField< Size, MeshFunction< Mesh, MeshEntityDimension, Real > >
          return v;
       }
       
-      bool save( File& file ) const
+      void save( File& file ) const
       {
-         if( ! Object::save( file ) )
-            return false;
+         Object::save( file );
          for( int i = 0; i < Size; i++ )
-            if( ! vectorField[ i ]->save( file ) )
-               return false;
-         return true;
+            vectorField[ i ]->save( file );
       }
 
-      bool load( File& file )
+      void load( File& file )
       {
-         if( ! Object::load( file ) )
-            return false;
+         Object::load( file );
          for( int i = 0; i < Size; i++ )
-            if( ! vectorField[ i ]->load( file ) )
-               return false;
-         return true;
+            vectorField[ i ]->load( file );
       }
  
-      bool boundLoad( File& file )
+      void boundLoad( File& file )
       {
-         if( ! Object::load( file ) )
-            return false;
+         Object::load( file );
          for( int i = 0; i < Size; i++ )
-            if( ! vectorField[ i ]->boundLoad( file ) )
-               return false;
-         return true;         
+            vectorField[ i ]->boundLoad( file );
       }
       
       bool write( const String& fileName,
diff --git a/src/TNL/Matrices/AdEllpack.h b/src/TNL/Matrices/AdEllpack.h
index f5fdc767346f9fbc90236f04ab000f3fdc20327b..bfe70b6cbba6f1c98558f7b59a21e98713d9fc6f 100644
--- a/src/TNL/Matrices/AdEllpack.h
+++ b/src/TNL/Matrices/AdEllpack.h
@@ -145,13 +145,13 @@ public:
     void vectorProduct( const InVector& inVector,
                         OutVector& outVector ) const;
 
-    bool save( File& file ) const;
+    void save( File& file ) const;
 
-    bool load( File& file );
+    void load( File& file );
 
-    bool save( const String& fileName ) const;
+    void save( const String& fileName ) const;
 
-    bool load( const String& fileName );
+    void load( const String& fileName );
 
     void print( std::ostream& str ) const;
 
diff --git a/src/TNL/Matrices/AdEllpack_impl.h b/src/TNL/Matrices/AdEllpack_impl.h
index daab3b8cdc351459120436186cb3060aeee54d8f..0838bf09b7861f60a99415c20cbb5503cc028ae7 100644
--- a/src/TNL/Matrices/AdEllpack_impl.h
+++ b/src/TNL/Matrices/AdEllpack_impl.h
@@ -609,45 +609,41 @@ void AdEllpack< Real, Device, Index >::vectorProduct( const InVector& inVector,
 template< typename Real,
           typename Device,
           typename Index >
-bool AdEllpack< Real, Device, Index >::save( File& file ) const
+void AdEllpack< Real, Device, Index >::save( File& file ) const
 {
-    if( Sparse< Real, Device, Index >::save( file ) ||
-        this->offset.save( file ) ||
-        this->rowOffset.save( file ) ||
-        this->localLoad.save( file ) ||
-        this->reduceMap.save( file ) )
-        return false;
-    return true;
+    Sparse< Real, Device, Index >::save( file );
+    this->offset.save( file );
+    this->rowOffset.save( file );
+    this->localLoad.save( file );
+    this->reduceMap.save( file );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool AdEllpack< Real, Device, Index >::load( File& file )
+void AdEllpack< Real, Device, Index >::load( File& file )
 {
-    if( Sparse< Real, Device, Index >::load( file ) ||
-        this->offset.load( file ) ||
-        this->rowOffset.load( file ) ||
-        this->localLoad.load( file ) ||
-        this->reduceMap.load( file ) )
-        return false;
-    return true;
+    Sparse< Real, Device, Index >::load( file );
+    this->offset.load( file );
+    this->rowOffset.load( file );
+    this->localLoad.load( file );
+    this->reduceMap.load( file );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool AdEllpack< Real, Device, Index >::save( const String& fileName ) const
+void AdEllpack< Real, Device, Index >::save( const String& fileName ) const
 {
-    return Object::save( fileName );
+    Object::save( fileName );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool AdEllpack< Real, Device, Index >::load( const String& fileName )
+void AdEllpack< Real, Device, Index >::load( const String& fileName )
 {
-    return Object::load( fileName );
+    Object::load( fileName );
 }
 
 template< typename Real,
@@ -872,8 +868,9 @@ bool AdEllpack< Real, Device, Index >::createArrays( warpList* list )
 		row++;
             this->reduceMap.setElement( i, row );
 	}
-	if( localLoad > this->totalLoad )
-	    std::cout << "Error localLoad!!" << std::endl;
+   // TODO: Fix, operator > is not defined for vectors
+	//if( localLoad > this->totalLoad )
+	//    std::cout << "Error localLoad!!" << std::endl;
         iteration++;
         warp = warp->next;
     }
diff --git a/src/TNL/Matrices/BiEllpack.h b/src/TNL/Matrices/BiEllpack.h
index b724a0ada17dc4efb2c1d0907054715107da01a4..93bfeabaa5814269c4329c70b7555cfc963b2c12 100644
--- a/src/TNL/Matrices/BiEllpack.h
+++ b/src/TNL/Matrices/BiEllpack.h
@@ -129,13 +129,13 @@ public:
 
 	void reset();
 
-	bool save( File& file ) const;
+	void save( File& file ) const;
 
-	bool load( File& file );
+	void load( File& file );
 
-	bool save( const String& fileName ) const;
+	void save( const String& fileName ) const;
 
-	bool load( const String& fileName );
+	void load( const String& fileName );
 
 	void print( std::ostream& str ) const;
 
diff --git a/src/TNL/Matrices/BiEllpackSymmetric.h b/src/TNL/Matrices/BiEllpackSymmetric.h
index e44921fe837e7d0f0060df78af167c12ea1c102e..5e72d9b641480d70426d2fd75e186ff9a1aca851 100644
--- a/src/TNL/Matrices/BiEllpackSymmetric.h
+++ b/src/TNL/Matrices/BiEllpackSymmetric.h
@@ -118,13 +118,13 @@ public:
 
 	void reset();
 
-	bool save( File& file ) const;
+	void save( File& file ) const;
 
-	bool load( File& file );
+	void load( File& file );
 
-	bool save( const String& fileName ) const;
+	void save( const String& fileName ) const;
 
-	bool load( const String& fileName );
+	void load( const String& fileName );
 
 	void print( std::ostream& str ) const;
 
diff --git a/src/TNL/Matrices/BiEllpackSymmetric_impl.h b/src/TNL/Matrices/BiEllpackSymmetric_impl.h
index 5b6f94b57b571963f5ba18c3c4c7e8fb7700fa99..69d32a4722dfeadfcb9182262508b28014ce4a1b 100644
--- a/src/TNL/Matrices/BiEllpackSymmetric_impl.h
+++ b/src/TNL/Matrices/BiEllpackSymmetric_impl.h
@@ -677,44 +677,40 @@ template< typename Real,
           typename Device,
           typename Index,
           int StripSize >
-bool BiEllpackSymmetric< Real, Device, Index, StripSize >::save( File& file ) const
+void BiEllpackSymmetric< Real, Device, Index, StripSize >::save( File& file ) const
 {
-    if( ! Sparse< Real, Device, Index >::save( file ) ||
-        ! this->groupPointers.save( file ) ||
-        ! this->rowPermArray.save( file ) )
-        return false;
-    return true;
+    Sparse< Real, Device, Index >::save( file );
+    this->groupPointers.save( file );
+    this->rowPermArray.save( file );
 }
 
 template< typename Real,
           typename Device,
           typename Index,
           int StripSize >
-bool BiEllpackSymmetric< Real, Device, Index, StripSize >::load( File& file )
+void BiEllpackSymmetric< Real, Device, Index, StripSize >::load( File& file )
 {
-    if( ! Sparse< Real, Device, Index >::load( file ) ||
-        ! this->groupPointers.load( file ) ||
-        ! this->rowPermArray.load( file ) )
-        return false;
-    return true;
+    Sparse< Real, Device, Index >::load( file );
+    this->groupPointers.load( file );
+    this->rowPermArray.load( file );
 }
 
 template< typename Real,
           typename Device,
           typename Index,
           int StripSize >
-bool BiEllpackSymmetric< Real, Device, Index, StripSize >::save( const String& fileName ) const
+void BiEllpackSymmetric< Real, Device, Index, StripSize >::save( const String& fileName ) const
 {
-    return Object::save( fileName );
+    Object::save( fileName );
 }
 
 template< typename Real,
           typename Device,
           typename Index,
           int StripSize >
-bool BiEllpackSymmetric< Real, Device, Index, StripSize >::load( const String& fileName )
+void BiEllpackSymmetric< Real, Device, Index, StripSize >::load( const String& fileName )
 {
-    return Object::load( fileName );
+    Object::load( fileName );
 }
 
 template< typename Real,
diff --git a/src/TNL/Matrices/BiEllpack_impl.h b/src/TNL/Matrices/BiEllpack_impl.h
index ea5e1efb9463915ec724b28b38abbfe64ac596b0..31dbd2bb3f8f5fb178ade2eff590873fe27d6a18 100644
--- a/src/TNL/Matrices/BiEllpack_impl.h
+++ b/src/TNL/Matrices/BiEllpack_impl.h
@@ -681,44 +681,40 @@ template< typename Real,
 		  typename Device,
 		  typename Index,
 		  int StripSize >
-bool BiEllpack< Real, Device, Index, StripSize >::save( File& file ) const
+void BiEllpack< Real, Device, Index, StripSize >::save( File& file ) const
 {
-	if( ! Sparse< Real, Device, Index >::save( file ) ||
-		! this->groupPointers.save( file ) ||
-		! this->rowPermArray.save( file ) )
-		return false;
-	return true;
+   Sparse< Real, Device, Index >::save( file );
+   this->groupPointers.save( file );
+   this->rowPermArray.save( file );
 }
 
 template< typename Real,
 		  typename Device,
 		  typename Index,
 		  int StripSize >
-bool BiEllpack< Real, Device, Index, StripSize >::load( File& file )
+void BiEllpack< Real, Device, Index, StripSize >::load( File& file )
 {
-	if( ! Sparse< Real, Device, Index >::load( file ) ||
-		! this->groupPointers.load( file ) ||
-		! this->rowPermArray.load( file ) )
-		return false;
-	return true;
+   Sparse< Real, Device, Index >::load( file );
+   this->groupPointers.load( file );
+   this->rowPermArray.load( file );
 }
 
 template< typename Real,
 		  typename Device,
 		  typename Index,
 		  int StripSize >
-bool BiEllpack< Real, Device, Index, StripSize >::save( const String& fileName ) const
+void BiEllpack< Real, Device, Index, StripSize >::save( const String& fileName ) const
 {
-	return Object::save( fileName );
+   Object::save( fileName );
 }
 
 template< typename Real,
 		  typename Device,
 		  typename Index,
 		  int StripSize >
-bool BiEllpack< Real, Device, Index, StripSize >::load( const String& fileName )
+void BiEllpack< Real, Device, Index, StripSize >::load( const String& fileName )
 {
-	return Object::load( fileName );
+   Object::load( fileName );
 }
 
 template< typename Real,
diff --git a/src/TNL/Matrices/CSR.h b/src/TNL/Matrices/CSR.h
index 10b7184569e80ceaea1b560dd39142e9098c672b..4f42c1bacdc64da76e189a344e655bd8b44d63e6 100644
--- a/src/TNL/Matrices/CSR.h
+++ b/src/TNL/Matrices/CSR.h
@@ -84,7 +84,7 @@ public:
    IndexType getRowLengthFast( const IndexType row ) const;
 
    IndexType getNonZeroRowLength( const IndexType row ) const;
-
+   
    __cuda_callable__
    IndexType getNonZeroRowLengthFast( const IndexType row ) const;
 
@@ -191,13 +191,13 @@ public:
              typename = typename Enabler< Device2 >::type >
    CSR& operator=( const CSR< Real2, Device2, Index2 >& matrix );
 
-   bool save( File& file ) const;
+   void save( File& file ) const;
 
-   bool load( File& file );
+   void load( File& file );
 
-   bool save( const String& fileName ) const;
+   void save( const String& fileName ) const;
 
-   bool load( const String& fileName );
+   void load( const String& fileName );
 
    void print( std::ostream& str ) const;
 
diff --git a/src/TNL/Matrices/CSR_impl.h b/src/TNL/Matrices/CSR_impl.h
index 0a682a9dc25cbea51617bb8c5ab89b0a76b0d846..5fe617b5430ca870a3857f5a1545e1a038163c7c 100644
--- a/src/TNL/Matrices/CSR_impl.h
+++ b/src/TNL/Matrices/CSR_impl.h
@@ -615,39 +615,35 @@ CSR< Real, Device, Index >::operator=( const CSR< Real2, Device2, Index2 >& matr
 template< typename Real,
           typename Device,
           typename Index >
-bool CSR< Real, Device, Index >::save( File& file ) const
+void CSR< Real, Device, Index >::save( File& file ) const
 {
-   if( ! Sparse< Real, Device, Index >::save( file ) ||
-       ! this->rowPointers.save( file ) )
-      return false;
-   return true;
+   Sparse< Real, Device, Index >::save( file );
+   this->rowPointers.save( file );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool CSR< Real, Device, Index >::load( File& file )
+void CSR< Real, Device, Index >::load( File& file )
 {
-   if( ! Sparse< Real, Device, Index >::load( file ) ||
-       ! this->rowPointers.load( file ) )
-      return false;
-   return true;
+   Sparse< Real, Device, Index >::load( file );
+   this->rowPointers.load( file );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool CSR< Real, Device, Index >::save( const String& fileName ) const
+void CSR< Real, Device, Index >::save( const String& fileName ) const
 {
-   return Object::save( fileName );
+   Object::save( fileName );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool CSR< Real, Device, Index >::load( const String& fileName )
+void CSR< Real, Device, Index >::load( const String& fileName )
 {
-   return Object::load( fileName );
+   Object::load( fileName );
 }
 
 template< typename Real,
diff --git a/src/TNL/Matrices/ChunkedEllpack.h b/src/TNL/Matrices/ChunkedEllpack.h
index ff889a49fe0d7b71c4e1fb1e6e1165e7d8970b86..928dcd8d1f6ad7303d913400f269a0b85aa22e61 100644
--- a/src/TNL/Matrices/ChunkedEllpack.h
+++ b/src/TNL/Matrices/ChunkedEllpack.h
@@ -241,13 +241,13 @@ public:
              typename = typename Enabler< Device2 >::type >
    ChunkedEllpack& operator=( const ChunkedEllpack< Real2, Device2, Index2 >& matrix );
 
-   bool save( File& file ) const;
+   void save( File& file ) const;
 
-   bool load( File& file );
+   void load( File& file );
 
-   bool save( const String& fileName ) const;
+   void save( const String& fileName ) const;
 
-   bool load( const String& fileName );
+   void load( const String& fileName );
 
    void print( std::ostream& str ) const;
 
diff --git a/src/TNL/Matrices/ChunkedEllpack_impl.h b/src/TNL/Matrices/ChunkedEllpack_impl.h
index ff1dd0742f1f2010b441206395e5cf278deaf37e..e3a686264dd3defe5921708fbc5373bc19b0b5ef 100644
--- a/src/TNL/Matrices/ChunkedEllpack_impl.h
+++ b/src/TNL/Matrices/ChunkedEllpack_impl.h
@@ -1284,45 +1284,41 @@ ChunkedEllpack< Real, Device, Index >::operator=( const ChunkedEllpack< Real2, D
 template< typename Real,
           typename Device,
           typename Index >
-bool ChunkedEllpack< Real, Device, Index >::save( File& file ) const
+void ChunkedEllpack< Real, Device, Index >::save( File& file ) const
 {
-   if( ! Sparse< Real, Device, Index >::save( file ) ||
-       ! this->rowToChunkMapping.save( file ) ||
-       ! this->rowToSliceMapping.save( file ) ||
-       ! this->rowPointers.save( file ) ||
-       ! this->slices.save( file ) )
-      return false;
-   return true;
+   Sparse< Real, Device, Index >::save( file );
+   this->rowToChunkMapping.save( file );
+   this->rowToSliceMapping.save( file );
+   this->rowPointers.save( file );
+   this->slices.save( file );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool ChunkedEllpack< Real, Device, Index >::load( File& file )
+void ChunkedEllpack< Real, Device, Index >::load( File& file )
 {
-   if( ! Sparse< Real, Device, Index >::load( file ) ||
-       ! this->rowToChunkMapping.load( file ) ||
-       ! this->rowToSliceMapping.load( file ) ||
-       ! this->rowPointers.load( file ) ||
-       ! this->slices.load( file ) )
-      return false;
-   return true;
+   Sparse< Real, Device, Index >::load( file );
+   this->rowToChunkMapping.load( file );
+   this->rowToSliceMapping.load( file );
+   this->rowPointers.load( file );
+   this->slices.load( file );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool ChunkedEllpack< Real, Device, Index >::save( const String& fileName ) const
+void ChunkedEllpack< Real, Device, Index >::save( const String& fileName ) const
 {
-   return Object::save( fileName );
+   Object::save( fileName );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool ChunkedEllpack< Real, Device, Index >::load( const String& fileName )
+void ChunkedEllpack< Real, Device, Index >::load( const String& fileName )
 {
-   return Object::load( fileName );
+   Object::load( fileName );
 }
 
 template< typename Real,
diff --git a/src/TNL/Matrices/Dense.h b/src/TNL/Matrices/Dense.h
index 351e8a8c7631feb1cf952cb8dd57762723a29bfc..e9601a9face2e7a754c25a1b8a397aae79da1a27 100644
--- a/src/TNL/Matrices/Dense.h
+++ b/src/TNL/Matrices/Dense.h
@@ -200,13 +200,13 @@ public:
              typename = typename Enabler< Device2 >::type >
    Dense& operator=( const Dense< Real2, Device2, Index2 >& matrix );
 
-   bool save( const String& fileName ) const;
+   void save( const String& fileName ) const;
 
-   bool load( const String& fileName );
+   void load( const String& fileName );
 
-   bool save( File& file ) const;
+   void save( File& file ) const;
 
-   bool load( File& file );
+   void load( File& file );
 
    void print( std::ostream& str ) const;
 
diff --git a/src/TNL/Matrices/Dense_impl.h b/src/TNL/Matrices/Dense_impl.h
index d204c3a0a6b48bb2c62d6802c48d636034ed320e..3844751d4638561b883d666d507fbf4ed444de71 100644
--- a/src/TNL/Matrices/Dense_impl.h
+++ b/src/TNL/Matrices/Dense_impl.h
@@ -936,37 +936,33 @@ Dense< Real, Device, Index >::operator=( const Dense< Real2, Device2, Index2 >&
 template< typename Real,
           typename Device,
           typename Index >
-bool Dense< Real, Device, Index >::save( const String& fileName ) const
+void Dense< Real, Device, Index >::save( const String& fileName ) const
 {
-   return Object::save( fileName );
+   Object::save( fileName );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool Dense< Real, Device, Index >::load( const String& fileName )
+void Dense< Real, Device, Index >::load( const String& fileName )
 {
-   return Object::load( fileName );
+   Object::load( fileName );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool Dense< Real, Device, Index >::save( File& file ) const
+void Dense< Real, Device, Index >::save( File& file ) const
 {
-   if( ! Matrix< Real, Device, Index >::save( file )  )
-      return false;
-   return true;
+   Matrix< Real, Device, Index >::save( file );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool Dense< Real, Device, Index >::load( File& file )
+void Dense< Real, Device, Index >::load( File& file )
 {
-   if( ! Matrix< Real, Device, Index >::load( file ) )
-      return false;
-   return true;
+   Matrix< Real, Device, Index >::load( file );
 }
 
 template< typename Real,
diff --git a/src/TNL/Matrices/DistributedSpMV.h b/src/TNL/Matrices/DistributedSpMV.h
index a96f028bcbb1bb6420419debf6ff019d6615cef7..f70773c1fc6afd998e833223a97cbef3c87c1476 100644
--- a/src/TNL/Matrices/DistributedSpMV.h
+++ b/src/TNL/Matrices/DistributedSpMV.h
@@ -199,8 +199,7 @@ public:
       else {
          auto outVectorView = outVector.getLocalVectorView();
          const Pointers::DevicePointer< const MatrixType > localMatrixPointer( localMatrix );
-         using InView = Containers::DistributedVectorView< const typename InVector::RealType, typename InVector::DeviceType, typename InVector::IndexType, typename InVector::CommunicatorType >;
-         const InView inView( inVector );
+         const auto inView = inVector.getConstView();
 
          // matrix-vector multiplication using local-only rows
          auto kernel1 = [=] __cuda_callable__ ( IndexType i, const MatrixType* localMatrix ) mutable
diff --git a/src/TNL/Matrices/Ellpack.h b/src/TNL/Matrices/Ellpack.h
index e19010dafa9f47a36f669f9b5832d31c7b289d10..100685e7b3fc43cc566d589cc64ed8e82c7df940 100644
--- a/src/TNL/Matrices/Ellpack.h
+++ b/src/TNL/Matrices/Ellpack.h
@@ -186,13 +186,13 @@ public:
              typename = typename Enabler< Device2 >::type >
    Ellpack& operator=( const Ellpack< Real2, Device2, Index2 >& matrix );
 
-   bool save( File& file ) const;
+   void save( File& file ) const;
 
-   bool load( File& file );
+   void load( File& file );
 
-   bool save( const String& fileName ) const;
+   void save( const String& fileName ) const;
 
-   bool load( const String& fileName );
+   void load( const String& fileName );
 
    void print( std::ostream& str ) const;
 
diff --git a/src/TNL/Matrices/EllpackSymmetric.h b/src/TNL/Matrices/EllpackSymmetric.h
index 0720d9d5293f5190edfb3411807ae29b380d91d3..b150bc4d9b9a6f0b764192ea0c2b6df2d458558a 100644
--- a/src/TNL/Matrices/EllpackSymmetric.h
+++ b/src/TNL/Matrices/EllpackSymmetric.h
@@ -158,13 +158,13 @@ class EllpackSymmetric : public Sparse< Real, Device, Index >
                              Vector& x,
                              const RealType& omega = 1.0 ) const;
 
-   bool save( File& file ) const;
+   void save( File& file ) const;
 
-   bool load( File& file );
+   void load( File& file );
 
-   bool save( const String& fileName ) const;
+   void save( const String& fileName ) const;
 
-   bool load( const String& fileName );
+   void load( const String& fileName );
 
    void print( std::ostream& str ) const;
 
diff --git a/src/TNL/Matrices/EllpackSymmetricGraph.h b/src/TNL/Matrices/EllpackSymmetricGraph.h
index 3a282c796be439209184023fb76aa692ff1e4294..85c7e49b0c46b5dde10b31f6c52d18a28360d7ed 100644
--- a/src/TNL/Matrices/EllpackSymmetricGraph.h
+++ b/src/TNL/Matrices/EllpackSymmetricGraph.h
@@ -157,13 +157,13 @@ class EllpackSymmetricGraph : public Sparse< Real, Device, Index >
 
    bool rearrangeMatrix( bool verbose );
 
-   bool save( File& file ) const;
+   void save( File& file ) const;
 
-   bool load( File& file );
+   void load( File& file );
 
-   bool save( const String& fileName ) const;
+   void save( const String& fileName ) const;
 
-   bool load( const String& fileName );
+   void load( const String& fileName );
 
    void print( std::ostream& str ) const;
 
diff --git a/src/TNL/Matrices/EllpackSymmetricGraph_impl.h b/src/TNL/Matrices/EllpackSymmetricGraph_impl.h
index 799d07281e62ae441c39162ee2fc5271997effac..8f038742bc4a261662a5b272ece80c857b16ed05 100644
--- a/src/TNL/Matrices/EllpackSymmetricGraph_impl.h
+++ b/src/TNL/Matrices/EllpackSymmetricGraph_impl.h
@@ -743,37 +743,35 @@ void EllpackSymmetricGraph< Real, Device, Index >::vectorProduct( const InVector
 template< typename Real,
           typename Device,
           typename Index >
-bool EllpackSymmetricGraph< Real, Device, Index >::save( File& file ) const
+void EllpackSymmetricGraph< Real, Device, Index >::save( File& file ) const
 {
-   if( ! Sparse< Real, Device, Index >::save( file) ) return false;
-   if( ! file.write( &this->rowLengths ) ) return false;
-   return true;
+   Sparse< Real, Device, Index >::save( file);
+   file.save( &this->rowLengths );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool EllpackSymmetricGraph< Real, Device, Index >::load( File& file )
+void EllpackSymmetricGraph< Real, Device, Index >::load( File& file )
 {
-   if( ! Sparse< Real, Device, Index >::load( file) ) return false;
-   if( ! file.read( &this->rowLengths ) ) return false;
-   return true;
+   Sparse< Real, Device, Index >::load( file);
+   file.load( &this->rowLengths );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool EllpackSymmetricGraph< Real, Device, Index >::save( const String& fileName ) const
+void EllpackSymmetricGraph< Real, Device, Index >::save( const String& fileName ) const
 {
-   return Object::save( fileName );
+   Object::save( fileName );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool EllpackSymmetricGraph< Real, Device, Index >::load( const String& fileName )
+void EllpackSymmetricGraph< Real, Device, Index >::load( const String& fileName )
 {
-   return Object::load( fileName );
+   Object::load( fileName );
 }
 
 template< typename Real,
diff --git a/src/TNL/Matrices/EllpackSymmetric_impl.h b/src/TNL/Matrices/EllpackSymmetric_impl.h
index 42202a883c0c887317aaf68904dfa0bddf27a646..fed7f7669c4f33abdadf4b91f30f8ec5e14b1e23 100644
--- a/src/TNL/Matrices/EllpackSymmetric_impl.h
+++ b/src/TNL/Matrices/EllpackSymmetric_impl.h
@@ -537,37 +537,35 @@ bool EllpackSymmetric< Real, Device, Index > :: performSORIteration( const Vecto
 template< typename Real,
           typename Device,
           typename Index >
-bool EllpackSymmetric< Real, Device, Index >::save( File& file ) const
+void EllpackSymmetric< Real, Device, Index >::save( File& file ) const
 {
-   if( ! Sparse< Real, Device, Index >::save( file) ) return false;
-   if( ! file.write( &this->rowLengths ) ) return false;
-   return true;
+   Sparse< Real, Device, Index >::save( file);
+   file.save( &this->rowLengths );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool EllpackSymmetric< Real, Device, Index >::load( File& file )
+void EllpackSymmetric< Real, Device, Index >::load( File& file )
 {
-   if( ! Sparse< Real, Device, Index >::load( file) ) return false;
-   if( ! file.read( &this->rowLengths ) ) return false;
-   return true;
+   Sparse< Real, Device, Index >::load( file);
+   file.load( &this->rowLengths );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool EllpackSymmetric< Real, Device, Index >::save( const String& fileName ) const
+void EllpackSymmetric< Real, Device, Index >::save( const String& fileName ) const
 {
-   return Object::save( fileName );
+   Object::save( fileName );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool EllpackSymmetric< Real, Device, Index >::load( const String& fileName )
+void EllpackSymmetric< Real, Device, Index >::load( const String& fileName )
 {
-   return Object::load( fileName );
+   Object::load( fileName );
 }
 
 template< typename Real,
diff --git a/src/TNL/Matrices/Ellpack_impl.h b/src/TNL/Matrices/Ellpack_impl.h
index 7c2a3b6f00fcc428d2fd422a069c5357497a4c9e..6c06fdd98beb4bba90bc0a16ddffacc998458ee2 100644
--- a/src/TNL/Matrices/Ellpack_impl.h
+++ b/src/TNL/Matrices/Ellpack_impl.h
@@ -713,37 +713,35 @@ Ellpack< Real, Device, Index >::operator=( const Ellpack< Real2, Device2, Index2
 template< typename Real,
           typename Device,
           typename Index >
-bool Ellpack< Real, Device, Index >::save( File& file ) const
+void Ellpack< Real, Device, Index >::save( File& file ) const
 {
-   if( ! Sparse< Real, Device, Index >::save( file) ) return false;
-   if( ! file.write( &this->rowLengths ) ) return false;
-   return true;
+   Sparse< Real, Device, Index >::save( file);
+   file.save( &this->rowLengths );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool Ellpack< Real, Device, Index >::load( File& file )
+void Ellpack< Real, Device, Index >::load( File& file )
 {
-   if( ! Sparse< Real, Device, Index >::load( file) ) return false;
-   if( ! file.read( &this->rowLengths ) ) return false;
-   return true;
+   Sparse< Real, Device, Index >::load( file);
+   file.load( &this->rowLengths );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool Ellpack< Real, Device, Index >::save( const String& fileName ) const
+void Ellpack< Real, Device, Index >::save( const String& fileName ) const
 {
-   return Object::save( fileName );
+   Object::save( fileName );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool Ellpack< Real, Device, Index >::load( const String& fileName )
+void Ellpack< Real, Device, Index >::load( const String& fileName )
 {
-   return Object::load( fileName );
+   Object::load( fileName );
 }
 
 template< typename Real,
diff --git a/src/TNL/Matrices/Matrix.h b/src/TNL/Matrices/Matrix.h
index 99f4bf1d63f7a78eb659794fde844196fdfbac1d..e8677b8532518dda1744070b7f7bf29c0c01f1cb 100644
--- a/src/TNL/Matrices/Matrix.h
+++ b/src/TNL/Matrices/Matrix.h
@@ -105,9 +105,9 @@ public:
    template< typename Matrix >
    bool operator != ( const Matrix& matrix ) const;
 
-   virtual bool save( File& file ) const;
+   virtual void save( File& file ) const;
 
-   virtual bool load( File& file );
+   virtual void load( File& file );
 
    virtual void print( std::ostream& str ) const;
 
diff --git a/src/TNL/Matrices/Matrix_impl.h b/src/TNL/Matrices/Matrix_impl.h
index cb685917fd676e0d062f400ab0fd42836dbe1e05..815e0e7d82c8406369665e947d4fa9de414fba89 100644
--- a/src/TNL/Matrices/Matrix_impl.h
+++ b/src/TNL/Matrices/Matrix_impl.h
@@ -43,7 +43,7 @@ template< typename Real,
 void Matrix< Real, Device, Index >::getCompressedRowLengths( CompressedRowLengthsVector& rowLengths ) const
 {
    rowLengths.setSize( this->getRows() );
-   getCompressedRowLengths( CompressedRowLengthsVectorView( rowLengths ) );
+   getCompressedRowLengths( rowLengths.getView() );
 }
 
 template< typename Real,
@@ -142,27 +142,23 @@ bool Matrix< Real, Device, Index >::operator != ( const MatrixT& matrix ) const
 template< typename Real,
           typename Device,
           typename Index >
-bool Matrix< Real, Device, Index >::save( File& file ) const
+void Matrix< Real, Device, Index >::save( File& file ) const
 {
-   if( ! Object::save( file ) ||
-       ! file.write( &this->rows ) ||
-       ! file.write( &this->columns ) ||
-       ! this->values.save( file ) )
-      return false;
-   return true;
+   Object::save( file );
+   file.save( &this->rows );
+   file.save( &this->columns );
+   this->values.save( file );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool Matrix< Real, Device, Index >::load( File& file )
+void Matrix< Real, Device, Index >::load( File& file )
 {
-   if( ! Object::load( file ) ||
-       ! file.read( &this->rows ) ||
-       ! file.read( &this->columns ) ||
-       ! this->values.load( file ) )
-      return false;
-   return true;
+   Object::load( file );
+   file.load( &this->rows );
+   file.load( &this->columns );
+   this->values.load( file );
 }
 
 template< typename Real,
diff --git a/src/TNL/Matrices/Multidiagonal.h b/src/TNL/Matrices/Multidiagonal.h
index cfa798e7a254916455db5c896640495bdbc504c1..969a1e0aaaeac9412979a9626d08ed173b0b82fa 100644
--- a/src/TNL/Matrices/Multidiagonal.h
+++ b/src/TNL/Matrices/Multidiagonal.h
@@ -192,13 +192,13 @@ public:
              typename = typename Enabler< Device2 >::type >
    Multidiagonal& operator=( const Multidiagonal< Real2, Device2, Index2 >& matrix );
 
-   bool save( File& file ) const;
+   void save( File& file ) const;
 
-   bool load( File& file );
+   void load( File& file );
 
-   bool save( const String& fileName ) const;
+   void save( const String& fileName ) const;
 
-   bool load( const String& fileName );
+   void load( const String& fileName );
 
    void print( std::ostream& str ) const;
 
diff --git a/src/TNL/Matrices/Multidiagonal_impl.h b/src/TNL/Matrices/Multidiagonal_impl.h
index bd4c24691252ac425466906c549168248aca8244..860b3717ca94a1a38d7b48f2dcb4d9060ccfd11c 100644
--- a/src/TNL/Matrices/Multidiagonal_impl.h
+++ b/src/TNL/Matrices/Multidiagonal_impl.h
@@ -650,39 +650,37 @@ Multidiagonal< Real, Device, Index >::operator=( const Multidiagonal< Real2, Dev
 template< typename Real,
           typename Device,
           typename Index >
-bool Multidiagonal< Real, Device, Index >::save( File& file ) const
+void Multidiagonal< Real, Device, Index >::save( File& file ) const
 {
-   if( ! Matrix< Real, Device, Index >::save( file ) ) return false;
-   if( ! this->values.save( file ) ) return false;
-   if( ! this->diagonalsShift.save( file ) ) return false;
-   return true;
+   Matrix< Real, Device, Index >::save( file );
+   this->values.save( file );
+   this->diagonalsShift.save( file );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool Multidiagonal< Real, Device, Index >::load( File& file )
+void Multidiagonal< Real, Device, Index >::load( File& file )
 {
-   if( ! Matrix< Real, Device, Index >::load( file ) ) return false;
-   if( ! this->values.load( file ) ) return false;
-   if( ! this->diagonalsShift.load( file ) ) return false;
-   return true;
+   Matrix< Real, Device, Index >::load( file );
+   this->values.load( file );
+   this->diagonalsShift.load( file );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool Multidiagonal< Real, Device, Index >::save( const String& fileName ) const
+void Multidiagonal< Real, Device, Index >::save( const String& fileName ) const
 {
-   return Object::save( fileName );
+   Object::save( fileName );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool Multidiagonal< Real, Device, Index >::load( const String& fileName )
+void Multidiagonal< Real, Device, Index >::load( const String& fileName )
 {
-   return Object::load( fileName );
+   Object::load( fileName );
 }
 
 template< typename Real,
diff --git a/src/TNL/Matrices/SlicedEllpack.h b/src/TNL/Matrices/SlicedEllpack.h
index 0fc9ccb0b2ca42bd2ec6441f9fe76cd661679f8e..b7302e55973eb699c80a2ed07cbdaae6cfa8d099 100644
--- a/src/TNL/Matrices/SlicedEllpack.h
+++ b/src/TNL/Matrices/SlicedEllpack.h
@@ -204,13 +204,13 @@ public:
              typename = typename Enabler< Device2 >::type >
    SlicedEllpack& operator=( const SlicedEllpack< Real2, Device2, Index2, SliceSize >& matrix );
 
-   bool save( File& file ) const;
+   void save( File& file ) const;
 
-   bool load( File& file );
+   void load( File& file );
 
-   bool save( const String& fileName ) const;
+   void save( const String& fileName ) const;
 
-   bool load( const String& fileName );
+   void load( const String& fileName );
 
    void print( std::ostream& str ) const;
 
diff --git a/src/TNL/Matrices/SlicedEllpackSymmetric.h b/src/TNL/Matrices/SlicedEllpackSymmetric.h
index d9abb0de2ef664fd4032e8e5b0e00203093eb250..550df75c43529ce909902389302221a8a0e8869c 100644
--- a/src/TNL/Matrices/SlicedEllpackSymmetric.h
+++ b/src/TNL/Matrices/SlicedEllpackSymmetric.h
@@ -173,13 +173,13 @@ class SlicedEllpackSymmetric : public Sparse< Real, Device, Index >
                              Vector& x,
                              const RealType& omega = 1.0 ) const;
 
-   bool save( File& file ) const;
+   void save( File& file ) const;
 
-   bool load( File& file );
+   void load( File& file );
 
-   bool save( const String& fileName ) const;
+   void save( const String& fileName ) const;
 
-   bool load( const String& fileName );
+   void load( const String& fileName );
 
    void print( std::ostream& str ) const;
 
diff --git a/src/TNL/Matrices/SlicedEllpackSymmetricGraph.h b/src/TNL/Matrices/SlicedEllpackSymmetricGraph.h
index a2ab000957227a88a9655888cb417cea6498f56f..762b0a21e3383ed3c551ee8409e23e8da18d56f4 100644
--- a/src/TNL/Matrices/SlicedEllpackSymmetricGraph.h
+++ b/src/TNL/Matrices/SlicedEllpackSymmetricGraph.h
@@ -171,13 +171,13 @@ class SlicedEllpackSymmetricGraph : public Sparse< Real, Device, Index >
 
    Containers::Vector< Index, Device, Index > getRealRowLengths();
 
-   bool save( File& file ) const;
+   void save( File& file ) const;
 
-   bool load( File& file );
+   void load( File& file );
 
-   bool save( const String& fileName ) const;
+   void save( const String& fileName ) const;
 
-   bool load( const String& fileName );
+   void load( const String& fileName );
 
    void print( std::ostream& str ) const;
 
diff --git a/src/TNL/Matrices/SlicedEllpackSymmetricGraph_impl.h b/src/TNL/Matrices/SlicedEllpackSymmetricGraph_impl.h
index 9f09a21c506bd08110bc8360e17d3bf1f3a4097c..dcd7ca3dc079c249ef45f2b0874faa622b1f329b 100644
--- a/src/TNL/Matrices/SlicedEllpackSymmetricGraph_impl.h
+++ b/src/TNL/Matrices/SlicedEllpackSymmetricGraph_impl.h
@@ -573,44 +573,40 @@ template< typename Real,
           typename Device,
           typename Index,
           int SliceSize >
-bool SlicedEllpackSymmetricGraph< Real, Device, Index, SliceSize >::save( File& file ) const
+void SlicedEllpackSymmetricGraph< Real, Device, Index, SliceSize >::save( File& file ) const
 {
-   if( ! Sparse< Real, Device, Index >::save( file ) ||
-       ! this->slicePointers.save( file ) ||
-       ! this->sliceRowLengths.save( file ) )
-      return false;
-   return true;
+   Sparse< Real, Device, Index >::save( file );
+   this->slicePointers.save( file );
+   this->sliceRowLengths.save( file );
 }
 
 template< typename Real,
           typename Device,
           typename Index,
           int SliceSize >
-bool SlicedEllpackSymmetricGraph< Real, Device, Index, SliceSize >::load( File& file )
+void SlicedEllpackSymmetricGraph< Real, Device, Index, SliceSize >::load( File& file )
 {
-   if( ! Sparse< Real, Device, Index >::load( file ) ||
-       ! this->slicePointers.load( file ) ||
-       ! this->sliceRowLengths.load( file ) )
-      return false;
-   return true;
+   Sparse< Real, Device, Index >::load( file );
+   this->slicePointers.load( file );
+   this->sliceRowLengths.load( file );
 }
 
 template< typename Real,
           typename Device,
           typename Index,
           int SliceSize >
-bool SlicedEllpackSymmetricGraph< Real, Device, Index, SliceSize >::save( const String& fileName ) const
+void SlicedEllpackSymmetricGraph< Real, Device, Index, SliceSize >::save( const String& fileName ) const
 {
-   return Object::save( fileName );
+   Object::save( fileName );
 }
 
 template< typename Real,
           typename Device,
           typename Index,
           int SliceSize >
-bool SlicedEllpackSymmetricGraph< Real, Device, Index, SliceSize >::load( const String& fileName )
+void SlicedEllpackSymmetricGraph< Real, Device, Index, SliceSize >::load( const String& fileName )
 {
-   return Object::load( fileName );
+   Object::load( fileName );
 }
 
 template< typename Real,
diff --git a/src/TNL/Matrices/SlicedEllpackSymmetric_impl.h b/src/TNL/Matrices/SlicedEllpackSymmetric_impl.h
index 402ac5a6c8128ab67bbf2393528fb3a2b58b9077..3a8e3cab4b8e874462c7f7695bab1b3693d4f8d4 100644
--- a/src/TNL/Matrices/SlicedEllpackSymmetric_impl.h
+++ b/src/TNL/Matrices/SlicedEllpackSymmetric_impl.h
@@ -622,44 +622,40 @@ template< typename Real,
           typename Device,
           typename Index,
           int SliceSize >
-bool SlicedEllpackSymmetric< Real, Device, Index, SliceSize >::save( File& file ) const
+void SlicedEllpackSymmetric< Real, Device, Index, SliceSize >::save( File& file ) const
 {
-   if( ! Sparse< Real, Device, Index >::save( file ) ||
-       ! this->slicePointers.save( file ) ||
-       ! this->sliceRowLengths.save( file ) )
-      return false;
-   return true;
+   Sparse< Real, Device, Index >::save( file );
+   this->slicePointers.save( file );
+   this->sliceRowLengths.save( file );
 }
 
 template< typename Real,
           typename Device,
           typename Index,
           int SliceSize >
-bool SlicedEllpackSymmetric< Real, Device, Index, SliceSize >::load( File& file )
+void SlicedEllpackSymmetric< Real, Device, Index, SliceSize >::load( File& file )
 {
-   if( ! Sparse< Real, Device, Index >::load( file ) ||
-       ! this->slicePointers.load( file ) ||
-       ! this->sliceRowLengths.load( file ) )
-      return false;
-   return true;
+   Sparse< Real, Device, Index >::load( file );
+   this->slicePointers.load( file );
+   this->sliceRowLengths.load( file );
 }
 
 template< typename Real,
           typename Device,
           typename Index,
           int SliceSize >
-bool SlicedEllpackSymmetric< Real, Device, Index, SliceSize >::save( const String& fileName ) const
+void SlicedEllpackSymmetric< Real, Device, Index, SliceSize >::save( const String& fileName ) const
 {
-   return Object::save( fileName );
+   Object::save( fileName );
 }
 
 template< typename Real,
           typename Device,
           typename Index,
           int SliceSize >
-bool SlicedEllpackSymmetric< Real, Device, Index, SliceSize >::load( const String& fileName )
+void SlicedEllpackSymmetric< Real, Device, Index, SliceSize >::load( const String& fileName )
 {
-   return Object::load( fileName );
+   Object::load( fileName );
 }
 
 template< typename Real,
diff --git a/src/TNL/Matrices/SlicedEllpack_impl.h b/src/TNL/Matrices/SlicedEllpack_impl.h
index 4d7593d3f33a1e1140f87fd8eb876172e70e42a5..8e20c970e95611849d528d2f7d910c2a254a0f9e 100644
--- a/src/TNL/Matrices/SlicedEllpack_impl.h
+++ b/src/TNL/Matrices/SlicedEllpack_impl.h
@@ -704,44 +704,40 @@ template< typename Real,
           typename Device,
           typename Index,
           int SliceSize >
-bool SlicedEllpack< Real, Device, Index, SliceSize >::save( File& file ) const
+void SlicedEllpack< Real, Device, Index, SliceSize >::save( File& file ) const
 {
-   if( ! Sparse< Real, Device, Index >::save( file ) ||
-       ! this->slicePointers.save( file ) ||
-       ! this->sliceCompressedRowLengths.save( file ) )
-      return false;
-   return true;
+   Sparse< Real, Device, Index >::save( file );
+   this->slicePointers.save( file );
+   this->sliceCompressedRowLengths.save( file );
 }
 
 template< typename Real,
           typename Device,
           typename Index,
           int SliceSize >
-bool SlicedEllpack< Real, Device, Index, SliceSize >::load( File& file )
+void SlicedEllpack< Real, Device, Index, SliceSize >::load( File& file )
 {
-   if( ! Sparse< Real, Device, Index >::load( file ) ||
-       ! this->slicePointers.load( file ) ||
-       ! this->sliceCompressedRowLengths.load( file ) )
-      return false;
-   return true;
+   Sparse< Real, Device, Index >::load( file );
+   this->slicePointers.load( file );
+   this->sliceCompressedRowLengths.load( file );
 }
 
 template< typename Real,
           typename Device,
           typename Index,
           int SliceSize >
-bool SlicedEllpack< Real, Device, Index, SliceSize >::save( const String& fileName ) const
+void SlicedEllpack< Real, Device, Index, SliceSize >::save( const String& fileName ) const
 {
-   return Object::save( fileName );
+   Object::save( fileName );
 }
 
 template< typename Real,
           typename Device,
           typename Index,
           int SliceSize >
-bool SlicedEllpack< Real, Device, Index, SliceSize >::load( const String& fileName )
+void SlicedEllpack< Real, Device, Index, SliceSize >::load( const String& fileName )
 {
-   return Object::load( fileName );
+   Object::load( fileName );
 }
 
 template< typename Real,
diff --git a/src/TNL/Matrices/Sparse.h b/src/TNL/Matrices/Sparse.h
index 069ade36cb989e18e1b6e1cc9821af5df50de8c1..7dc3798d22fa421655944f6ad6669725fece5e4c 100644
--- a/src/TNL/Matrices/Sparse.h
+++ b/src/TNL/Matrices/Sparse.h
@@ -48,9 +48,9 @@ class Sparse : public Matrix< Real, Device, Index >
 
    void reset();
 
-   bool save( File& file ) const;
+   void save( File& file ) const;
 
-   bool load( File& file );
+   void load( File& file );
 
    void printStructure( std::ostream& str ) const;
 
diff --git a/src/TNL/Matrices/Sparse_impl.h b/src/TNL/Matrices/Sparse_impl.h
index cd57637cbd773dc2ce25a13ad9b39191a7d2507b..13b7ee7a933c936f75d41b58f9e83a5467dce1e6 100644
--- a/src/TNL/Matrices/Sparse_impl.h
+++ b/src/TNL/Matrices/Sparse_impl.h
@@ -88,25 +88,21 @@ void Sparse< Real, Device, Index >::reset()
 template< typename Real,
           typename Device,
           typename Index >
-bool Sparse< Real, Device, Index >::save( File& file ) const
+void Sparse< Real, Device, Index >::save( File& file ) const
 {
-   if( ! Matrix< Real, Device, Index >::save( file ) ||
-       ! this->values.save( file ) ||
-       ! this->columnIndexes.save( file ) )
-      return false;
-   return true;
+   Matrix< Real, Device, Index >::save( file );
+   this->values.save( file );
+   this->columnIndexes.save( file );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool Sparse< Real, Device, Index >::load( File& file )
+void Sparse< Real, Device, Index >::load( File& file )
 {
-   if( ! Matrix< Real, Device, Index >::load( file ) ||
-       ! this->values.load( file ) ||
-       ! this->columnIndexes.load( file ) )
-      return false;
-   return true;
+   Matrix< Real, Device, Index >::load( file );
+   this->values.load( file );
+   this->columnIndexes.load( file );
 }
 
 template< typename Real,
diff --git a/src/TNL/Matrices/ThreePartVector.h b/src/TNL/Matrices/ThreePartVector.h
index b492879bdec0fd9c92788c585dad6814e2693a02..6afc2dd114150da67084ffd9b4394c3c81574ab0 100644
--- a/src/TNL/Matrices/ThreePartVector.h
+++ b/src/TNL/Matrices/ThreePartVector.h
@@ -118,7 +118,7 @@ public:
 
    ThreePartVectorView< ConstReal, Device, Index > getConstView()
    {
-      return {left, middle, right};
+      return {left.getConstView(), middle, right.getConstView()};
    }
 
 //   __cuda_callable__
diff --git a/src/TNL/Meshes/DistributedMeshes/DistributedGridIO_MeshFunction.h b/src/TNL/Meshes/DistributedMeshes/DistributedGridIO_MeshFunction.h
index 00342c7a948977c2c8c1acbdd313671050ca51a1..b9d3c5e24e7ad2c99a888c30e361711029bcb601 100644
--- a/src/TNL/Meshes/DistributedMeshes/DistributedGridIO_MeshFunction.h
+++ b/src/TNL/Meshes/DistributedMeshes/DistributedGridIO_MeshFunction.h
@@ -47,7 +47,7 @@ class DistributedGridIO<
 
          if(distrGrid==NULL) //not distributed
          {
-            return meshFunction.save(fileName);
+            meshFunction.save(fileName);
          }
 
          MeshType mesh=meshFunction.getMesh();
@@ -65,11 +65,7 @@ class DistributedGridIO<
          newMesh->setOrigin(origin+TNL::Containers::Scale(spaceSteps,localBegin));
 
          File meshFile;
-         if( ! meshFile.open( fileName+String("-mesh-")+distrGrid->printProcessCoords()+String(".tnl"),IOMode::write) )
-         {
-            std::cerr << "Failed to open mesh file for writing." << std::endl;
-            return false;
-         }
+         meshFile.open( fileName+String("-mesh-")+distrGrid->printProcessCoords()+String(".tnl"),File::Mode::Out );
          newMesh->save( meshFile );
          meshFile.close();
 
@@ -84,15 +80,11 @@ class DistributedGridIO<
          CopyEntitiesHelper<MeshFunctionType>::Copy(meshFunction,newMeshFunction,localBegin,zeroCoord,localSize);
 
          File file;
-         if( ! file.open( fileName+String("-")+distrGrid->printProcessCoords()+String(".tnl"), IOMode::write ) )
-         {
-            std::cerr << "Failed to open file for writing." << std::endl;
-            return false;
-         }
-         bool ret=newMeshFunction.save(file);
+         file.open( fileName+String("-")+distrGrid->printProcessCoords()+String(".tnl"), File::Mode::Out );
+         newMeshFunction.save(file);
          file.close();
 
-         return ret;
+         return true;
 
       };
             
@@ -101,7 +93,8 @@ class DistributedGridIO<
         auto *distrGrid=meshFunction.getMesh().getDistributedMesh();
         if(distrGrid==NULL) //not distributed
         {
-            return meshFunction.boundLoad(fileName);
+            meshFunction.boundLoad(fileName);
+            return true;
         }
 
         MeshType mesh=meshFunction.getMesh();
@@ -126,16 +119,12 @@ class DistributedGridIO<
         zeroCoord.setValue(0);        
 
         File file;
-        if( ! file.open( fileName+String("-")+distrGrid->printProcessCoords()+String(".tnl"), IOMode::read ) )
-        {
-            std::cerr << "Failed to open file for reading." << std::endl;
-            return false;
-        }
-        bool result=newMeshFunction.boundLoad(file);
+        file.open( fileName+String("-")+distrGrid->printProcessCoords()+String(".tnl"), File::Mode::In );
+        newMeshFunction.boundLoad(file);
         file.close();
         CopyEntitiesHelper<MeshFunctionType>::Copy(newMeshFunction,meshFunction,zeroCoord,localBegin,localSize);
         
-        return result;
+        return true;
     };
     
 };
@@ -165,7 +154,7 @@ class DistributedGridIO_MPIIOBase
         
         if(distrGrid==NULL) //not distributed
         {
-            return meshFunction.save(fileName);
+            meshFunction.save(fileName);
         }
 
        MPI_Comm group=*((MPI_Comm*)(distrGrid->getCommunicationGroup()));
@@ -307,7 +296,7 @@ class DistributedGridIO_MPIIOBase
         MPI_File_write(file,&meshFunctionSerializationTypeLength,1,MPI_INT,&wstatus);
         MPI_Get_count(&wstatus,MPI_INT,&count);
         size+=count*sizeof(int);
-        MPI_File_write(file,meshFunctionSerializationType.getString(),meshFunctionSerializationType.getLength(),MPI_CHAR,&wstatus);
+        MPI_File_write(file,const_cast< void* >( ( const void* ) meshFunctionSerializationType.getString() ),meshFunctionSerializationType.getLength(),MPI_CHAR,&wstatus);
         MPI_Get_count(&wstatus,MPI_CHAR,&count);
         size+=count*sizeof(char);
 
@@ -321,7 +310,7 @@ class DistributedGridIO_MPIIOBase
         MPI_File_write(file,&dataSerializationTypeLength,1,MPI_INT,&wstatus);
         MPI_Get_count(&wstatus,MPI_INT,&count);
         size+=count*sizeof(int);
-        MPI_File_write(file,dataSerializationType.getString(),dataSerializationType.getLength(),MPI_CHAR,&wstatus);
+        MPI_File_write( file, const_cast< void* >( ( const void* ) dataSerializationType.getString() ), dataSerializationType.getLength(), MPI_CHAR, &wstatus );
         MPI_Get_count(&wstatus,MPI_CHAR,&count);
         size+=count*sizeof(char);
         //Data count
@@ -332,12 +321,13 @@ class DistributedGridIO_MPIIOBase
         return size;
     };
 
-	static bool load(const String& fileName,MeshFunctionType &meshFunction, RealType* data )
-	{
-		auto *distrGrid=meshFunction.getMesh().getDistributedMesh();
+   static bool load(const String& fileName,MeshFunctionType &meshFunction, RealType* data )
+   {
+      auto *distrGrid=meshFunction.getMesh().getDistributedMesh();
       if(distrGrid==NULL) //not distributed
       {
-         return meshFunction.boundLoad(fileName);
+         meshFunction.boundLoad(fileName);
+         return true;
       }
 
       MPI_Comm group=*((MPI_Comm*)(distrGrid->getCommunicationGroup()));
@@ -352,11 +342,11 @@ class DistributedGridIO_MPIIOBase
          std::cerr << "Unable to open file " << fileName.getString() << std::endl;
          return false;
       }
-		bool ret= load(file, meshFunction, data,0)>0;
+      bool ret= load(file, meshFunction, data,0)>0;
 
       MPI_File_close(&file);
-		return ret;
-	}
+      return ret;
+   }
             
     /* Funky bomb - no checks - only dirty load */
     static int load(MPI_File &file,MeshFunctionType &meshFunction, RealType* data, int offset ) 
diff --git a/src/TNL/Meshes/DistributedMeshes/DistributedGridIO_VectorField.h b/src/TNL/Meshes/DistributedMeshes/DistributedGridIO_VectorField.h
index c3489994f69458bec85813f1915ce8aa245e681d..1ba844071df9c51843c6de26a5c459d17de19e50 100644
--- a/src/TNL/Meshes/DistributedMeshes/DistributedGridIO_VectorField.h
+++ b/src/TNL/Meshes/DistributedMeshes/DistributedGridIO_VectorField.h
@@ -49,7 +49,8 @@ class DistributedGridIO<
             auto *distrGrid=vectorField.getMesh().getDistributedMesh();
 			if(distrGrid==NULL)
 			{
-				return vectorField.save(fileName);
+				vectorField.save(fileName);
+                                return true;
 			}
 
             MPI_Comm group=*((MPI_Comm*)(distrGrid->getCommunicationGroup()));
@@ -105,7 +106,7 @@ class DistributedGridIO<
 		    MPI_File_write(file,&vectorFieldSerializationTypeLength,1,MPI_INT,&wstatus);
 		    MPI_Get_count(&wstatus,MPI_INT,&count);
 		    size+=count*sizeof(int);
-		    MPI_File_write(file,vectorFieldSerializationType.getString(),vectorFieldSerializationType.getLength(),MPI_CHAR,&wstatus);
+		    MPI_File_write(file,const_cast< void* >( ( const void* ) vectorFieldSerializationType.getString() ),vectorFieldSerializationType.getLength(),MPI_CHAR,&wstatus);
 		    MPI_Get_count(&wstatus,MPI_CHAR,&count);
 		    size+=count*sizeof(char);
 
@@ -139,7 +140,8 @@ class DistributedGridIO<
             auto *distrGrid=vectorField.getMesh().getDistributedMesh();
 			if(distrGrid==NULL)
 			{
-				return vectorField.save(fileName);
+				vectorField.save(fileName);
+                                return true;
 			}
 
             MPI_Comm group=*((MPI_Comm*)(distrGrid->getCommunicationGroup()));
diff --git a/src/TNL/Meshes/GridDetails/Grid1D.h b/src/TNL/Meshes/GridDetails/Grid1D.h
index 9a8f1460076d578837b48b7f0dbcee258e70d9f2..e4986c9fa140cf2f185204c2bdde16b41a01a999 100644
--- a/src/TNL/Meshes/GridDetails/Grid1D.h
+++ b/src/TNL/Meshes/GridDetails/Grid1D.h
@@ -208,22 +208,22 @@ class Grid< 1, Real, Device, Index > : public Object
    /**
     * \brief Method for saving the object to a file as a binary data
     */
-   bool save( File& file ) const;
+   void save( File& file ) const;
 
    /**
     * \brief Method for restoring the object from a file.
     */
-   bool load( File& file );
+   void load( File& file );
 
    /**
     * \brief Method for saving the object to a file.
     */
-   bool save( const String& fileName ) const;
+   void save( const String& fileName ) const;
 
    /**
     * \brief Method for restoring the object from a file.
     */
-   bool load( const String& fileName );
+   void load( const String& fileName );
 
    void writeProlog( Logger& logger ) const;
 
diff --git a/src/TNL/Meshes/GridDetails/Grid1D_impl.h b/src/TNL/Meshes/GridDetails/Grid1D_impl.h
index 995fa6dab31446cdd5e2a293e3377f04e97cb7ab..5f3e919c662ee40d0c9f6ca0c830b1824c7f305e 100644
--- a/src/TNL/Meshes/GridDetails/Grid1D_impl.h
+++ b/src/TNL/Meshes/GridDetails/Grid1D_impl.h
@@ -371,53 +371,41 @@ Grid< 1, Real, Device, Index >:: getDistributedMesh(void) const
 template< typename Real,
           typename Device,
           typename Index >
-bool Grid< 1, Real, Device, Index >::save( File& file ) const
+void Grid< 1, Real, Device, Index >::save( File& file ) const
 {
-   if( ! Object::save( file ) )
-      return false;
-   if( ! this->origin.save( file ) ||
-       ! this->proportions.save( file ) ||
-       ! this->dimensions.save( file ) )
-   {
-      std::cerr << "I was not able to save the domain description of a Grid." << std::endl;
-      return false;
-   }
-   return true;
+   Object::save( file );
+   this->origin.save( file );
+   this->proportions.save( file );
+   this->dimensions.save( file );
 };
 
 template< typename Real,
           typename Device,
           typename Index >
-bool Grid< 1, Real, Device, Index >::load( File& file )
+void Grid< 1, Real, Device, Index >::load( File& file )
 {
-   if( ! Object::load( file ) )
-      return false;
+   Object::load( file );
    CoordinatesType dimensions;
-   if( ! this->origin.load( file ) ||
-       ! this->proportions.load( file ) ||
-       ! dimensions.load( file ) )
-   {
-      std::cerr << "I was not able to load the domain description of a Grid." << std::endl;
-      return false;
-   }
+   this->origin.load( file );
+   this->proportions.load( file );
+   dimensions.load( file );
    this->setDimensions( dimensions );
-   return true;
 };
 
 template< typename Real,
           typename Device,
           typename Index >
-bool Grid< 1, Real, Device, Index >::save( const String& fileName ) const
+void Grid< 1, Real, Device, Index >::save( const String& fileName ) const
 {
-   return Object::save( fileName );
+   Object::save( fileName );
 }
 
 template< typename Real,
           typename Device,
           typename Index >
-bool Grid< 1, Real, Device, Index >::load( const String& fileName )
+void Grid< 1, Real, Device, Index >::load( const String& fileName )
 {
-   return Object::load( fileName );
+   Object::load( fileName );
 }
 
 template< typename Real,
diff --git a/src/TNL/Meshes/GridDetails/Grid2D.h b/src/TNL/Meshes/GridDetails/Grid2D.h
index f2dbebc5c78c36959a68a574886496c75857ca81..59ad153e229973033bd8c7b8c4501fa6992167f8 100644
--- a/src/TNL/Meshes/GridDetails/Grid2D.h
+++ b/src/TNL/Meshes/GridDetails/Grid2D.h
@@ -207,22 +207,22 @@ class Grid< 2, Real, Device, Index > : public Object
    /**
     * \brief See Grid1D::save( File& file ) const.
     */
-   bool save( File& file ) const;
+   void save( File& file ) const;
 
    /**
     * \brief See Grid1D::load( File& file ).
     */
-   bool load( File& file );
+   void load( File& file );
 
    /**
     * \brief See Grid1D::save( const String& fileName ) const.
     */
-   bool save( const String& fileName ) const;
+   void save( const String& fileName ) const;
 
    /**
     * \brief See Grid1D::load( const String& fileName ).
     */
-   bool load( const String& fileName );
+   void load( const String& fileName );
 
    void writeProlog( Logger& logger ) const;
 
diff --git a/src/TNL/Meshes/GridDetails/Grid2D_impl.h b/src/TNL/Meshes/GridDetails/Grid2D_impl.h
index 41e05d8b5a5853f8f5cc9d08ef8a0360b7202636..42f2601b67facfde7bd52a7bf62c5fea5ea4c618 100644
--- a/src/TNL/Meshes/GridDetails/Grid2D_impl.h
+++ b/src/TNL/Meshes/GridDetails/Grid2D_impl.h
@@ -453,53 +453,41 @@ Grid< 2, Real, Device, Index >:: getDistributedMesh(void) const
 template< typename Real,
           typename Device,
           typename Index >
-bool Grid< 2, Real, Device, Index > :: save( File& file ) const
+void Grid< 2, Real, Device, Index > :: save( File& file ) const
 {
-   if( ! Object::save( file ) )
-      return false;
-   if( ! this->origin.save( file ) ||
-       ! this->proportions.save( file ) ||
-       ! this->dimensions.save( file ) )
-   {
-      std::cerr << "I was not able to save the domain description of a Grid." << std::endl;
-      return false;
-   }
-   return true;
+   Object::save( file );
+   this->origin.save( file );
+   this->proportions.save( file );
+   this->dimensions.save( file );
 };
 
 template< typename Real,
           typename Device,
           typename Index >
-bool Grid< 2, Real, Device, Index > :: load( File& file )
+void Grid< 2, Real, Device, Index > :: load( File& file )
 {
-   if( ! Object::load( file ) )
-      return false;
+   Object::load( file );
    CoordinatesType dimensions;
-   if( ! this->origin.load( file ) ||
-       ! this->proportions.load( file ) ||
-       ! dimensions.load( file ) )
-   {
-      std::cerr << "I was not able to load the domain description of a Grid." << std::endl;
-      return false;
-   }
+   this->origin.load( file );
+   this->proportions.load( file );
+   dimensions.load( file );
    this->setDimensions( dimensions );
-   return true;
 };
 
 template< typename Real,
           typename Device,
           typename Index >
-bool Grid< 2, Real, Device, Index > :: save( const String& fileName ) const
+void Grid< 2, Real, Device, Index > :: save( const String& fileName ) const
 {
-   return Object :: save( fileName );
+   Object::save( fileName );
 };
 
 template< typename Real,
            typename Device,
            typename Index >
-bool Grid< 2, Real, Device, Index > :: load( const String& fileName )
+void Grid< 2, Real, Device, Index > :: load( const String& fileName )
 {
-   return Object :: load( fileName );
+   Object::load( fileName );
 };
 
 template< typename Real,
diff --git a/src/TNL/Meshes/GridDetails/Grid3D.h b/src/TNL/Meshes/GridDetails/Grid3D.h
index 617efe7f31bc9e8b5ef3898e0f75eb9cf1ada11a..232c3680549a7956e9275e5a477fa43fc63370a6 100644
--- a/src/TNL/Meshes/GridDetails/Grid3D.h
+++ b/src/TNL/Meshes/GridDetails/Grid3D.h
@@ -208,22 +208,22 @@ class Grid< 3, Real, Device, Index > : public Object
    /**
     * \brief See Grid1D::save( File& file ) const.
     */
-   bool save( File& file ) const;
+   void save( File& file ) const;
 
    /**
     * \brief See Grid1D::load( File& file ).
     */
-   bool load( File& file );
+   void load( File& file );
 
    /**
     * \brief See Grid1D::save( const String& fileName ) const.
     */
-   bool save( const String& fileName ) const;
+   void save( const String& fileName ) const;
 
    /**
     * \brief See Grid1D::load( const String& fileName ).
     */
-   bool load( const String& fileName );
+   void load( const String& fileName );
 
    void writeProlog( Logger& logger ) const;
 
diff --git a/src/TNL/Meshes/GridDetails/Grid3D_impl.h b/src/TNL/Meshes/GridDetails/Grid3D_impl.h
index edbee0c006bc50e2575262efc64f5b2978d13034..4908ad7074df5d828049ff41339147a00b2a8551 100644
--- a/src/TNL/Meshes/GridDetails/Grid3D_impl.h
+++ b/src/TNL/Meshes/GridDetails/Grid3D_impl.h
@@ -535,53 +535,41 @@ Grid< 3, Real, Device, Index >:: getDistributedMesh(void) const
 template< typename Real,
           typename Device,
           typename Index >
-bool Grid< 3, Real, Device, Index > :: save( File& file ) const
+void Grid< 3, Real, Device, Index > :: save( File& file ) const
 {
-   if( ! Object::save( file ) )
-      return false;
-   if( ! this->origin.save( file ) ||
-       ! this->proportions.save( file ) ||
-       ! this->dimensions.save( file ) )
-   {
-      std::cerr << "I was not able to save the domain description of a Grid." << std::endl;
-      return false;
-   }
-   return true;
+   Object::save( file );
+   this->origin.save( file );
+   this->proportions.save( file );
+   this->dimensions.save( file );
 };
 
 template< typename Real,
           typename Device,
           typename Index >
-bool Grid< 3, Real, Device, Index > :: load( File& file )
+void Grid< 3, Real, Device, Index >::load( File& file )
 {
-   if( ! Object :: load( file ) )
-      return false;
+   Object :: load( file );
    CoordinatesType dimensions;
-   if( ! this->origin.load( file ) ||
-       ! this->proportions.load( file ) ||
-       ! dimensions.load( file ) )
-   {
-      std::cerr << "I was not able to load the domain description of a Grid." << std::endl;
-      return false;
-   }
+   this->origin.load( file );
+   this->proportions.load( file );
+   dimensions.load( file );
    this->setDimensions( dimensions );
-   return true;
 };
 
 template< typename Real,
           typename Device,
           typename Index >
-bool Grid< 3, Real, Device, Index > :: save( const String& fileName ) const
+void Grid< 3, Real, Device, Index >::save( const String& fileName ) const
 {
-   return Object :: save( fileName );
+   Object::save( fileName );
 };
 
 template< typename Real,
           typename Device,
           typename Index >
-bool Grid< 3, Real, Device, Index > :: load( const String& fileName )
+void Grid< 3, Real, Device, Index >::load( const String& fileName )
 {
-   return Object :: load( fileName );
+   Object::load( fileName );
 };
 
 template< typename Real,
diff --git a/src/TNL/Meshes/GridDetails/GridTraverser_1D.hpp b/src/TNL/Meshes/GridDetails/GridTraverser_1D.hpp
index 5b35d5be972516d945da497837fc5711d62bb693..42ba1b636a0a7626097f32d8283c88798de4d65e 100644
--- a/src/TNL/Meshes/GridDetails/GridTraverser_1D.hpp
+++ b/src/TNL/Meshes/GridDetails/GridTraverser_1D.hpp
@@ -185,7 +185,7 @@ processEntities(
    auto& pool = CudaStreamPool::getInstance();
    const cudaStream_t& s = pool.getStream( stream );
 
-   //Devices::Cuda::synchronizeDevice();
+   Devices::Cuda::synchronizeDevice();
    if( processOnlyBoundaryEntities )
    {
       dim3 cudaBlockSize( 2 );
diff --git a/src/TNL/Meshes/Mesh.h b/src/TNL/Meshes/Mesh.h
index 793f1b0bbf925fa720e2cf4c583054b6c6466f43..589a862b9228bfbc7b1108c3caa51af6303532c0 100644
--- a/src/TNL/Meshes/Mesh.h
+++ b/src/TNL/Meshes/Mesh.h
@@ -160,9 +160,9 @@ class Mesh
                             const GlobalIndexVector& iperm );
 
 
-      bool save( File& file ) const;
+      void save( File& file ) const;
 
-      bool load( File& file );
+      void load( File& file );
 
       using Object::load;
       using Object::save;
diff --git a/src/TNL/Meshes/MeshDetails/MeshLayers/BoundaryTags/Layer.h b/src/TNL/Meshes/MeshDetails/MeshLayers/BoundaryTags/Layer.h
index f743fd25e435ef32b8aa50a550a229772d08d89e..99a0e612667ed157f153d5a120ecd497cdc70110 100644
--- a/src/TNL/Meshes/MeshDetails/MeshLayers/BoundaryTags/Layer.h
+++ b/src/TNL/Meshes/MeshDetails/MeshLayers/BoundaryTags/Layer.h
@@ -170,7 +170,11 @@ public:
 
    bool save( File& file ) const
    {
-      if( ! boundaryTags.save( file ) )
+      try
+      {
+         boundaryTags.save( file );
+      }
+      catch(...)
       {
          std::cerr << "Failed to save the boundary tags of the entities with dimension " << DimensionTag::value << "." << std::endl;
          return false;
@@ -180,7 +184,11 @@ public:
 
    bool load( File& file )
    {
-      if( ! boundaryTags.load( file ) )
+      try
+      {
+         boundaryTags.load( file );
+      }
+      catch(...)
       {
          std::cerr << "Failed to load the boundary tags of the entities with dimension " << DimensionTag::value << "." << std::endl;
          return false;
diff --git a/src/TNL/Meshes/MeshDetails/MeshLayers/StorageLayer.h b/src/TNL/Meshes/MeshDetails/MeshLayers/StorageLayer.h
index 80bb94da67d4f89b62f2d99794686f4a031a0bb5..a9d25d8438316f34782cb8d4cf14c97573dd0b96 100644
--- a/src/TNL/Meshes/MeshDetails/MeshLayers/StorageLayer.h
+++ b/src/TNL/Meshes/MeshDetails/MeshLayers/StorageLayer.h
@@ -141,10 +141,14 @@ public:
 
    bool save( File& file ) const
    {
-      if( ! SubentityStorageBaseType::save( file ) ||
-          ! SuperentityStorageBaseType::save( file ) ||
-          ! this->entities.save( file ) ||
-          ! BaseType::save( file ) )
+      try
+      {
+         SubentityStorageBaseType::save( file );
+         SuperentityStorageBaseType::save( file );
+         this->entities.save( file );
+         BaseType::save( file );
+      }
+      catch(...)
       {
          std::cerr << "Saving of the mesh entities with dimension " << DimensionTag::value << " failed." << std::endl;
          return false;
@@ -154,10 +158,14 @@ public:
 
    bool load( File& file )
    {
-      if( ! SubentityStorageBaseType::load( file ) ||
-          ! SuperentityStorageBaseType::load( file ) ||
-          ! this->entities.load( file ) ||
-          ! BaseType::load( file ) )
+      try
+      {
+         SubentityStorageBaseType::load( file );
+         SuperentityStorageBaseType::load( file );
+         this->entities.load( file );
+         BaseType::load( file );
+      }
+      catch(...)
       {
          std::cerr << "Loading of the mesh entities with dimension " << DimensionTag::value << " failed." << std::endl;
          return false;
diff --git a/src/TNL/Meshes/MeshDetails/MeshLayers/SubentityStorageLayer.h b/src/TNL/Meshes/MeshDetails/MeshLayers/SubentityStorageLayer.h
index c26e525a9c5e532708a3bb430bdeb140b56f0dc4..cd4d9edf00c6da911b5bf172094dcc04df6d9aaf 100644
--- a/src/TNL/Meshes/MeshDetails/MeshLayers/SubentityStorageLayer.h
+++ b/src/TNL/Meshes/MeshDetails/MeshLayers/SubentityStorageLayer.h
@@ -107,8 +107,12 @@ protected:
 
    bool save( File& file ) const
    {
-      if( ! BaseType::save( file ) ||
-          ! this->storageNetwork.save( file ) )
+      try
+      {
+         BaseType::save( file );
+         this->storageNetwork.save( file );
+      }
+      catch(...)
       {
          std::cerr << "Saving of the entity subentities layer with " << SubdimensionTag::value << " dimension failed." << std::endl;
          return false;
@@ -118,8 +122,12 @@ protected:
 
    bool load( File& file )
    {
-      if( ! BaseType::load( file ) ||
-          ! this->storageNetwork.load( file ) )
+      try
+      {
+         BaseType::load( file );
+         this->storageNetwork.load( file );
+      }
+      catch(...)
       {
          std::cerr << "Loading of the entity subentities layer with " << SubdimensionTag::value << " dimension failed." << std::endl;
          return false;
diff --git a/src/TNL/Meshes/MeshDetails/MeshLayers/SuperentityStorageLayer.h b/src/TNL/Meshes/MeshDetails/MeshLayers/SuperentityStorageLayer.h
index 62d86fe7bff83042f19ab41f68023c91c4cf83ee..7e49a3155cc389d08655387874977e038db2cfa6 100644
--- a/src/TNL/Meshes/MeshDetails/MeshLayers/SuperentityStorageLayer.h
+++ b/src/TNL/Meshes/MeshDetails/MeshLayers/SuperentityStorageLayer.h
@@ -109,8 +109,12 @@ protected:
 
    bool save( File& file ) const
    {
-      if( ! BaseType::save( file ) ||
-          ! this->storageNetwork.save( file ) )
+      try
+      {
+         BaseType::save( file );
+         this->storageNetwork.save( file );
+      }
+      catch(...)
       {
          std::cerr << "Saving of the entity superentities layer with " << SuperdimensionTag::value << " dimension failed." << std::endl;
          return false;
@@ -120,8 +124,12 @@ protected:
 
    bool load( File& file )
    {
-      if( ! BaseType::load( file ) ||
-          ! this->storageNetwork.load( file ) )
+      try
+      {
+         BaseType::load( file );
+         this->storageNetwork.load( file );
+      }
+      catch(...)
       {
          std::cerr << "Loading of the entity superentities layer with " << SuperdimensionTag::value << " dimension failed." << std::endl;
          return false;
diff --git a/src/TNL/Meshes/MeshDetails/Mesh_impl.h b/src/TNL/Meshes/MeshDetails/Mesh_impl.h
index cd704edafc8dd0488ef971586235ed8534ccb0b3..3f00336a8df0f225dc6614ad23a061e8d99207dc 100644
--- a/src/TNL/Meshes/MeshDetails/Mesh_impl.h
+++ b/src/TNL/Meshes/MeshDetails/Mesh_impl.h
@@ -212,8 +212,8 @@ reorderEntities( const GlobalIndexVector& perm,
    // basic sanity check
    if( perm.getSize() != entitiesCount || iperm.getSize() != entitiesCount ) {
       throw std::logic_error( "Wrong size of permutation vectors: "
-                              "perm = " + std::to_string( perm ) + ", "
-                              "iperm = " + std::to_string( iperm ) );
+                              "perm size = " + std::to_string( perm.getSize() ) + ", "
+                              "iperm size = " + std::to_string( iperm.getSize() ) );
    }
    TNL_ASSERT( perm.min() == 0 && perm.max() == entitiesCount - 1,
                std::cerr << "Given array is not a permutation: min = " << perm.min()
@@ -236,35 +236,25 @@ reorderEntities( const GlobalIndexVector& perm,
 
 
 template< typename MeshConfig, typename Device >
-bool
+void
 Mesh< MeshConfig, Device >::
 save( File& file ) const
 {
-   if( ! Object::save( file ) ||
-       ! StorageBaseType::save( file ) ||
-       ! BoundaryTagsLayerFamily::save( file ) )
-   {
-      std::cerr << "Mesh saving failed." << std::endl;
-      return false;
-   }
-   return true;
+   Object::save( file );
+   StorageBaseType::save( file );
+   BoundaryTagsLayerFamily::save( file );
 }
 
 template< typename MeshConfig, typename Device >
-bool
+void
 Mesh< MeshConfig, Device >::
 load( File& file )
 {
-   if( ! Object::load( file ) ||
-       ! StorageBaseType::load( file ) ||
-       ! BoundaryTagsLayerFamily::load( file ) )
-   {
-      std::cerr << "Mesh loading failed." << std::endl;
-      return false;
-   }
+   Object::load( file );
+   StorageBaseType::load( file );
+   BoundaryTagsLayerFamily::load( file );
    // update pointers from entities into the subentity and superentity storage networks
    EntityStorageRebinder< Mesh< MeshConfig, Device > >::exec( *this );
-   return true;
 }
 
 template< typename MeshConfig, typename Device >
diff --git a/src/TNL/Meshes/Readers/TNLReader.h b/src/TNL/Meshes/Readers/TNLReader.h
index 68f4d13a21c99bb2ce93bd6e0bdf2f0e32f1bcf4..6100a5119474fde61ad49c450def2a77ff84f53e 100644
--- a/src/TNL/Meshes/Readers/TNLReader.h
+++ b/src/TNL/Meshes/Readers/TNLReader.h
@@ -12,6 +12,7 @@
 
 #include <TNL/String.h>
 #include <TNL/Object.h>
+#include <TNL/Exceptions/ObjectTypeDetectionFailure.h>
 #include <TNL/Meshes/Readers/EntityShape.h>
 
 namespace TNL {
@@ -28,9 +29,13 @@ public:
       this->fileName = fileName;
 
       String objectType;
-      if( ! getObjectType( fileName, objectType ) ) {
-         std::cerr << "Failed to detect the mesh type from the file " << fileName << "." << std::endl;
-         return EXIT_FAILURE;
+      try
+      {
+         objectType = getObjectType( fileName );
+      }
+      catch( ... )
+      {
+         throw Exceptions::ObjectTypeDetectionFailure( fileName, "mesh" );
       }
 
       const std::vector< String > parsedMeshType = parseObjectType( objectType );
@@ -103,7 +108,8 @@ public:
    static bool
    readMesh( const String& fileName, MeshType& mesh )
    {
-      return mesh.load( fileName );
+      mesh.load( fileName );
+      return true;
    }
 
    String
diff --git a/src/TNL/Meshes/TypeResolver/TypeResolver_impl.h b/src/TNL/Meshes/TypeResolver/TypeResolver_impl.h
index b3fe7f1ba5f9ae9d85af8d508e7a5ab1b4a0795d..6c60126457d1d4aa33426631b836407be6a412d7 100644
--- a/src/TNL/Meshes/TypeResolver/TypeResolver_impl.h
+++ b/src/TNL/Meshes/TypeResolver/TypeResolver_impl.h
@@ -130,7 +130,7 @@ loadMesh( const String& fileName,
    bool status = true;
 
    if( ends_with( fileName_, ".tnl" ) )
-      status = mesh.load( fileName );
+      mesh.load( fileName );
    else if( ends_with( fileName_, ".ng" ) ) {
       Readers::NetgenReader reader;
       status = reader.readMesh( fileName, mesh );
@@ -210,7 +210,11 @@ loadMesh( const String& fileName,
    {
       std::cout << "Loading a global mesh from the file " << fileName << "...";
       Grid< Dimension, Real, Device, Index > globalGrid;
-      if( ! globalGrid.load( fileName ) )
+      try
+      {
+         globalGrid.load( fileName );
+      }
+      catch(...)
       {
          std::cerr << std::endl;
          std::cerr << "I am not able to load the global mesh from the file " << fileName << "." << std::endl;
@@ -226,7 +230,11 @@ loadMesh( const String& fileName,
    else
    {
       std::cout << "Loading a mesh from the file " << fileName << "...";
-      if( ! mesh.load( fileName ) )
+      try
+      {
+         mesh.load( fileName );
+      }
+      catch(...)
       {
          std::cerr << std::endl;
          std::cerr << "I am not able to load the mesh from the file " << fileName << "." << std::endl;
diff --git a/src/TNL/Object.h b/src/TNL/Object.h
index d909a21edda099e8b4c8fd70a8a1f9499918ad42..92ed9fef7821cd3bb295d7b5eeace72e3f1a50bf 100644
--- a/src/TNL/Object.h
+++ b/src/TNL/Object.h
@@ -22,40 +22,68 @@
 namespace TNL {
 
 /**
- * \brief Basic class for all 'large' objects like matrices, meshes, grids, solvers, etc..
+ * \brief Basic class for majority of TNL objects like matrices, meshes, grids, solvers, etc..
  *
- *  Objects like numerical grids, meshes, matrices large vectors etc.
- *  are inherited by this class. This class provides name for such objects. Giving
- *  a name to each bigger object is compulsory. The name can help to locate
- *  possible errors in the code. This can help to identify an object where, for
- *  example, one tries to touch non-existing element. All objects of the TNL should
- *  have only constructor with name and then only setter methods and method init.
- *  Each object derived from the Object must be able to tell its type via the method
- *  \ref getType and it must support methods \ref save and \ref load for saving and
- *  loading the object from a \ref File "file".
+ * Objects like numerical meshes, matrices large vectors etc. are inherited by 
+ * this class. This class introduces virtual method \ref getType which is 
+ * supposed to tell the object type in a C++ style.
+ * 
+ * Since the virtual destructor is not defined as \ref __cuda_callable__, 
+ * objects inherited from Object should not be created in CUDA kernels.
+ * 
+ * In addition to methods of this class, see the following related functions:
+ * 
+ * \ref getObjectType
+ * 
+ * \ref parseObjectType
+ * 
  */
 class Object
 {
    public:
 
       /**
-       * \brief Type getter.
+       * \brief Static type getter.
        *
        * Returns the type in C++ style - for example the returned value
-       * may look as \c "Vector< double, Devices::Cuda >".
+       * may look as \c "Array< double, Devices::Cuda, int >".
+       * 
+       * \par Example
+       * \include ObjectExample_getType.cpp
+       * \par Output
+       * \include ObjectExample_getType.out
        */
-      static String getType();      
+      static String getType();
 
-      virtual String getTypeVirtual() const;   
+      /***
+       * \brief Virtual type getter.
+       * 
+       * Returns the type in C++ style - for example the returned value
+       * may look as \c "Array< double, Devices::Cuda, int >".
+       * See example at \ref Object::getType.
+       */
+      virtual String getTypeVirtual() const;
 
       /**
-       * \brief This is used for load and save methods.
+       * \brief Static serialization type getter.
        *
-       * Each object is saved as if it was stored on \ref Devices::Host. So even
-       * \c Vector< double, Devices::Cuda > is saved as \c Vector< double, Devices::Host >.
+       * Objects in TNL are saved as in a device independent manner. This method
+       * is supposed to return the object type but with the device type replaced 
+       * by Devices::Host. For example \c Array< double, Devices::Cuda > is
+       * saved as \c Array< double, Devices::Host >.
+       * See example at \ref Object::getType.
        */
       static String getSerializationType();
 
+      /***
+       * \brief Virtual serialization type getter.
+       * 
+       * Objects in TNL are saved as in a device independent manner. This method
+       * is supposed to return the object type but with the device type replaced 
+       * by Devices::Host. For example \c Array< double, Devices::Cuda > is
+       * saved as \c Array< double, Devices::Host >.
+       * See example at \ref Object::getType.
+       */
       virtual String getSerializationTypeVirtual() const;
 
       /**
@@ -63,59 +91,89 @@ class Object
        *
        * \param file Name of file object.
        */
-      virtual bool save( File& file ) const;
+      virtual void save( File& file ) const;
 
       /**
        * \brief Method for restoring the object from a file.
        *
        * \param file Name of file object.
        */
-      virtual bool load( File& file );
+      virtual void load( File& file );
 
       /**
        * \brief Method for restoring the object from a file.
        *
        * \param file Name of file object.
        */
-      virtual bool boundLoad( File& file );
+      virtual void boundLoad( File& file );
 
       /**
        * \brief Method for saving the object to a file as a binary data.
        *
        * \param fileName String defining the name of a file.
        */
-      bool save( const String& fileName ) const;
+      void save( const String& fileName ) const;
 
       /**
        * \brief Method for restoring the object from a file.
        *
        * \param fileName String defining the name of a file.
        */
-      bool load( const String& fileName );
+      void load( const String& fileName );
 
        /**
        * \brief Method for restoring the object from a file.
        *
        * \param fileName String defining the name of a file.
        */
-      bool boundLoad( const String& fileName );
+      void boundLoad( const String& fileName );
       
-      /// Destructor.
-      // FIXME: __cuda_callable__ would have to be added to every overriding destructor,
-      // even if the object's constructor is not __cuda_callable__
-      //   __cuda_callable__
+      /**
+       * \brief Destructor.
+       * 
+       * Since it is not defined as \ref __cuda_callable__, objects inherited
+       * from Object should not be created in CUDA kernels.
+       */
 #ifndef HAVE_MIC
       virtual ~Object(){};
 #endif
 };
 
-bool getObjectType( File& file, String& type );
+/**
+ * \brief Extracts object type from a binary file.
+ * 
+ * @param file is file where the object is stored
+ * @return string with the object type
+ */
+String getObjectType( File& file );
 
-bool getObjectType( const String& file_name, String& type );
+/**
+ * \brief Does the same as \ref getObjectType but with a \e fileName parameter instead of file.
+ * 
+ * @param fileName name of a file where the object is stored
+ * @return string with the object type
+ */
+String getObjectType( const String& fileName );
 
+/**
+ * \brief Parses the object type
+ * 
+ * @param objectType is a string with the object type to be parsed.
+ * @return vector of strings where the first one is the object type and the next
+ * strings are the template parameters.
+ *
+ * \par Example
+ * \include ParseObjectTypeExample.cpp
+ * \par Output
+ * \include ParseObjectTypeExample.out
+ */
 std::vector< String >
 parseObjectType( const String& objectType );
 
+inline void saveHeader( File& file, const String& type );
+
+inline void loadHeader( File& file, String& type );
+
 } // namespace TNL
 
-#include <TNL/Object_impl.h>
+#include <TNL/Object.hpp>
diff --git a/src/TNL/Object_impl.h b/src/TNL/Object.hpp
similarity index 54%
rename from src/TNL/Object_impl.h
rename to src/TNL/Object.hpp
index f0b1a8545ac0769e270b6804463f7d2af1aa64ac..1e83f036f123cff75fafe63bbcb6b9cc3fba50db 100644
--- a/src/TNL/Object_impl.h
+++ b/src/TNL/Object.hpp
@@ -15,113 +15,88 @@
 #include <cstring>
 
 #include <TNL/Object.h>
+#include <TNL/Exceptions/NotTNLFile.h>
+#include <TNL/Exceptions/ObjectTypeMismatch.h>
 
 namespace TNL {
 
 static constexpr char magic_number[] = "TNLMN";
 
-inline String Object :: getType()
+inline String Object::getType()
 {
    return String( "Object" );
 }
 
-inline String Object :: getTypeVirtual() const
+inline String Object::getTypeVirtual() const
 {
    return this->getType();
 }
 
-inline String Object :: getSerializationType()
+inline String Object::getSerializationType()
 {
    return String( "Object" );
 }
 
-inline String Object :: getSerializationTypeVirtual() const
+inline String Object::getSerializationTypeVirtual() const
 {
    return this->getSerializationType();
 }
 
-inline bool Object :: save( File& file ) const
+inline void Object::save( File& file ) const
 {
-   if( ! file.write( magic_number, strlen( magic_number ) ) )
-      return false;
+   file.save( magic_number, strlen( magic_number ) );
    file << this->getSerializationTypeVirtual();
-   return true;
 }
 
-inline bool Object :: load( File& file )
+inline void Object::load( File& file )
 {
-   String objectType;
-   if( ! getObjectType( file, objectType ) )
-      return false;
+   String objectType = getObjectType( file );
    if( objectType != this->getSerializationTypeVirtual() )
-   {
-      std::cerr << "Given file contains instance of " << objectType << " but " << getSerializationTypeVirtual() << " is expected." << std::endl;
-      return false;
-   }
-   return true;
+      throw Exceptions::ObjectTypeMismatch( this->getSerializationTypeVirtual(), objectType );
 }
 
-inline bool Object :: boundLoad( File& file )
+inline void Object::boundLoad( File& file )
 {
-   return load( file );
+   this->load( file );
 }
 
-inline bool Object :: save( const String& fileName ) const
+inline void Object::save( const String& fileName ) const
 {
    File file;
-   if( ! file.open( fileName, IOMode::write ) )
-   {
-      std::cerr << "I am not able to open the file " << fileName << " for writing." << std::endl;
-      return false;
-   }
-   return this->save( file );
+   file.open( fileName, File::Mode::Out );
+   this->save( file );
 }
 
-inline bool Object :: load( const String& fileName )
+inline void Object::load( const String& fileName )
 {
    File file;
-   if( ! file.open( fileName, IOMode::read ) )
-   {
-      std::cerr << "I am not able to open the file " << fileName << " for reading." << std::endl;
-      return false;
-   }
-   return this->load( file );
+   file.open( fileName, File::Mode::In );
+   this->load( file );
 }
 
-inline bool Object :: boundLoad( const String& fileName )
+inline void Object::boundLoad( const String& fileName )
 {
    File file;
-   if( ! file.open( fileName, IOMode::read ) )
-   {
-      std::cerr << "I am not able to open the file " << fileName << " for reading." << std::endl;
-      return false;
-   }
-   return this->boundLoad( file );
+   file.open( fileName, File::Mode::In );
+   this->boundLoad( file );
 }
 
-
-inline bool getObjectType( File& file, String& type )
+inline String getObjectType( File& file )
 {
    char mn[ 10 ];
-   file.read( mn, strlen( magic_number ) );
+   String type;
+   file.load( mn, strlen( magic_number ) );
    if( strncmp( mn, magic_number, 5 ) != 0 )
-   {
-       std::cout << "Not a TNL file (wrong magic number)." << std::endl;
-       return false;
-   }
+      throw Exceptions::NotTNLFile();
    file >> type;
-   return true;
+   return type;
 }
 
-inline bool getObjectType( const String& fileName, String& type )
+inline String getObjectType( const String& fileName )
 {
    File binaryFile;
-   if( ! binaryFile.open( fileName, IOMode::read ) )
-   {
-      std::cerr << "I am not able to open the file " << fileName << " for detecting the object inside!" << std::endl;
-      return false;
-   }
-   return getObjectType( binaryFile, type );
+   binaryFile.open( fileName, File::Mode::In );
+   return getObjectType( binaryFile );
 }
 
 inline std::vector< String >
@@ -176,4 +151,21 @@ parseObjectType( const String& objectType )
    return parsedObjectType;
 }
 
+inline void saveHeader( File& file, const String& type )
+{
+   file.save( magic_number, strlen( magic_number ) );
+   file << type;
+}
+
+inline void loadHeader( File& file, String& type )
+{
+   char mn[ 10 ];
+   file.load( mn, strlen( magic_number ) );
+   if( strncmp( mn, magic_number, 5 ) != 0 )
+      throw Exceptions::NotTNLFile();
+   file >> type;
+}
+
+
+
 } // namespace TNL
diff --git a/src/TNL/Problems/HeatEquationProblem_impl.h b/src/TNL/Problems/HeatEquationProblem_impl.h
index 03be60b3b1a39922ba7bd24b8e92264b3fb2dd5a..0c0cd7418e5f88235f7acb751f3404e404ab636e 100644
--- a/src/TNL/Problems/HeatEquationProblem_impl.h
+++ b/src/TNL/Problems/HeatEquationProblem_impl.h
@@ -162,12 +162,16 @@ setInitialCondition( const Config::ParameterContainer& parameters,
     }
     else
     {
-       if( ! this->uPointer->boundLoad( initialConditionFile ) )
-       {
-          std::cerr << "I am not able to load the initial condition from the file " << initialConditionFile << "." << std::endl;
-          return false;
-       }
-    }
+      try
+      {
+         this->uPointer->boundLoad( initialConditionFile );
+      }
+      catch(...)
+      {
+         std::cerr << "I am not able to load the initial condition from the file " << initialConditionFile << "." << std::endl;
+         return false;
+      }
+   }
    return true;
 }
 
@@ -226,8 +230,7 @@ makeSnapshot( const RealType& time,
    }
    else
    {
-      if( ! this->uPointer->save( fileName.getFileName() ) )
-         return false;
+      this->uPointer->save( fileName.getFileName() );
    }
    return true;
 }
diff --git a/src/TNL/Solvers/Linear/GMRES_impl.h b/src/TNL/Solvers/Linear/GMRES_impl.h
index 17f8dd1f38fe64ae96fafe8735a23ea331dfb2a1..4731ccaf7d36ce6e0c7db2857b55f10eb60cf369 100644
--- a/src/TNL/Solvers/Linear/GMRES_impl.h
+++ b/src/TNL/Solvers/Linear/GMRES_impl.h
@@ -185,7 +185,8 @@ orthogonalize_MGS( const int m, const RealType normb, const RealType beta )
 {
    // initial binding to _M_tmp sets the correct local range, global size and
    // communication group for distributed views
-   VectorViewType v_i( _M_tmp ), v_k( _M_tmp );
+   VectorViewType v_i( _M_tmp.getView() );
+   VectorViewType v_k( _M_tmp.getView() );
 
    /***
     * v_0 = r / | r | =  1.0 / beta * r
@@ -258,7 +259,8 @@ orthogonalize_CWY( const int m, const RealType normb, const RealType beta )
 {
    // initial binding to _M_tmp sets the correct local range, global size and
    // communication group for distributed views
-   VectorViewType v_i( _M_tmp ), y_i( _M_tmp );
+   VectorViewType v_i( _M_tmp.getView() );
+   VectorViewType y_i( _M_tmp.getView() );
 
    /***
     * z = r / | r | =  1.0 / beta * r
diff --git a/src/TNL/String.h b/src/TNL/String.h
index 3da2ffbf4b74d63665140ad980d00640d921855d..a04802216c2dd14a6495b30146a49066f708820e 100644
--- a/src/TNL/String.h
+++ b/src/TNL/String.h
@@ -1,4 +1,4 @@
-/***************************************************************************
+/*************************************************************************
                           String.h  -  description
                              -------------------
     begin                : 2004/04/10 16:35
@@ -23,226 +23,361 @@ namespace TNL {
 
 class String;
 
-/////
-/// \brief Class for managing strings.
-///
-/// \par Example
-/// \include StringExample.cpp
-/// \par Output
-/// \include StringExample.out
+/**
+ * \brief Class for managing strings.
+ *
+ * The following example shows common use of String.
+ * 
+ * \par Example
+ * \include StringExample.cpp
+ * \par Output
+ * \include StringExample.out
+ * 
+ * In addition to methods of this class, check the following related functions:
+ * 
+ * \ref convertToString
+ * 
+ * \ref operator+
+ * 
+ * \ref operator<<
+ * 
+ * \ref mpiSend
+ * 
+ * \ref mpiReceive
+ */
 class String
 : public std::string
 {
-public:
-   /////
-   /// \brief Default constructor.
-   ///
-   /// Constructs an empty string object.
-   String() = default;
-
-   /// \brief Default copy constructor.
-   String( const String& ) = default;
-
-   /// \brief Default move constructor.
-   String( String&& ) = default;
-
-   /// \brief Initialization by \e std::string.
-   String( const std::string& str ) : std::string( str ) {}
-
-   /// \brief Default copy assignment operator.
-   String& operator=( const String& ) = default;
-
-   /// \brief Default move assignment operator.
-   String& operator=( String&& ) = default;
-
-   /// \brief Inherited constructors and assignment operators.
-   using std::string::string;
-   using std::string::operator=;
-
-
-   /// \brief Returns type of string: \c "String".
-   static String getType();
-
-   /// \brief Returns the number of characters in given string. Equivalent to \ref getSize.
-   int getLength() const;
-
-   /// \brief Returns the number of characters in given string.
-   ///
-   /// \par Example
-   /// \include StringExampleGetSize.cpp
-   /// \par Output
-   /// \include StringExampleGetSize.out
-   int getSize() const;
-
-   /// \brief Returns size of allocated storage for given string.
-   ///
-   /// \par Example
-   /// \include StringExampleGetAllocatedSize.cpp
-   /// \par Output
-   /// \include StringExampleGetAllocatedSize.out
-   int getAllocatedSize() const;
-
-   /////
-   /// \brief Reserves space for given \e size.
-   ///
-   /// Requests to allocate storage space of given \e size to avoid memory reallocation.
-   /// It allocates one more byte for the terminating 0.
-   /// @param size Number of characters.
-   ///
-   /// \par Example
-   /// \include StringExampleSetSize.cpp
-   /// \par Output
-   /// \include StringExampleSetSize.out
-   void setSize( int size );
-
-   /////
-   /// \brief Returns pointer to data.
-   ///
-   /// It returns the content of the given string as a constant pointer to char.
-   const char* getString() const;
-
-   /////
-   /// \brief Operator for accessing particular chars of the string.
-   ///
-   /// This function overloads \ref operator[]. It returns a reference to
-   /// the character at position \e i in given string.
-   /// The character can not be changed be user.
-   const char& operator[]( int i ) const;
-
-   /// \brief Operator for accessing particular chars of the string.
-   ///
-   /// It returns the character at the position \e i in given string as
-   /// a modifiable reference.
-   char& operator[]( int i );
-
-   /////
-   // Operators for single characters.
-
-   /// \brief This function overloads \ref operator+=.
-   ///
-   /// Appends character \e str to this string.
-   String& operator+=( char str );
-   /// \brief This function concatenates strings and returns a newly constructed string object.
-   String operator+( char str ) const;
-   /// \brief This function checks whether the given string is equal to \e str.
-   ///
-   /// It returns \e true when the given string is equal to \e str. Otherwise returns \e false.
-   bool operator==( char str ) const;
-   /// \brief This function overloads \ref operator!=.
-   bool operator!=( char str ) const;
-
-   /////
-   // Operators for C strings.
-
-   /// \brief This function overloads \ref operator+=.
-   ///
-   /// It appends the C string \e str to this string.
-   String& operator+=( const char* str );
-   /// \brief This function concatenates C strings \e str and returns a newly
-   /// constructed string object.
-   String operator+( const char* str ) const;
-   /// \brief This function overloads \ref operator==.
-   bool operator==( const char* str ) const;
-   /// \brief This function overloads \ref operator!=.
-   bool operator!=( const char* str ) const;
-
-   /////
-   // Operators for std::string.
-
-   /// \brief This function overloads \ref operator+=.
-   ///
-   /// It appends the C string \e str to this string.
-   String& operator+=( const std::string& str );
-   /// \brief This function concatenates C strings \e str and returns a newly
-   /// constructed string object.
-   String operator+( const std::string& str ) const;
-   /// \brief This function overloads \ref operator==.
-   bool operator==( const std::string& str ) const;
-   /// \brief This function overloads \ref operator!=.
-   bool operator!=( const std::string& str ) const;
-
-   /////
-   // Operators for String.
-
-   /// \brief This function overloads \ref operator+=.
-   ///
-   /// It appends the C string \e str to this string.
-   String& operator+=( const String& str );
-   /// \brief This function concatenates C strings \e str and returns a newly
-   /// constructed string object.
-   String operator+( const String& str ) const;
-   /// \brief This function overloads \ref operator==.
-   bool operator==( const String& str ) const;
-   /// \brief This function overloads \ref operator!=.
-   bool operator!=( const String& str ) const;
-
-   /// \brief Cast to bool operator.
-   ///
-   /// This operator converts string to boolean expression (true or false).
-   operator bool() const;
-
-   /// \brief Cast to bool with negation operator.
-   ///
-   /// This operator converts string to boolean expression (false or true).
-   bool operator!() const;
-
-   /////
-   /// \brief Replaces portion of string.
-   ///
-   /// Replaces section \e pattern from this string with new piece of string \e replaceWith.
-   /// If parameter \e count is defined, the function makes replacement several times,
-   /// every time when it finds the same pattern in this string.
-   /// @param pattern Section of given string that will be replaced.
-   /// @param replaceWith New piece of string that will be used to replace \e pattern.
-   /// @param count A whole number that specifies how many replacements should be done.
-   String replace( const String& pattern,
-                   const String& replaceWith,
-                   int count = 0 ) const;
-
-   /////
-   /// \brief Trims/strips given string.
-   ///
-   /// Removes all spaces from given string except for single spaces between words.
-   String strip( char strip = ' ' ) const;
-
-   /// \brief Splits string into list of strings with respect to given \e separator.
-   ///
-   /// Splits the string into list of substrings wherever \e separator occurs,
-   /// and returs list of those strings. When \e separator does not appear
-   /// anywhere in the given string, this function returns a single-element list
-   /// containing given sting.
-   /// @param separator Character, which separates substrings in given string.
-   std::vector< String > split( const char separator = ' ', bool skipEmpty = false ) const;
-
-#ifdef HAVE_MPI
-
-   /****
-    * \brief Sends the string to the target MPI process.
-    */
-   void send( int target, int tag = 0, MPI_Comm mpi_comm = MPI_COMM_WORLD );
-
-   /****
-    * \brief Receives a string from the source MPI process.
-    */
-   void receive( int source, int tag = 0, MPI_Comm mpi_comm = MPI_COMM_WORLD );
-
-   //! Broadcast to other nodes in MPI cluster
-   // void MPIBcast( int root, MPI_Comm mpi_comm = MPI_COMM_WORLD );
-#endif
+   public:
+
+      /**
+       * \brief This enum defines how the operation split of string is to be performed.
+       */
+      enum class SplitSkip
+      {
+         NoSkip,    ///< Do not skip empty characters
+         SkipEmpty  ///< Skip empty characters.
+      };
+      
+      /**
+       * \brief Default constructor.
+       *
+       * Constructs an empty string object.
+       */
+      String() = default;
+
+      /**
+       * \brief Default copy constructor.
+       */
+      String( const String& ) = default;
+
+      /**
+       * \brief Default move constructor.
+       */
+      String( String&& ) = default;
+
+      /**
+       * \brief Initialization by \e std::string.
+       */
+      String( const std::string& str ) : std::string( str ) {}
+
+      /**
+       * \brief Default copy assignment operator.
+       */
+      String& operator=( const String& ) = default;
+
+      /**
+       * \brief Default move assignment operator.
+       */
+      String& operator=( String&& ) = default;
+
+      /**
+       * \brief Inherited constructors.
+       */
+      using std::string::string;
+      
+      /**
+       * \brief Inherited assignment operators.
+       */
+      using std::string::operator=;
+
+      /**
+       * \brief Returns type of string: \c "String".
+       */
+      static String getType();
+
+      /**
+       * \brief Returns the number of characters in given string. Equivalent to \ref getSize.
+       */
+      int getLength() const;
+
+      /**
+       * \brief Returns the number of characters in given string.
+       */
+      int getSize() const;
+
+      /**
+       *  \brief Returns size of allocated storage for given string.
+       *
+       * \par Example
+       * \include StringExampleGetAllocatedSize.cpp
+       * \par Output
+       * \include StringExampleGetAllocatedSize.out
+       */
+      int getAllocatedSize() const;
+
+      /**
+       * \brief Reserves space for given \e size.
+       *
+       * Requests to allocate storage space of given \e size to avoid memory reallocation.
+       * It allocates one more byte for the terminating 0.
+       * @param size Number of characters.
+       *
+       * \par Example
+       * \include StringExampleSetSize.cpp
+       * \par Output
+       * \include StringExampleSetSize.out
+       */
+      void setSize( int size );
+
+      /**
+       * \brief Returns pointer to data.
+       *
+       * It returns the content of the given string as a constant pointer to char.
+       */
+      const char* getString() const;
+
+      /**
+       * \brief Operator for accessing particular chars of the string.
+       *
+       * This function overloads \ref operator[]. It returns a reference to
+       * the character at position \e i in given string.
+       * The character can not be changed be user.
+       */
+      const char& operator[]( int i ) const;
+
+      /**
+       *  \brief Operator for accessing particular chars of the string.
+       *
+       * It returns the character at the position \e i in given string as
+       * a modifiable reference.
+       */
+      char& operator[]( int i );
+
+      /**
+       * Operators for single characters.
+       */
+
+      /**
+       * \brief This function overloads \ref operator+=.
+       *
+       * Appends character \e str to this string.
+       */
+      String& operator+=( char str );
+      
+      /**
+       * \brief This function concatenates strings and returns a newly constructed string object.
+       */
+      String operator+( char str ) const;
+      
+      /**
+       * \brief This function checks whether the given string is equal to \e str.
+       *
+       * It returns \e true when the given string is equal to \e str. Otherwise it returns \e false.
+       */
+      bool operator==( char str ) const;
+
+      /**
+       * \brief This function overloads \ref operator!=.
+       * 
+       * It returns \e true when the given string is NOT equal to \e str. Otherwise it returns \e true.
+       */
+      bool operator!=( char str ) const;
+
+      /**
+       * Operators for C strings.
+       */
+
+      /**
+       * \brief This function overloads \ref operator+=.
+       *
+       * It appends the C string \e str to this string.
+       */
+      String& operator+=( const char* str );
+
+      /**
+       * \brief This function concatenates C strings \e str and returns a newly constructed string object.
+       */
+      String operator+( const char* str ) const;
+
+      /**
+       * \brief This function overloads \ref operator==.
+       * 
+       * It returns \e true when the given string is equal to \e str. Otherwise it returns \e false.
+       */
+      bool operator==( const char* str ) const;
+
+      /**
+       * \brief This function overloads \ref operator!=.
+       * 
+       * It returns \e true when the given string is NOT equal to \e str. Otherwise it returns \e true.
+       */
+      bool operator!=( const char* str ) const;
+
+      /**
+       * Operators for std::string.
+       */
+
+      /**
+       * \brief This function overloads \ref operator+=.
+       *
+       * It appends the C string \e str to this string.
+       */
+      String& operator+=( const std::string& str );
+
+      /**
+       * \brief This function concatenates C strings \e str and returns a newly constructed string object.
+       */
+      String operator+( const std::string& str ) const;
+      
+      /**
+       * \brief This function overloads \ref operator==.
+       * 
+       * It returns \e true when the given string is equal to \e str. Otherwise it returns \e false.
+       */
+      bool operator==( const std::string& str ) const;
+
+      /**
+       * \brief This function overloads \ref operator!=.
+       * 
+       * It returns \e true when the given string is NOT equal to \e str. Otherwise it returns \e true.
+       */
+      bool operator!=( const std::string& str ) const;
+
+      /**
+       * Operators for String.
+       */
+
+      /**
+       * \brief This function overloads \ref operator+=.
+       *
+       * It appends the C string \e str to this string.
+       */
+      String& operator+=( const String& str );
+
+      /**
+       * \brief This function concatenates C strings \e str and returns a newly constructed string object.
+       */
+      String operator+( const String& str ) const;
+
+      /**
+       * \brief This function overloads \ref operator==.
+       *
+       * It returns \e true when the given string is equal to \e str. Otherwise it returns \e false.
+       */
+      bool operator==( const String& str ) const;
+
+      /**
+       * \brief This function overloads \ref operator!=.
+       * 
+       * It returns \e true when the given string is NOT equal to \e str. Otherwise it returns \e true.
+       */
+      bool operator!=( const String& str ) const;
+
+      /**
+       *  \brief Cast to bool operator.
+       *
+       * This operator converts string to boolean expression (true or false).
+       * It returns \e true if the string is NOT empty. Otherwise it returns \e false.
+       */
+      operator bool() const;
+
+      /** \brief Cast to bool with negation operator.
+       *
+       * This operator converts string to boolean expression (false or true).
+       * It returns \e true if the string is empty. Otherwise it returns \e false.
+       */
+      bool operator!() const;
+
+      /**
+       * \brief This method replaces part of the string.
+       *
+       * It replaces \e pattern in this string with a string \e replaceWith.
+       * If parameter \e count is defined, the function makes replacement only count occurrences,
+       * of the given pattern. If \e count is zero, all pattern occurrences are replaced.
+       * 
+       * @param pattern to be replaced.
+       * @param replaceWith string the \e pattern will be replaced with.
+       * @param count number of occurrences to be replaced. All occurrences are replaced if \e count is zero..
+       *
+       * \par Example
+       * \include StringExampleReplace.cpp
+       * \par Output
+       * \include StringExampleReplace.out
+       */
+      String replace( const String& pattern,
+                      const String& replaceWith,
+                      int count = 0 ) const;
+
+      /**
+       * \brief Trims/strips this string.
+       *
+       * Removes all 'spaces' from given string except for single 'spaces' between words.
+       * 
+       * @param strip can be used to change the character to be removed.
+       * 
+       * \par Example
+       * \include StringExampleStrip.cpp
+       * \par Output
+       * \include StringExampleStrip.out   
+       */
+      String strip( char strip = ' ' ) const;
+
+      /**
+       *  \brief Splits string into list of strings with respect to given \e separator.
+       *
+       * This method splits the string into sequence of substrings divided by occurrences of \e separator.
+       * It returns the list of those strings via std::vector. When \e separator does not appear
+       * anywhere in the given string, this function returns a single-element list
+       * containing given sting. If \e skipEmpty equals \e SkipEmpty no empty substrings are
+       * inserted into the resulting container.
+       * 
+       * @param separator is a character separating substrings in given string.
+       * @param skipEmpty 
+       * 
+       * \par Example
+       * \include StringExampleSplit.cpp
+       * \par Output
+       * \include StringExampleSplit.out   
+       */
+      std::vector< String > split( const char separator = ' ', SplitSkip skipEmpty = SplitSkip::NoSkip ) const;
 };
 
-/// \brief Returns concatenation of \e string1 and \e string2.
+/**
+ * \brief Returns concatenation of \e string1 and \e string2.
+ */
 String operator+( char string1, const String& string2 );
 
-/// \brief Returns concatenation of \e string1 and \e string2.
+/**
+ * \brief Returns concatenation of \e string1 and \e string2.
+ */
 String operator+( const char* string1, const String& string2 );
 
-/// \brief Returns concatenation of \e string1 and \e string2.
+/**
+ * \brief Returns concatenation of \e string1 and \e string2.
+ */
 String operator+( const std::string& string1, const String& string2 );
 
-/// \brief Performs the string output to a stream
+/**
+ * \brief Writes the string \e str to given \e stream
+ */
 std::ostream& operator<<( std::ostream& stream, const String& str );
 
+/**
+ * \brief Converts \e value of type \e T to a String.
+ * 
+ * \tparam T can be any type fir which operator << is defined. 
+ */
 template< typename T >
 String convertToString( const T& value )
 {
@@ -251,12 +386,44 @@ String convertToString( const T& value )
    return String( str.str().data() );
 }
 
+/**
+ * \brief Specialization of function \ref convertToString for boolean.
+ * 
+ * The boolean type is converted to 'true' ot 'false'.
+ */
 template<> inline String convertToString( const bool& b )
 {
    if( b ) return "true";
    return "false";
 }
 
+#ifdef HAVE_MPI
+
+/**
+ * \brief Sends the string to the target MPI process.
+ * 
+ * @param str string to be sent
+ * @param target target MPI process ID
+ * @param tag MPI tag
+ * @param mpi_comm MPI communication group
+ */
+void mpiSend( const String& str, int target, int tag = 0, MPI_Comm mpi_comm = MPI_COMM_WORLD );
+
+/**
+ * \brief Receives a string from the target MPI process.
+ * 
+ * @param str says where the received string is to be saved to
+ * @param source source MPI process ID
+ * @param tag MPI tag
+ * @param mpi_comm MPI communication group
+ */
+void mpiReceive( String& str, int source, int tag = 0, MPI_Comm mpi_comm = MPI_COMM_WORLD );
+
+//! Broadcast to other nodes in MPI cluster
+// void MPIBcast( String& str, int root, MPI_Comm mpi_comm = MPI_COMM_WORLD );
+
+#endif
+
 } // namespace TNL
 
-#include <TNL/String_impl.h>
+#include <TNL/String.hpp>
diff --git a/src/TNL/String_impl.h b/src/TNL/String.hpp
similarity index 90%
rename from src/TNL/String_impl.h
rename to src/TNL/String.hpp
index 3c5aa253a083a43c6d7a2936dea09c3474406797..4cdeee7aceb62e93b27a91655938df494c9e3666 100644
--- a/src/TNL/String_impl.h
+++ b/src/TNL/String.hpp
@@ -50,7 +50,6 @@ inline const char* String::getString() const
    return this->c_str();
 }
 
-
 inline const char& String::operator[]( int i ) const
 {
    TNL_ASSERT( i >= 0 && i < getLength(),
@@ -65,7 +64,6 @@ inline char& String::operator[]( int i )
    return std::string::operator[]( i );
 }
 
-
 /****
  * Operators for single characters
  */
@@ -90,7 +88,6 @@ inline bool String::operator!=( char str ) const
    return ! operator==( str );
 }
 
-
 /****
  * Operators for C strings
  */
@@ -115,7 +112,6 @@ inline bool String::operator!=( const char* str ) const
    return ! operator==( str );
 }
 
-
 /****
  * Operators for std::string
  */
@@ -140,7 +136,6 @@ inline bool String::operator!=( const std::string& str ) const
    return ! operator==( str );
 }
 
-
 /****
  * Operators for String
  */
@@ -216,44 +211,64 @@ String::strip( char strip ) const
 }
 
 inline std::vector< String >
-String::split( const char separator, bool skipEmpty ) const
+String::split( const char separator, SplitSkip skip ) const
 {
    std::vector< String > parts;
    String s;
    for( int i = 0; i < this->getLength(); i++ ) {
       if( ( *this )[ i ] == separator ) {
-         if( ! skipEmpty || s != "" )
+         if( skip != SplitSkip::SkipEmpty || s != "" )
             parts.push_back( s );
          s = "";
       }
       else s += ( *this )[ i ];
    }
-   if( ! skipEmpty || s != "" )
+   if( skip != SplitSkip::SkipEmpty || s != "" )
       parts.push_back( s );
    return parts;
 }
 
+inline String operator+( char string1, const String& string2 )
+{
+   return convertToString( string1 ) + string2;
+}
+
+inline String operator+( const char* string1, const String& string2 )
+{
+   return String( string1 ) + string2;
+}
+
+inline String operator+( const std::string& string1, const String& string2 )
+{
+   return String( string1 ) + string2;
+}
+
+inline std::ostream& operator<<( std::ostream& stream, const String& str )
+{
+   stream << str.getString();
+   return stream;
+}
+
 #ifdef HAVE_MPI
-inline void String::send( int target, int tag, MPI_Comm mpi_comm )
+inline void mpiSend( const String& str, int target, int tag, MPI_Comm mpi_comm )
 {
-   int size = this->getSize();
+   int size = str.getSize();
    MPI_Send( &size, 1, MPI_INT, target, tag, mpi_comm );
-   MPI_Send( this->getString(), this->length(), MPI_CHAR, target, tag, mpi_comm );
+   MPI_Send( const_cast< void* >( ( const void* ) str.getString() ), str.length(), MPI_CHAR, target, tag, mpi_comm );
 }
 
-inline void String::receive( int source, int tag, MPI_Comm mpi_comm )
+inline void mpiReceive( String& str, int source, int tag, MPI_Comm mpi_comm )
 {
    int size;
    MPI_Status status;
    MPI_Recv( &size, 1, MPI_INT, source, tag, mpi_comm, &status );
-   this->setSize( size );
-   MPI_Recv( const_cast< void* >( ( const void* ) this->data() ), size, MPI_CHAR, source, tag, mpi_comm,  &status );
+   str.setSize( size );
+   MPI_Recv( const_cast< void* >( ( const void* ) str.data() ), size, MPI_CHAR, source, tag, mpi_comm,  &status );
 }
 
 /*
 inline void String :: MPIBcast( int root, MPI_Comm comm )
 {
-#ifdef USE_MPI
    int iproc;
    MPI_Comm_rank( MPI_COMM_WORLD, &iproc );
    TNL_ASSERT( string, );
@@ -270,30 +285,9 @@ inline void String :: MPIBcast( int root, MPI_Comm comm )
    }
  
    MPI_Bcast( string, len + 1, MPI_CHAR, root, comm );
-#endif
 }
 */
 #endif
 
-inline String operator+( char string1, const String& string2 )
-{
-   return convertToString( string1 ) + string2;
-}
-
-inline String operator+( const char* string1, const String& string2 )
-{
-   return String( string1 ) + string2;
-}
-
-inline String operator+( const std::string& string1, const String& string2 )
-{
-   return String( string1 ) + string2;
-}
-
-inline std::ostream& operator<<( std::ostream& stream, const String& str )
-{
-   stream << str.getString();
-   return stream;
-}
 
 } // namespace TNL
diff --git a/src/TNL/Timer.h b/src/TNL/Timer.h
index 486f09f38e84ecfc3829c2dfd6b5428af5995460..2c697a04e95b81d07f4a12871f19344e16688617 100644
--- a/src/TNL/Timer.h
+++ b/src/TNL/Timer.h
@@ -16,78 +16,92 @@ namespace TNL {
 
 class Logger;
 
-/// \brief Class for time measuring.
-///
-/// Counts the elapsed time in seconds between the \ref start and \ref stop methods.
-/// \par Example
-/// \include TimerExample.cpp
-// \par Output
-// \include TimerExample.out
+/**
+ * \brief Class for real time, CPU time and CPU cycles measuring.
+ *
+ * It measures the elapsed real time, CPU time (in seconds) and CPU cycles
+ * elapsed on the timer. The timer can be paused by calling \ref stop and \ref
+ * start methods and reseted by calling \ref reset.
+ *
+ * \par Example
+ * \include TimerExample.cpp
+ * \par Output
+ * \include TimerExample.out
+ */
 class Timer
 {
    public:
 
-      /////
-      /// \brief Basic constructor.
-      ///
-      /// This function creates a new timer and resets it.
+      /**
+       * \brief Basic constructor.
+       *
+       * This function creates a new timer and resets it.
+       */
       Timer();
 
-      /////
-      /// \brief Resets timer.
-      ///
-      /// Resets all time and cycle measurements such as real time, CPU time and CPU cycles.
-      /// Sets all of them to zero.
+      /**
+       * \brief Resets timer.
+       *
+       * Resets all time and cycle measurements such as real time, CPU time and 
+       * CPU cycles. Sets all of them to zero.
+       */
       void reset();
 
-      ////
-      /// \brief Stops (pauses) the timer.
-      ///
-      /// Pauses all time and cycle measurements such as real time, CPU time and
-      /// CPU cycles, but does not set them to zero.
+      /**
+       * \brief Stops (pauses) the timer.
+       *
+       * Pauses all time and cycle measurements such as real time, CPU time and
+       * CPU cycles, but does not set them to zero.
+       */
       void stop();
 
-      /////
-      /// \brief Starts timer.
-      ///
-      /// Starts all time and cycle measurements such as real time, CPU time and
-      /// CPU cycles. This method can be used also after using the \ref stop method.
-      /// The timer then continues measuring the time without reseting.
+      /**
+       * \brief Starts timer.
+       *
+       * Starts all time and cycle measurements such as real time, CPU time and
+       * CPU cycles. This method can be used also after using the \ref stop
+       * method. The timer then continues measuring the time without reseting.
+       */
       void start();
 
-      /////
-      /// \brief Returns the elapsed time on given timer.
-      ///
-      /// It returns the elapsed time (in seconds) between calling the \ref start and \ref stop methods.
-      /// Starts counting the real time after the method \ref start is called and
-      /// pauses when the method \ref stop is called.
-      /// If the timer has been started more then once without resetting,
-      /// the real time is counted by adding all intervals (between \ref start and \ref stop
-      /// methods) together.
-      /// This function can be called while the timer is running, there is no
-      /// need to use \ref stop method first.
+      /**
+       * \brief Returns the elapsed real time on this timer.
+       *
+       * This method returns the real time elapsed so far (in seconds).
+       * This method can be called while the timer is running, there is no
+       * need to use \ref stop method first.
+       */
       double getRealTime() const;
 
-      /////
-      /// \brief Returns the elapsed CPU time on given timer.
-      ///
-      /// The CPU time is measured in seconds.
-      /// CPU time is the amount of time for which a central processing unit (CPU)
-      /// was used for processing instructions of a computer program or operating system.
-      /// The CPU time is measured by adding the amount of CPU time between \ref start and \ref stop
-      /// methods together.
+      /**
+       * \brief Returns the elapsed CPU time on this timer.
+       *
+       * This method returns the CPU time (i.e. time the CPU spent by processing
+       * this process) elapsed so far (in seconds). This method can be called
+       * while the timer is running, there is no need to use \ref stop method
+       * first.
+       */
       double getCPUTime() const;
 
-      /// \brief Returns the number of CPU cycles (machine cycles).
-      ///
-      /// CPU cycles are counted by adding the number of CPU cycles between \ref start and \ref stop
-      /// methods together.
+      /**
+       * \brief Returns the number of CPU cycles (machine cycles) elapsed on this timer.
+       *
+       * CPU cycles are counted by adding the number of CPU cycles between
+       * \ref start and \ref stop methods together.
+       */
       unsigned long long int getCPUCycles() const;
 
-      /// \brief Writes a record into the \e logger.
-      ///
-      /// \param logger Name of Logger object.
-      /// \param logLevel A non-negative integer recording the log record indent.
+      /**
+       * \brief Writes a record into the \e logger.
+       *
+       * \param logger Name of Logger object.
+       * \param logLevel A non-negative integer recording the log record indent.
+       * 
+       * \par Example
+       * \include TimerExampleLogger.cpp
+       * \par Output
+       * \include TimerExampleLogger.out
+       */
       bool writeLog( Logger& logger, int logLevel = 0 ) const;
 
    protected:
@@ -95,43 +109,44 @@ class Timer
       using TimePoint = typename std::chrono::high_resolution_clock::time_point;
       using Duration = typename std::chrono::high_resolution_clock::duration;
 
-      /// \brief Function for measuring the real time.
+      /**
+       * \brief Function for measuring the real time.
+       */
       TimePoint readRealTime() const;
 
-      /// \brief Function for measuring the CPU time.
-      ///
-      /// CPU time is the amount of time for which a central processing unit (CPU)
-      /// was used for processing instructions of a computer program or operating system.
+      /**
+       * \brief Function for measuring the CPU time.
+       */
       double readCPUTime() const;
 
-      /// \brief Function for counting the number of CPU cycles (machine cycles).
+      /**
+       * \brief Function for counting the number of CPU cycles (machine cycles).
+       */
       unsigned long long int readCPUCycles() const;
 
+      /**
+       * \brief Converts the real time into seconds as a floating point number.
+       */
       double durationToDouble( const Duration& duration ) const;
 
-   TimePoint initialRealTime;
-   Duration totalRealTime;
+      /**
+       * \brief Time Stamp Counter returning number of CPU cycles since reset.
+       *
+       * Only for x86 compatible CPUs.
+       */
+      inline unsigned long long rdtsc() const;
 
-   double initialCPUTime, totalCPUTime;
+      TimePoint initialRealTime;
 
-   unsigned long long int initialCPUCycles, totalCPUCycles;
+      Duration totalRealTime;
 
-   /// \brief Saves information about the state of given timer.
-   ///
-   /// Knows whether the timer is currently stopped or it is running.
-   bool stopState;
+      double initialCPUTime, totalCPUTime;
 
-   /// \brief Time Stamp Counter returning number of CPU cycles since reset.
-   ///
-   /// Only for x86 compatibile CPUs.
-   inline unsigned long long rdtsc() const
-   {
-     unsigned hi, lo;
-     __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
-     return ( ( unsigned long long ) lo ) | ( ( ( unsigned long long ) hi ) << 32 );
-   }
+      unsigned long long int initialCPUCycles, totalCPUCycles;
+
+      bool stopState;
 };
 
 } // namespace TNL
 
-#include <TNL/Timer_impl.h>
+#include <TNL/Timer.hpp>
diff --git a/src/TNL/Timer_impl.h b/src/TNL/Timer.hpp
similarity index 93%
rename from src/TNL/Timer_impl.h
rename to src/TNL/Timer.hpp
index 5a1cec336efcb1b226949064a62a9f573eb1ee61..b4a4fa63996a5a9a867fb773d67183659e9efe6c 100644
--- a/src/TNL/Timer_impl.h
+++ b/src/TNL/Timer.hpp
@@ -78,6 +78,14 @@ inline unsigned long long int Timer::getCPUCycles() const
    return this->totalCPUCycles;
 }
 
+inline bool Timer::writeLog( Logger& logger, int logLevel ) const
+{
+   logger.writeParameter< double                 >( "Real time:",  this->getRealTime(),  logLevel );
+   logger.writeParameter< double                 >( "CPU time:",   this->getCPUTime(),   logLevel );
+   logger.writeParameter< unsigned long long int >( "CPU Cycles:", this->getCPUCycles(), logLevel );
+   return true;
+}
+
 inline typename Timer::TimePoint Timer::readRealTime() const
 {
    return std::chrono::high_resolution_clock::now();
@@ -105,13 +113,11 @@ inline double Timer::durationToDouble( const Duration& duration ) const
    return dur.count();
 }
 
-
-inline bool Timer::writeLog( Logger& logger, int logLevel ) const
+inline unsigned long long Timer::rdtsc() const
 {
-   logger.writeParameter< double                 >( "Real time:",  this->getRealTime(),  logLevel );
-   logger.writeParameter< double                 >( "CPU time:",   this->getCPUTime(),   logLevel );
-   logger.writeParameter< unsigned long long int >( "CPU Cycles:", this->getCPUCycles(), logLevel );
-   return true;
+  unsigned hi, lo;
+  __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
+  return ( ( unsigned long long ) lo ) | ( ( ( unsigned long long ) hi ) << 32 );
 }
 
 } // namespace TNL
diff --git a/src/Tools/tnl-diff.cpp b/src/Tools/tnl-diff.cpp
index b35dba1726d34d729906b6c0cc4d3a5f753da06f..1d681a6df133001011cf01c7bc0ba8a4ea671859 100644
--- a/src/Tools/tnl-diff.cpp
+++ b/src/Tools/tnl-diff.cpp
@@ -9,6 +9,7 @@
 /* See Copyright Notice in tnl/Copyright */
 
 #include "tnl-diff.h"
+#include <TNL/Exceptions/ObjectTypeDetectionFailure.h>
 #include <TNL/Meshes/DummyMesh.h>
 #include <TNL/Meshes/Grid.h>
 
@@ -50,10 +51,13 @@ int main( int argc, char* argv[] )
       return EXIT_SUCCESS;
    }*/
    String meshType;
-   if( ! getObjectType( meshFile, meshType ) )
+   try
    {
-      std::cerr << "I am not able to detect the mesh type from the file " << meshFile << "." << std::endl;
-      return EXIT_FAILURE;
+      meshType = getObjectType( meshFile );
+   }
+   catch(...)
+   {
+      throw Exceptions::ObjectTypeDetectionFailure( meshFile, "mesh" );
    }
    std::cout << meshType << " detected in " << meshFile << " file." << std::endl;
    const std::vector< String > parsedMeshType = parseObjectType( meshType );
diff --git a/src/Tools/tnl-diff.h b/src/Tools/tnl-diff.h
index 0f90bc28aa400c22aeda2ec8eabbb3e99e07fbab..5443f953ac1163b649d5b4afa4cf12121183e709 100644
--- a/src/Tools/tnl-diff.h
+++ b/src/Tools/tnl-diff.h
@@ -227,8 +227,12 @@ bool computeDifferenceOfMeshFunctions( const MeshPointer& meshPointer, const Con
          }
          if( verbose )
            std::cout << "Processing files " << inputFiles[ i ] << " and " << inputFiles[ i + 1 ] << "...           \r" << std::flush;
-         if( ! v1.load( inputFiles[ i ] ) ||
-             ! v2.load( inputFiles[ i + 1 ] ) )
+         try
+         {
+            v1.load( inputFiles[ i ] );
+            v2.load( inputFiles[ i + 1 ] );
+         }
+         catch(...)
          {
             std::cerr << "Unable to read the files " << inputFiles[ i ] << " and " << inputFiles[ i + 1 ] << "." << std::endl;
             outputFile.close();
@@ -246,22 +250,12 @@ bool computeDifferenceOfMeshFunctions( const MeshPointer& meshPointer, const Con
          {
             if( verbose )
               std::cout << "Reading the file " << inputFiles[ 0 ] << "...               \r" << std::flush;
-            if( ! v1.load( inputFiles[ 0 ] ) )
-            {
-               std::cerr << "Unable to read the file " << inputFiles[ 0 ] << std::endl;
-               outputFile.close();
-               return false;
-            }
+            v1.load( inputFiles[ 0 ] );
             file1 = inputFiles[ 0 ];
          }
          if( verbose )
            std::cout << "Processing the files " << inputFiles[ 0 ] << " and " << inputFiles[ i ] << "...             \r" << std::flush;
-         if( ! v2.load( inputFiles[ i ] ) )
-         {
-            std::cerr << "Unable to read the file " << inputFiles[ 1 ] << std::endl;
-            outputFile.close();
-            return false;
-         }
+         v2.load( inputFiles[ i ] );
          if( ! exactMatch )
             outputFile << std::setw( 6 ) << ( i - 1 ) * snapshotPeriod << " ";
          file2 = inputFiles[ i ];
@@ -273,13 +267,8 @@ bool computeDifferenceOfMeshFunctions( const MeshPointer& meshPointer, const Con
             i = half;
          if( verbose )
            std::cout << "Processing files " << inputFiles[ i - half ] << " and " << inputFiles[ i ] << "...                 \r" << std::flush;
-         if( ! v1.load( inputFiles[ i - half ] ) ||
-             ! v2.load( inputFiles[ i ] ) )
-         {
-            std::cerr << "Unable to read the files " << inputFiles[ i - half ] << " and " << inputFiles[ i ] << "." << std::endl;
-            outputFile.close();
-            return false;
-         }
+         v1.load( inputFiles[ i - half ] );
+         v2.load( inputFiles[ i ] );
          //if( snapshotPeriod != 0.0 )
          if( ! exactMatch )
             outputFile << std::setw( 6 ) << ( i - half ) * snapshotPeriod << " ";
@@ -315,10 +304,7 @@ bool computeDifferenceOfMeshFunctions( const MeshPointer& meshPointer, const Con
 
          if( writeDifference )
          {
-            String differenceFileName;
-            differenceFileName = inputFiles[ i ];
-            removeFileExtension( differenceFileName );
-            differenceFileName += ".diff.tnl";
+            String differenceFileName = removeFileNameExtension( inputFiles[ i ] ) + ".diff.tnl";
             //diff.setLike( v1 );
             diff = v1;
             diff -= v2;
@@ -377,13 +363,8 @@ bool computeDifferenceOfVectors( const MeshPointer& meshPointer, const Config::P
          }
          if( verbose )
            std::cout << "Processing files " << inputFiles[ i ] << " and " << inputFiles[ i + 1 ] << "...           \r" << std::flush;
-         if( ! v1.load( inputFiles[ i ] ) ||
-             ! v2.load( inputFiles[ i + 1 ] ) )
-         {
-            std::cerr << "Unable to read the files " << inputFiles[ i ] << " and " << inputFiles[ i + 1 ] << "." << std::endl;
-            outputFile.close();
-            return false;
-         }
+         v1.load( inputFiles[ i ] );
+         v2.load( inputFiles[ i + 1 ] );
          outputFile << std::setw( 6 ) << i/2 * snapshotPeriod << " ";
          i++;
       }
@@ -393,21 +374,11 @@ bool computeDifferenceOfVectors( const MeshPointer& meshPointer, const Config::P
          {
             if( verbose )
               std::cout << "Reading the file " << inputFiles[ 0 ] << "...               \r" << std::flush;
-            if( ! v1.load( inputFiles[ 0 ] ) )
-            {
-               std::cerr << "Unable to read the file " << inputFiles[ 0 ] << std::endl;
-               outputFile.close();
-               return false;
-            }
+            v1.load( inputFiles[ 0 ] );
          }
          if( verbose )
            std::cout << "Processing the files " << inputFiles[ 0 ] << " and " << inputFiles[ i ] << "...             \r" << std::flush;
-         if( ! v2.load( inputFiles[ i ] ) )
-         {
-            std::cerr << "Unable to read the file " << inputFiles[ 1 ] << std::endl;
-            outputFile.close();
-            return false;
-         }
+         v2.load( inputFiles[ i ] );
          outputFile << std::setw( 6 ) << ( i - 1 ) * snapshotPeriod << " ";
       }
       if( mode == "halves" )
@@ -417,13 +388,8 @@ bool computeDifferenceOfVectors( const MeshPointer& meshPointer, const Config::P
             i = half;
          if( verbose )
            std::cout << "Processing files " << inputFiles[ i - half ] << " and " << inputFiles[ i ] << "...                 \r" << std::flush;
-         if( ! v1.load( inputFiles[ i - half ] ) ||
-             ! v2.load( inputFiles[ i ] ) )
-         {
-            std::cerr << "Unable to read the files " << inputFiles[ i - half ] << " and " << inputFiles[ i ] << "." << std::endl;
-            outputFile.close();
-            return false;
-         }
+         v1.load( inputFiles[ i - half ] );
+         v2.load( inputFiles[ i ] );
          //if( snapshotPeriod != 0.0 )
          outputFile << std::setw( 6 ) << ( i - half ) * snapshotPeriod << " ";
       }
@@ -450,10 +416,7 @@ bool computeDifferenceOfVectors( const MeshPointer& meshPointer, const Config::P
 
       if( writeDifference )
       {
-         String differenceFileName;
-         differenceFileName = inputFiles[ i ];
-         removeFileExtension( differenceFileName );
-         differenceFileName += ".diff.tnl";
+         String differenceFileName = removeFileNameExtension( inputFiles[ i ] ) + ".diff.tnl";
          Containers::Vector< Real, Devices::Host, Index > diff;
          diff.setLike( v1 );
          diff = v1;
@@ -471,11 +434,9 @@ bool computeDifferenceOfVectors( const MeshPointer& meshPointer, const Config::P
 template< typename MeshPointer, typename Value, typename Real, typename Index >
 bool computeDifference( const MeshPointer& meshPointer, const String& objectType, const Config::ParameterContainer& parameters )
 {
-   if( objectType == "Functions::MeshFunction" ||
-       objectType == "tnlMeshFunction" )  // TODO: remove deprecated type name
+   if( objectType == "Functions::MeshFunction" )
       return computeDifferenceOfMeshFunctions< MeshPointer, Value, Real, Index >( meshPointer, parameters );
-   if( objectType == "Containers::Vector" ||
-       objectType == "tnlVector" || objectType == "tnlSharedVector" )   // TODO: remove deprecated type name
+   if( objectType == "Containers::Vector" )
       return computeDifferenceOfVectors< MeshPointer, Value, Real, Index >( meshPointer, parameters );
    std::cerr << "Unknown object type " << objectType << "." << std::endl;
    return false;
@@ -489,19 +450,12 @@ bool setIndexType( const MeshPointer& meshPointer,
                    const Config::ParameterContainer& parameters )
 {
    String indexType;
-   if( parsedObjectType[ 0 ] == "Containers::MultiVector" ||
-       parsedObjectType[ 0 ] == "tnlMultiVector" ||                       // TODO: remove deprecated type names
-       parsedObjectType[ 0 ] == "tnlSharedMultiVector"   )                //
-      indexType = parsedObjectType[ 4 ];
-   if( parsedObjectType[ 0 ] == "Containers::Vector" ||
-       parsedObjectType[ 0 ] == "tnlSharedVector" ||                     // TODO: remove deprecated type names
-       parsedObjectType[ 0 ] == "tnlVector" )                            //
+   if( parsedObjectType[ 0 ] == "Containers::Vector" )
       indexType = parsedObjectType[ 3 ];
 
-   if( parsedObjectType[ 0 ] == "Functions::MeshFunction" ||
-       parsedObjectType[ 0 ] == "tnlMeshFunction" )                      // TODO: remove deprecated type names
+   if( parsedObjectType[ 0 ] == "Functions::MeshFunction" )
       return computeDifference< MeshPointer, Value, Real, typename MeshPointer::ObjectType::IndexType >( meshPointer, parsedObjectType[ 0 ], parameters );
-   
+
    if( indexType == "int" )
       return computeDifference< MeshPointer, Value, Real, int >( meshPointer, parsedObjectType[ 0 ], parameters );
    if( indexType == "long-int" )
@@ -569,16 +523,9 @@ bool setValueType( const MeshPointer& meshPointer,
 {
    String elementType;
 
-   if( parsedObjectType[ 0 ] == "Containers::MultiVector" ||
-       parsedObjectType[ 0 ] == "tnlMultiVector" ||                         // TODO: remove deprecated type names
-       parsedObjectType[ 0 ] == "tnlSharedMultiVector" )                    //
-      elementType = parsedObjectType[ 2 ];
-   if( parsedObjectType[ 0 ] == "Functions::MeshFunction" ||
-       parsedObjectType[ 0 ] == "tnlMeshFunction" )                         // TODO: remove deprecated type names
+   if( parsedObjectType[ 0 ] == "Functions::MeshFunction" )
       elementType = parsedObjectType[ 3 ];
-   if( parsedObjectType[ 0 ] == "Containers::Vector" ||
-       parsedObjectType[ 0 ] == "tnlSharedVector" ||                        // TODO: remove deprecated type names
-       parsedObjectType[ 0 ] == "tnlVector" )                               //
+   if( parsedObjectType[ 0 ] == "Containers::Vector" )
       elementType = parsedObjectType[ 1 ];
 
 
@@ -616,16 +563,22 @@ bool processFiles( const Config::ParameterContainer& parameters )
 
    MeshPointer meshPointer;
    if( meshFile != "" )
-      if( ! meshPointer->load( meshFile ) )
+   {
+      try
+      {
+         meshPointer->load( meshFile );
+      }
+      catch(...)
       {
          std::cerr << "I am not able to load mesh from the file " << meshFile << "." << std::endl;
          return false;
       }
+   }
 
    String objectType;
    try
    {
-      getObjectType( inputFiles[ 0 ], objectType );
+      objectType = getObjectType( inputFiles[ 0 ] );
    }
    catch( std::ios_base::failure exception )
    {
diff --git a/src/Tools/tnl-grid-setup.h b/src/Tools/tnl-grid-setup.h
index 48da6a16dc16695c7eef8aa2d212a0a30ac17ba5..896d3abb971571abcededb8bed75dcd9cb0f1fff 100644
--- a/src/Tools/tnl-grid-setup.h
+++ b/src/Tools/tnl-grid-setup.h
@@ -36,7 +36,11 @@ bool setupGrid( const Config::ParameterContainer& parameters )
       grid.setDimensions( CoordinatesType( sizeX ) );
       std::cout << "Setting dimensions to  ... " << sizeX << std::endl;
       std::cout << "Writing the grid to the file " << outputFile << " .... ";      
-      if( ! grid.save( outputFile ) )
+      try
+      {
+         grid.save( outputFile );
+      }
+      catch(...)
       {
          std::cerr << "[ FAILED ] " << std::endl;
          return false;
@@ -70,7 +74,11 @@ bool setupGrid( const Config::ParameterContainer& parameters )
       std::cout << "Setting dimensions to  ... " << grid.getDimensions() << std::endl;
       std::cout << "Writing the grid to the file " << outputFile << " .... ";
 
-      if( ! grid.save( outputFile ) )
+      try
+      {
+         grid.save( outputFile );
+      }
+      catch(...)
       {
          std::cerr << "[ FAILED ] " << std::endl;
          return false;
@@ -108,7 +116,11 @@ bool setupGrid( const Config::ParameterContainer& parameters )
       std::cout << "Setting dimensions to  ... " << grid.getDimensions() << std::endl;
       std::cout << "Writing the grid to the file " << outputFile << " .... ";      
       
-      if( ! grid.save( outputFile ) )
+      try
+      {
+         grid.save( outputFile );
+      }
+      catch(...)
       {
          std::cerr << "[ FAILED ] " << std::endl;
          return false;
diff --git a/src/Tools/tnl-grid-to-mesh.cpp b/src/Tools/tnl-grid-to-mesh.cpp
index 2cd56244676ce70f700775943cfe970105ed95cd..d2d03a29a850c38b8bb940102ae1a1f235d193ab 100644
--- a/src/Tools/tnl-grid-to-mesh.cpp
+++ b/src/Tools/tnl-grid-to-mesh.cpp
@@ -186,7 +186,12 @@ struct GridConverter
          return false;
       }
 
-      if( ! mesh.save( outputFileName ) ) {
+      try
+      {
+         mesh.save( outputFileName );
+      }
+      catch(...)
+      {
          std::cerr << "Failed to save the mesh to file '" << outputFileName << "'." << std::endl;
          return false;
       }
diff --git a/src/Tools/tnl-image-converter.cpp b/src/Tools/tnl-image-converter.cpp
index f06ba841df524c4bd7522b81dc947f8080c0debe..8a7fccf5009f9c101b3f2ad85c983635aa96101d 100644
--- a/src/Tools/tnl-image-converter.cpp
+++ b/src/Tools/tnl-image-converter.cpp
@@ -77,9 +77,7 @@ bool processImages( const Config::ParameterContainer& parameters )
          meshFunction.setMesh( grid );
          if( ! pgmImage.read( roi, meshFunction ) )
             return false;
-         String outputFileName( fileName );
-         removeFileExtension( outputFileName );
-         outputFileName += ".tnl";
+         String outputFileName = removeFileNameExtension( fileName ) + ".tnl";
          std::cout << "Writing image data to " << outputFileName << std::endl;
          meshFunction.save( outputFileName );
          pgmImage.close();
@@ -104,9 +102,7 @@ bool processImages( const Config::ParameterContainer& parameters )
          meshFunction.setMesh( grid );
          if( ! pngImage.read( roi, meshFunction ) )
             return false;
-         String outputFileName( fileName );
-         removeFileExtension( outputFileName );
-         outputFileName += ".tnl";
+         String outputFileName = removeFileNameExtension( fileName ) + ".tnl";
          std::cout << "Writing image data to " << outputFileName << std::endl;
          meshFunction.save( outputFileName );
          pgmImage.close();
@@ -131,9 +127,7 @@ bool processImages( const Config::ParameterContainer& parameters )
          meshFunction.setMesh( grid );
          if( ! jpegImage.read( roi, meshFunction ) )
             return false;
-         String outputFileName( fileName );
-         removeFileExtension( outputFileName );
-         outputFileName += ".tnl";
+         String outputFileName = removeFileNameExtension( fileName ) + ".tnl";
          std::cout << "Writing image data to " << outputFileName << std::endl;
          meshFunction.save( outputFileName );
          pgmImage.close();
@@ -150,7 +144,11 @@ bool processFiles( const Config::ParameterContainer& parameters )
    String meshFile = parameters.getParameter< String >( "mesh-file" );
  
    Meshes::Grid< 2, double, Devices::Host, int > grid;
-   if( ! grid.load( meshFile ) )
+   try
+   {
+      grid.load( meshFile );
+   }
+   catch(...)
    {
       std::cerr << "I am not able to load the mesh file " << meshFile << "." << std::endl;
       return false;
@@ -160,7 +158,11 @@ bool processFiles( const Config::ParameterContainer& parameters )
    {
       const String& fileName = inputFiles[ i ];
       std::cout << "Processing file " << fileName << "... ";
-      if( ! vector.load( fileName ) )
+      try
+      {
+         vector.load( fileName );
+      }
+      catch(...)
       {
          std::cerr << "I am not able to load data from a file " << fileName << "." << std::endl;
          return false;
@@ -168,9 +170,7 @@ bool processFiles( const Config::ParameterContainer& parameters )
       if( imageFormat == "pgm" || imageFormat == "pgm-binary" || imageFormat == "pgm-ascii" )
       {
          Images::PGMImage< int > image;
-         String outputFileName( fileName );
-         removeFileExtension( outputFileName );
-         outputFileName += ".pgm";
+         String outputFileName = removeFileNameExtension( fileName ) + ".pgm";
 	 if ( imageFormat == "pgm" || imageFormat == "pgm-binary")
          	image.openForWrite( outputFileName, grid, true );
 	 if ( imageFormat == "pgm-ascii" )
@@ -182,9 +182,7 @@ bool processFiles( const Config::ParameterContainer& parameters )
       if( imageFormat == "png" )
       {
          Images::PNGImage< int > image;
-         String outputFileName( fileName );
-         removeFileExtension( outputFileName );
-         outputFileName += ".png";
+         String outputFileName = removeFileNameExtension( fileName ) + ".png";
          image.openForWrite( outputFileName, grid );
          image.write( grid, vector );
          image.close();
@@ -192,9 +190,7 @@ bool processFiles( const Config::ParameterContainer& parameters )
       if( imageFormat == "jpg" )
       {
          Images::JPEGImage< int > image;
-         String outputFileName( fileName );
-         removeFileExtension( outputFileName );
-         outputFileName += ".jpg";
+         String outputFileName = removeFileNameExtension( fileName ) + ".jpg";
          image.openForWrite( outputFileName, grid );
          image.write( grid, vector );
          image.close();
diff --git a/src/Tools/tnl-init.cpp b/src/Tools/tnl-init.cpp
index 0695d62e106b6959c852f96c27f7a398025e4202..1bdadb07aef7896e4ff9943f69bcf5ed71d33478 100644
--- a/src/Tools/tnl-init.cpp
+++ b/src/Tools/tnl-init.cpp
@@ -64,7 +64,11 @@ int main( int argc, char* argv[] )
 
    String meshFile = parameters. getParameter< String >( "mesh" );
    String meshType;
-   if( ! getObjectType( meshFile, meshType ) )
+   try
+   {
+      meshType = getObjectType( meshFile );
+   }
+   catch(...)
    {
       std::cerr << "I am not able to detect the mesh type from the file " << meshFile << "." << std::endl;
       return EXIT_FAILURE;
diff --git a/src/Tools/tnl-init.h b/src/Tools/tnl-init.h
index 5530ee5ad5a68107242c01092409d77bee2ac196..a393a7a7cf25523dfbf40034cd5833da5ebb4716 100644
--- a/src/Tools/tnl-init.h
+++ b/src/Tools/tnl-init.h
@@ -47,8 +47,7 @@ bool renderFunction( const Config::ParameterContainer& parameters )
        //suppose global mesh loaded from single file
        String meshFile = parameters.getParameter< String >( "mesh" );
        std::cout << "+ -> Loading mesh from " << meshFile << " ... " << std::endl;
-       if( ! globalMesh.load( meshFile ) )
-          return false;
+       globalMesh.load( meshFile );
    
        // TODO: This should work with no overlaps
        distributedMesh.template setGlobalGrid<CommunicatorType>(globalMesh);
@@ -61,8 +60,7 @@ bool renderFunction( const Config::ParameterContainer& parameters )
     {
        String meshFile = parameters.getParameter< String >( "mesh" );
        std::cout << "+ -> Loading mesh from " << meshFile << " ... " << std::endl;
-       if( ! meshPointer->load( meshFile ) )
-            return false;
+       meshPointer->load( meshFile );
     }
 
    typedef Functions::TestFunction< MeshType::getMeshDimension(), RealType > FunctionType;
@@ -107,7 +105,7 @@ bool renderFunction( const Config::ParameterContainer& parameters )
       if( finalTime > 0.0 )
       {
          String extension = getFileExtension( outputFile );
-         removeFileExtension( outputFile );
+         outputFile = removeFileNameExtension( outputFile );
          outputFile += "-";
          FileName outputFileName;
          outputFileName.setFileNameBase( outputFile.getString() );
@@ -125,10 +123,7 @@ bool renderFunction( const Config::ParameterContainer& parameters )
             return false;
       }
       else
-      {
-        if( ! meshFunction->save( outputFile) )
-         return false;
-      }
+        meshFunction->save( outputFile);
 
       time += tau;
       step ++;
diff --git a/src/Tools/tnl-lattice-init.h b/src/Tools/tnl-lattice-init.h
index 0b42a72ead2ea71758697dbf70190fb15639094c..557bf53594f158016373d1e915bc484a5c16546c 100644
--- a/src/Tools/tnl-lattice-init.h
+++ b/src/Tools/tnl-lattice-init.h
@@ -12,6 +12,7 @@
 
 #include <TNL/Object.h>
 #include <TNL/Config/ParameterContainer.h>
+#include <TNL/Exceptions/ObjectTypeDetectionFailure.h>
 #include <TNL/Meshes/Grid.h>
 #include <TNL/Meshes/GridEntity.h>
 #include <TNL/Functions/MeshFunction.h>
@@ -163,11 +164,7 @@ bool performExtrude( const Config::ParameterContainer& parameters,
             }
          }
    String outputFile = parameters.getParameter< String >( "output-file" );
-   if( ! f.save( outputFile ) )
-   {
-      std::cerr << "Unable to save output file " << outputFile << "." << std::endl;
-      return false;
-   }
+   f.save( outputFile );
    return true;
 }
 
@@ -179,14 +176,22 @@ readProfileMeshFunction( const Config::ParameterContainer& parameters )
    String profileMeshFile = parameters.getParameter< String >( "profile-mesh" );
    using ProfileMeshPointer = Pointers::SharedPointer< typename ProfileMeshFunction::MeshType >;
    ProfileMeshPointer profileMesh;
-   if( ! profileMesh->load( profileMeshFile ) )
+   try
+   {
+      profileMesh->load( profileMeshFile );
+   }
+   catch(...)
    {
       std::cerr << "Unable to load the profile mesh file." << profileMeshFile << "." << std::endl;
       return false;
    }
    String profileFile = parameters.getParameter< String >( "profile-file" );
    ProfileMeshFunction profileMeshFunction( profileMesh );
-   if( ! profileMeshFunction.load( profileFile ) )
+   try
+   {
+      profileMeshFunction.load( profileFile );
+   }
+   catch(...)
    {
       std::cerr << "Unable to load profile mesh function from the file " << profileFile << "." << std::endl;
       return false;
@@ -194,7 +199,11 @@ readProfileMeshFunction( const Config::ParameterContainer& parameters )
    String meshFile = parameters.getParameter< String >( "mesh" );
    using MeshPointer = Pointers::SharedPointer< Mesh >;
    MeshPointer mesh;
-   if( ! mesh->load( meshFile ) )
+   try
+   {
+      mesh->load( meshFile );
+   }
+   catch(...)
    {
       std::cerr << "Unable to load 3D mesh from the file " << meshFile << "." << std::endl;
       return false;
@@ -204,7 +213,11 @@ readProfileMeshFunction( const Config::ParameterContainer& parameters )
    if( parameters.checkParameter( "input-file" ) )
    {
       const String& inputFile = parameters.getParameter< String >( "input-file" ); 
-      if( ! meshFunction.load( inputFile ) )
+      try
+      {
+         meshFunction.load( inputFile );
+      }
+      catch(...)
       {
          std::cerr << "Unable to load " << inputFile << "." << std::endl;
          return false;
@@ -221,10 +234,13 @@ bool resolveProfileReal( const Config::ParameterContainer& parameters )
 {
    String profileFile = parameters. getParameter< String >( "profile-file" );
    String meshFunctionType;
-   if( ! getObjectType( profileFile, meshFunctionType ) )
+   try
    {
-      std::cerr << "I am not able to detect the mesh function type from the profile file " << profileFile << "." << std::endl;
-      return EXIT_FAILURE;
+      meshFunctionType = getObjectType( profileFile );
+   }
+   catch(...)
+   {
+      throw Exceptions::ObjectTypeDetectionFailure( profileFile, "mesh" );
    }
    //std::cout << meshFunctionType << " detected in " << profileFile << " file." << std::endl;
    const std::vector< String > parsedMeshFunctionType = parseObjectType( meshFunctionType );
@@ -277,10 +293,13 @@ bool resolveMesh( const Config::ParameterContainer& parameters )
 {
    String meshFile = parameters.getParameter< String >( "mesh" );
    String meshType;
-   if( ! getObjectType( meshFile, meshType ) )
+   try
    {
-      std::cerr << "I am not able to detect the mesh type from the file " << meshFile << "." << std::endl;
-      return EXIT_FAILURE;
+      meshType = getObjectType( meshFile );
+   }
+   catch(...)
+   {
+      throw Exceptions::ObjectTypeDetectionFailure( meshFile, "mesh" );
    }
    std::cout << meshType << " detected in " << meshFile << " file." << std::endl;
    const std::vector< String > parsedMeshType = parseObjectType( meshType );
@@ -372,10 +391,13 @@ bool resolveProfileMeshType( const Config::ParameterContainer& parameters )
 {
    String meshFile = parameters. getParameter< String >( "profile-mesh" );
    String meshType;
-   if( ! getObjectType( meshFile, meshType ) )
+   try
    {
-      std::cerr << "I am not able to detect the mesh type from the file " << meshFile << "." << std::endl;
-      return EXIT_FAILURE;
+      meshType = getObjectType( meshFile );
+   }
+   catch(...)
+   {
+      throw Exceptions::ObjectTypeDetectionFailure( meshFile, "mesh" );
    }
    std::cout << meshType << " detected in " << meshFile << " file." << std::endl;
    const std::vector< String > parsedMeshType = parseObjectType( meshType );
diff --git a/src/Tools/tnl-mesh-converter.cpp b/src/Tools/tnl-mesh-converter.cpp
index dd7ec0b2049ed7421ff6ec72ad4aeece22ff0e34..cd9de1a597c266722092d1851ac41e2c8dfa7217 100644
--- a/src/Tools/tnl-mesh-converter.cpp
+++ b/src/Tools/tnl-mesh-converter.cpp
@@ -78,8 +78,14 @@ struct MeshConverter
          return false;
       }
 
-      if( outputFormat == "tnl" ) {
-         if( ! mesh.save( outputFileName ) ) {
+      if( outputFormat == "tnl" )
+      {
+         try
+         {
+            mesh.save( outputFileName );
+         }
+         catch(...)
+         {
             std::cerr << "Failed to save the mesh to file '" << outputFileName << "'." << std::endl;
             return false;
          }
diff --git a/src/Tools/tnl-view.h b/src/Tools/tnl-view.h
index e4ae274ae63be5e1dc2cd476917b3d4abd6f55a8..64c09e32bb8263de055f443c60ab1627d4424839 100644
--- a/src/Tools/tnl-view.h
+++ b/src/Tools/tnl-view.h
@@ -16,7 +16,6 @@
 #include <TNL/Config/ParameterContainer.h>
 #include <TNL/String.h>
 #include <TNL/Containers/Vector.h>
-#include <TNL/Containers/MultiVector.h>
 #include <TNL/Meshes/Grid.h>
 #include <TNL/Functions/MeshFunction.h>
 #include <TNL/Functions/VectorField.h>
@@ -30,8 +29,7 @@ bool getOutputFileName( const String& inputFileName,
                         const String& outputFormat,
                         String& outputFileName )
 {
-   outputFileName = inputFileName;
-   removeFileExtension( outputFileName );
+   outputFileName = removeFileNameExtension( inputFileName );
    if( outputFormat == "gnuplot" )
    {
       outputFileName += ".gplt";
@@ -55,7 +53,11 @@ bool writeMeshFunction( const typename MeshFunction::MeshPointer& meshPointer,
 
    MeshFunction function( meshPointer );
    std::cout << "Mesh function: " << function.getType() << std::endl;
-   if( ! function.load( inputFileName ) )
+   try
+   {
+      function.load( inputFileName );
+   }
+   catch(...)
    {
       std::cerr << "Unable to load mesh function from a file " << inputFileName << "." << std::endl;
       return false;
@@ -83,7 +85,11 @@ bool writeVectorField( const typename VectorField::FunctionType::MeshPointer& me
 
    VectorField field( meshPointer );
    std::cout << "VectorField: " << field.getType() << std::endl;
-   if( ! field.load( inputFileName ) )
+   try
+   {
+      field.load( inputFileName );
+   }
+   catch(...)
    {
       std::cerr << "Unable to load vector field from a file " << inputFileName << "." << std::endl;
       return false;
@@ -244,37 +250,16 @@ bool convertObject( const MeshPointer& meshPointer,
      std::cout << " writing to " << outputFileName << " ... " << std::flush;
 
 
-   if( parsedObjectType[ 0 ] == "Containers::Vector" ||
-       parsedObjectType[ 0 ] == "tnlSharedVector" ||   // TODO: remove deprecated type names
-       parsedObjectType[ 0 ] == "tnlVector" )          //
+   if( parsedObjectType[ 0 ] == "Containers::Vector" )
    {
       using MeshType = typename MeshPointer::ObjectType;
       // FIXME: why is MeshType::GlobalIndexType not the same as Index?
 //      Containers::Vector< Value, Devices::Host, Index > vector;
       Containers::Vector< Value, Devices::Host, typename MeshType::GlobalIndexType > vector;
-      if( ! vector.load( inputFileName ) )
-         return false;
+      vector.load( inputFileName );
       Functions::MeshFunction< MeshType, MeshType::getMeshDimension(), Value > mf;
       mf.bind( meshPointer, vector );
-      if( ! mf.write( outputFileName, outputFormat ) )
-         return false;
-   }
-
-   if( parsedObjectType[ 0 ] == "Containers::MultiVector" ||
-       parsedObjectType[ 0 ] == "tnlMultiVector" ||      // TODO: remove deprecated type names  
-       parsedObjectType[ 0 ] == "tnlSharedMultiVector" ) //
-   {
-      Containers::MultiVector< Dimension, Value, Devices::Host, Index > multiVector;
-      if( ! multiVector. load( inputFileName ) )
-         return false;
-      typedef Meshes::Grid< Dimension, Real, Devices::Host, Index > GridType;
-      typedef typename GridType::PointType PointType;
-      typedef typename GridType::CoordinatesType CoordinatesType;
-//      GridType grid;
-//      grid. setDomain( PointType( 0.0 ), PointType( 1.0 ) );
-//      grid. setDimensions( CoordinatesType( multiVector. getDimensions() ) );
-//      if( ! grid. write( multiVector, outputFileName, outputFormat ) )
-         return false;
+      mf.write( outputFileName, outputFormat );
    }
    return true;
 }
@@ -286,13 +271,7 @@ bool setDimension( const MeshPointer& meshPointer,
                     const Config::ParameterContainer& parameters )
 {
    int dimensions( 0 );
-   if( parsedObjectType[ 0 ] == "Containers::MultiVector" ||
-       parsedObjectType[ 0 ] == "tnlMultiVector" ||                     // TODO: remove deprecated type names
-       parsedObjectType[ 0 ] == "tnlSharedMultiVector" )                //
-      dimensions = atoi( parsedObjectType[ 1 ]. getString() );
-   if( parsedObjectType[ 0 ] == "Containers::Vector" ||
-       parsedObjectType[ 0 ] == "tnlVector" ||                          // TODO: remove deprecated type names
-       parsedObjectType[ 0 ] == "tnlSharedVector" )                     //
+   if( parsedObjectType[ 0 ] == "Containers::Vector" )
       dimensions = 1;
    switch( dimensions )
    {
@@ -314,13 +293,7 @@ bool setIndexType( const MeshPointer& meshPointer,
                    const Config::ParameterContainer& parameters )
 {
    String indexType;
-   if( parsedObjectType[ 0 ] == "Containers::MultiVector" ||
-       parsedObjectType[ 0 ] == "tnlMultiVector" ||                        // TODO: remove deprecated type names
-       parsedObjectType[ 0 ] == "tnlSharedMultiVector" )                   //
-      indexType = parsedObjectType[ 4 ];
-   if( parsedObjectType[ 0 ] == "Containers::Vector" || 
-       parsedObjectType[ 0 ] == "tnlSharedVector" ||                       // TODO: remove deprecated type names
-       parsedObjectType[ 0 ] == "tnlVector" )                              //
+   if( parsedObjectType[ 0 ] == "Containers::Vector" )
       indexType = parsedObjectType[ 3 ];
 
    if( indexType == "int" )
@@ -391,13 +364,7 @@ bool setValueType( const MeshPointer& meshPointer,
    String elementType;
 
    // TODO: Fix this even for arrays
-   if( parsedObjectType[ 0 ] == "Containers::MultiVector" ||
-       parsedObjectType[ 0 ] == "tnlMultiVector" ||                            // TODO: remove deprecated type names
-       parsedObjectType[ 0 ] == "tnlSharedMultiVector" )                       //
-      elementType = parsedObjectType[ 2 ];
-   if( parsedObjectType[ 0 ] == "Containers::Vector" ||
-       parsedObjectType[ 0 ] == "tnlSharedVector" ||                           // TODO: remove deprecated type names
-       parsedObjectType[ 0 ] == "tnlVector" )                                  //
+   if( parsedObjectType[ 0 ] == "Containers::Vector" )
       elementType = parsedObjectType[ 1 ];
 
    if( elementType == "float" )
@@ -419,8 +386,7 @@ bool setValueType( const MeshPointer& meshPointer,
       std::cerr << "Unable to parse object type " << elementType << "." << std::endl;
       return false;
    }
-   if( parsedValueType[ 0 ] == "Containers::StaticVector" ||
-       parsedValueType[ 0 ] == "Containers::StaticVector" )               // TODO: remove deprecated type names
+   if( parsedValueType[ 0 ] == "Containers::StaticVector" )
       return setTupleType< MeshPointer >( meshPointer, inputFileName, parsedObjectType, parsedValueType, parameters );
 
    std::cerr << "Unknown element type " << elementType << "." << std::endl;
@@ -473,35 +439,34 @@ struct FilesProcessor
          }
 
          String objectType;
-         if( ! getObjectType( inputFiles[ i ], objectType ) )
-             std::cerr << "unknown object ... SKIPPING!" << std::endl;
-         else
+         try
          {
-            if( verbose )
-              std::cout << objectType << " detected ... ";
-
-            const std::vector< String > parsedObjectType = parseObjectType( objectType );
-            if( ! parsedObjectType.size() )
-            {
-               std::cerr << "Unable to parse object type " << objectType << "." << std::endl;
-               error = true;
-               continue;
-            }
-            if( parsedObjectType[ 0 ] == "Containers::MultiVector" ||
-                parsedObjectType[ 0 ] == "Containers::Vector" ||
-                parsedObjectType[ 0 ] == "tnlMultiVector" ||                     // TODO: remove deprecated type names
-                parsedObjectType[ 0 ] == "tnlSharedMultiVector" ||               // 
-                parsedObjectType[ 0 ] == "tnlSharedVector" ||                    //
-                parsedObjectType[ 0 ] == "tnlVector" )                           //
-               setValueType< MeshPointer >( meshPointer, inputFiles[ i ], parsedObjectType, parameters );
-            if( parsedObjectType[ 0 ] == "Functions::MeshFunction" ||
-                parsedObjectType[ 0 ] == "tnlMeshFunction" )                     // TODO: remove deprecated type names
-               setMeshFunction< MeshPointer >( meshPointer, inputFiles[ i ], parsedObjectType, parameters );
-            if( parsedObjectType[ 0 ] == "Functions::VectorField" )
-               setVectorFieldSize< MeshPointer >( meshPointer, inputFiles[ i ], parsedObjectType, parameters );
-            if( verbose )
-               std::cout << "[ OK ].  " << std::endl;
+            objectType = getObjectType( inputFiles[ i ] );
+         }
+         catch(...)
+         {
+            std::cerr << "unknown object ... SKIPPING!" << std::endl;
+            continue;
          }
+         
+         if( verbose )
+           std::cout << objectType << " detected ... ";
+
+         const std::vector< String > parsedObjectType = parseObjectType( objectType );
+         if( ! parsedObjectType.size() )
+         {
+            std::cerr << "Unable to parse object type " << objectType << "." << std::endl;
+            error = true;
+            continue;
+         }
+         if( parsedObjectType[ 0 ] == "Containers::Vector" )
+            setValueType< MeshPointer >( meshPointer, inputFiles[ i ], parsedObjectType, parameters );
+         if( parsedObjectType[ 0 ] == "Functions::MeshFunction" )
+            setMeshFunction< MeshPointer >( meshPointer, inputFiles[ i ], parsedObjectType, parameters );
+         if( parsedObjectType[ 0 ] == "Functions::VectorField" )
+            setVectorFieldSize< MeshPointer >( meshPointer, inputFiles[ i ], parsedObjectType, parameters );
+         if( verbose )
+            std::cout << "[ OK ].  " << std::endl;
       }
       if( verbose )
         std::cout << std::endl;
diff --git a/src/UnitTests/Containers/ArrayTest.h b/src/UnitTests/Containers/ArrayTest.h
index d2bddbd29640e87f3c8bd3029a5c5e05a5e42cc4..3790b35dc9935e1dba49676b0b0ff1ba0245e82c 100644
--- a/src/UnitTests/Containers/ArrayTest.h
+++ b/src/UnitTests/Containers/ArrayTest.h
@@ -10,7 +10,7 @@
 
 #pragma once
 
-#ifdef HAVE_GTEST 
+#ifdef HAVE_GTEST
 #include <type_traits>
 
 #include <TNL/Containers/Array.h>
@@ -158,7 +158,7 @@ TYPED_TEST( ArrayTest, constructors )
       EXPECT_EQ( w.getData(), data );
 
       ArrayType z1( w );
-      EXPECT_EQ( z1.getData(), data );
+      //EXPECT_EQ( z1.getData(), data );
       EXPECT_EQ( z1.getSize(), 10 );
 
       ArrayType z2( w, 1 );
@@ -169,6 +169,31 @@ TYPED_TEST( ArrayTest, constructors )
       EXPECT_EQ( z3.getData(), data + 2 );
       EXPECT_EQ( z3.getSize(), 3 );
    }
+
+   ArrayType w( v );
+   EXPECT_EQ( w.getSize(), v.getSize() );
+   for( int i = 0; i < 10; i++ )
+      EXPECT_EQ( v.getElement( i ), w.getElement( i ) );
+   v.reset();
+   EXPECT_EQ( w.getSize(), 10 );
+
+   ArrayType a1 { 1, 2, 3 };
+   EXPECT_EQ( a1.getElement( 0 ), 1 );
+   EXPECT_EQ( a1.getElement( 1 ), 2 );
+   EXPECT_EQ( a1.getElement( 2 ), 3 );
+
+   std::list< int > l = { 4, 5, 6 };
+   ArrayType a2( l );
+   EXPECT_EQ( a2.getElement( 0 ), 4 );
+   EXPECT_EQ( a2.getElement( 1 ), 5 );
+   EXPECT_EQ( a2.getElement( 2 ), 6 );
+
+   std::vector< int > q = { 7, 8, 9 };
+
+   ArrayType a3( q );
+   EXPECT_EQ( a3.getElement( 0 ), 7 );
+   EXPECT_EQ( a3.getElement( 1 ), 8 );
+   EXPECT_EQ( a3.getElement( 2 ), 9 );
 }
 
 TYPED_TEST( ArrayTest, setSize )
@@ -184,18 +209,22 @@ TYPED_TEST( ArrayTest, setSize )
 
    ArrayType v( u );
    EXPECT_EQ( v.getSize(), 10 );
-   EXPECT_EQ( v.getData(), u.getData() );
+   //EXPECT_EQ( v.getData(), u.getData() );
    v.setSize( 11 );
    EXPECT_EQ( u.getSize(), 10 );
    EXPECT_EQ( v.getSize(), 11 );
    EXPECT_NE( v.getData(), u.getData() );
 
-   // cast to bool returns true iff size > 0
-   EXPECT_TRUE( (bool) u );
-   EXPECT_FALSE( ! u );
-   u.setSize( 0 );
-   EXPECT_FALSE( (bool) u );
-   EXPECT_TRUE( ! u );
+}
+
+TYPED_TEST( ArrayTest, empty )
+{
+   using ArrayType = typename TestFixture::ArrayType;
+   ArrayType u( 10 );
+
+   EXPECT_FALSE( u.empty() );
+   u.reset();
+   EXPECT_TRUE( u.empty() );
 }
 
 TYPED_TEST( ArrayTest, setLike )
@@ -273,15 +302,19 @@ TYPED_TEST( ArrayTest, reset )
    ArrayType u;
    u.setSize( 100 );
    EXPECT_EQ( u.getSize(), 100 );
+   EXPECT_FALSE( u.empty() );
    EXPECT_NE( u.getData(), nullptr );
    u.reset();
    EXPECT_EQ( u.getSize(), 0 );
+   EXPECT_TRUE( u.empty() );
    EXPECT_EQ( u.getData(), nullptr );
    u.setSize( 100 );
    EXPECT_EQ( u.getSize(), 100 );
+   EXPECT_FALSE( u.empty() );
    EXPECT_NE( u.getData(), nullptr );
    u.reset();
    EXPECT_EQ( u.getSize(), 0 );
+   EXPECT_TRUE( u.empty() );
    EXPECT_EQ( u.getData(), nullptr );
 }
 
@@ -437,7 +470,9 @@ TYPED_TEST( ArrayTest, assignmentOperator )
       u_host.setElement( i, i );
    }
 
-   v.setValue( 0 );
+   v = 72; //.setValue( 0 );
+   for( int i = 0; i < 10; i++ )
+      EXPECT_EQ( v.getElement( i ), 72 );
    v = u;
    EXPECT_EQ( u, v );
 
@@ -450,6 +485,10 @@ TYPED_TEST( ArrayTest, assignmentOperator )
    u_host.setValue( 0 );
    u_host = u;
    EXPECT_EQ( u_host, u );
+
+   u = 5;
+   for( int i = 0; i < 10; i++ )
+      EXPECT_EQ( u.getElement( i ), 5 );
 }
 
 // test works only for arithmetic types
@@ -504,11 +543,11 @@ TYPED_TEST( ArrayTest, SaveAndLoad )
    for( int i = 0; i < 100; i ++ )
       v.setElement( i, 3.14147 );
    File file;
-   file.open( "test-file.tnl", IOMode::write );
-   EXPECT_TRUE( v.save( file ) );
+   file.open( "test-file.tnl", File::Mode::Out );
+   v.save( file );
    file.close();
-   file.open( "test-file.tnl", IOMode::read );
-   EXPECT_TRUE( u.load( file ) );
+   file.open( "test-file.tnl", File::Mode::In );
+   u.load( file );
    EXPECT_EQ( u, v );
 
    EXPECT_EQ( std::remove( "test-file.tnl" ), 0 );
@@ -523,24 +562,33 @@ TYPED_TEST( ArrayTest, boundLoad )
    for( int i = 0; i < 100; i ++ )
       v.setElement( i, 3.14147 );
    File file;
-   file.open( "test-file.tnl", IOMode::write );
-   EXPECT_TRUE( v.save( file ) );
+   file.open( "test-file.tnl", File::Mode::Out );
+   v.save( file );
    file.close();
 
    w.setSize( 100 );
    u.bind( w );
-   file.open( "test-file.tnl", IOMode::read );
-   EXPECT_TRUE( u.boundLoad( file ) );
+   file.open( "test-file.tnl", File::Mode::In );
+   u.boundLoad( file );
    EXPECT_EQ( u, v );
    EXPECT_EQ( u.getData(), w.getData() );
 
    u.setSize( 50 );
-   file.open( "test-file.tnl", IOMode::read );
-   EXPECT_FALSE( u.boundLoad( file ) );
+   file.open( "test-file.tnl", File::Mode::In );
+   bool catched( false );
+   try
+   {
+      u.boundLoad( file );
+   }
+   catch(...)
+   {
+      catched = true;
+   }
+   EXPECT_TRUE( catched  );
 
    u.reset();
-   file.open( "test-file.tnl", IOMode::read );
-   EXPECT_TRUE( u.boundLoad( file ) );
+   file.open( "test-file.tnl", File::Mode::In );
+   u.boundLoad( file );
 
    EXPECT_EQ( std::remove( "test-file.tnl" ), 0 );
 }
@@ -553,8 +601,8 @@ TYPED_TEST( ArrayTest, referenceCountingConstructors )
    ArrayType u( 10 );
    ArrayType v( u );
    ArrayType w( v );
-   EXPECT_EQ( v.getData(), u.getData() );
-   EXPECT_EQ( w.getData(), u.getData() );
+   //EXPECT_EQ( v.getData(), u.getData() );
+   //EXPECT_EQ( w.getData(), u.getData() );
 
    // copies of a static array
    if( std::is_same< typename ArrayType::DeviceType, Devices::Host >::value ) {
@@ -563,8 +611,8 @@ TYPED_TEST( ArrayTest, referenceCountingConstructors )
       ArrayType v( u );
       ArrayType w( v );
       EXPECT_EQ( u.getData(), data );
-      EXPECT_EQ( v.getData(), data );
-      EXPECT_EQ( w.getData(), data );
+      //EXPECT_EQ( v.getData(), data );
+      //EXPECT_EQ( w.getData(), data );
    }
 }
 
diff --git a/src/UnitTests/Containers/ArrayViewTest.h b/src/UnitTests/Containers/ArrayViewTest.h
index 7f3cc7bb338f8178b44fea3275feceabb709dd2f..061a2f5effcf45680c43d6645bdbbc383775bb76 100644
--- a/src/UnitTests/Containers/ArrayViewTest.h
+++ b/src/UnitTests/Containers/ArrayViewTest.h
@@ -149,12 +149,12 @@ TYPED_TEST( ArrayViewTest, constructors )
 {
    using ArrayType = typename TestFixture::ArrayType;
    using ViewType = typename TestFixture::ViewType;
-   using ConstViewType = VectorView< const typename ArrayType::ValueType, typename ArrayType::DeviceType, typename ArrayType::IndexType >;
+   using ConstViewType = typename ViewType::ConstViewType;
 
    ArrayType a( 10 );
    EXPECT_EQ( a.getSize(), 10 );
 
-   ViewType v( a );
+   ViewType v = a.getView();
    EXPECT_EQ( v.getSize(), 10 );
    EXPECT_EQ( v.getData(), a.getData() );
 
@@ -170,10 +170,10 @@ TYPED_TEST( ArrayViewTest, constructors )
 
    // test initialization by const reference
    const ArrayType& b = a;
-   ConstViewType b_view( b );
-   ConstViewType const_a_view( a );
+   ConstViewType b_view = b.getConstView();
+   ConstViewType const_a_view = a.getConstView();
 
-   // test initialization of cons view by non-const view
+   // test initialization of const view by non-const view
    ConstViewType const_b_view( b_view );
 }
 
@@ -221,7 +221,8 @@ TYPED_TEST( ArrayViewTest, swap )
    a.setValue( 0 );
    b.setValue( 1 );
 
-   ViewType u( a ), v( b );
+   ViewType u = a.getView();
+   ViewType v = b.getView();
    u.swap( v );
    EXPECT_EQ( u.getSize(), 20 );
    EXPECT_EQ( v.getSize(), 10 );
@@ -238,7 +239,7 @@ TYPED_TEST( ArrayViewTest, reset )
 
    ArrayType a;
    a.setSize( 100 );
-   ViewType u( a );
+   ViewType u = a.getView();
    EXPECT_EQ( u.getSize(), 100 );
    EXPECT_NE( u.getData(), nullptr );
    u.reset();
@@ -306,6 +307,35 @@ TYPED_TEST( ArrayViewTest, elementwiseAccess )
    testArrayViewElementwiseAccess( ArrayType() );
 }
 
+template< typename ArrayType >
+void ArrayViewEvaluateTest( ArrayType& u )
+{
+   using ValueType = typename ArrayType::ValueType;
+   using DeviceType = typename ArrayType::DeviceType;
+   using IndexType = typename ArrayType::IndexType;
+   using ViewType = ArrayView< ValueType, DeviceType, IndexType >;
+   ViewType v( u );
+
+   auto f = [] __cuda_callable__ ( IndexType i )
+   {
+      return 3 * i % 4;
+   };
+   
+   v.evaluate( f );
+   for( int i = 0; i < 10; i++ )
+   {
+      EXPECT_EQ( u.getElement( i ), 3 * i % 4 );
+      EXPECT_EQ( v.getElement( i ), 3 * i % 4 );
+   }
+}
+
+TYPED_TEST( ArrayViewTest, evaluate )
+{
+   using ArrayType = typename TestFixture::ArrayType;
+   ArrayType u( 10 );
+   ArrayViewEvaluateTest( u );
+}
+
 TYPED_TEST( ArrayViewTest, containsValue )
 {
    using ArrayType = typename TestFixture::ArrayType;
@@ -313,7 +343,7 @@ TYPED_TEST( ArrayViewTest, containsValue )
 
    ArrayType a;
    a.setSize( 1024 );
-   ViewType v( a );
+   ViewType v = a.getView();
 
    for( int i = 0; i < v.getSize(); i++ )
       v.setElement( i, i % 10 );
@@ -332,7 +362,7 @@ TYPED_TEST( ArrayViewTest, containsOnlyValue )
 
    ArrayType a;
    a.setSize( 1024 );
-   ViewType v( a );
+   ViewType v = a.getView();
 
    for( int i = 0; i < v.getSize(); i++ )
       v.setElement( i, i % 10 );
@@ -357,7 +387,9 @@ TYPED_TEST( ArrayViewTest, comparisonOperator )
       b.setElement( i, 2 * i );
    }
 
-   ViewType u( a ), v( a ), w( b );
+   ViewType u = a.getView();
+   ViewType v = a.getView();
+   ViewType w = b.getView();
 
    EXPECT_TRUE( u == u );
    EXPECT_TRUE( u == v );
@@ -406,8 +438,8 @@ TYPED_TEST( ArrayViewTest, comparisonOperatorWithDifferentType )
       b.setElement( i, i );
    }
 
-   ViewType1 u( a );
-   ViewType2 v( b );
+   ViewType1 u = a.getView();
+   ViewType2 v = b.getView();
 
    EXPECT_TRUE( u == v );
    EXPECT_FALSE( u != v );
@@ -431,8 +463,9 @@ TYPED_TEST( ArrayViewTest, assignmentOperator )
       a_host.setElement( i, i );
    }
 
-   ViewType u( a ), v( b );
-   typename ViewType::HostType u_host( a_host );
+   ViewType u = a.getView();
+   ViewType v = b.getView();
+   typename ViewType::HostType u_host = a_host.getView();
 
    v.setValue( 0 );
    v = u;
@@ -472,7 +505,7 @@ void testArrayAssignmentWithDifferentType()
    }
 
    using ViewType = ArrayView< typename ArrayType::ValueType, typename ArrayType::DeviceType, typename ArrayType::IndexType >;
-   ViewType u( a );
+   ViewType u = a.getView();
    typename ViewType::HostType u_host( a_host );
    using ShortViewType = ArrayView< short, typename ArrayType::DeviceType, short >;
    ShortViewType v( b );
diff --git a/src/UnitTests/Containers/CMakeLists.txt b/src/UnitTests/Containers/CMakeLists.txt
index fe75ed458bad9e8e8314a4e351e86dcfc6870bea..99e4d677bc3df482484bb56b87cea9c71c3a6f15 100644
--- a/src/UnitTests/Containers/CMakeLists.txt
+++ b/src/UnitTests/Containers/CMakeLists.txt
@@ -58,16 +58,6 @@ ADD_EXECUTABLE( StaticVectorTest StaticVectorTest.cpp )
 TARGET_COMPILE_OPTIONS( StaticVectorTest PRIVATE ${CXX_TESTS_FLAGS} )
 TARGET_LINK_LIBRARIES( StaticVectorTest ${GTEST_BOTH_LIBRARIES} )
 
-#IF( BUILD_CUDA )
-#   CUDA_ADD_EXECUTABLE( MultiArrayTest MultiArrayTest.cu
-#                        OPTIONS ${CXX_TESTS_FLAGS} )
-#   TARGET_LINK_LIBRARIES( MultiArrayTest ${GTEST_BOTH_LIBRARIES} )
-#ELSE(  BUILD_CUDA )
-#   ADD_EXECUTABLE( MultiArrayTest MultiArrayTest.cpp )
-#   TARGET_COMPILE_OPTIONS( MultiArrayTest PRIVATE ${CXX_TESTS_FLAGS} )
-#   TARGET_LINK_LIBRARIES( MultiArrayTest ${GTEST_BOTH_LIBRARIES} )
-#ENDIF( BUILD_CUDA )
-
 
 ADD_TEST( ListTest ${EXECUTABLE_OUTPUT_PATH}/ListTest${CMAKE_EXECUTABLE_SUFFIX} )
 ADD_TEST( ArrayOperationsTest ${EXECUTABLE_OUTPUT_PATH}/ArrayOperationsTest${CMAKE_EXECUTABLE_SUFFIX} )
@@ -82,7 +72,6 @@ ENDIF()
 ADD_TEST( MultireductionTest ${EXECUTABLE_OUTPUT_PATH}/MultireductionTest${CMAKE_EXECUTABLE_SUFFIX} )
 ADD_TEST( StaticArrayTest ${EXECUTABLE_OUTPUT_PATH}/StaticArrayTest${CMAKE_EXECUTABLE_SUFFIX} )
 ADD_TEST( StaticVectorTest ${EXECUTABLE_OUTPUT_PATH}/StaticVectorTest${CMAKE_EXECUTABLE_SUFFIX} )
-#ADD_TEST( MultiArrayTest ${EXECUTABLE_OUTPUT_PATH}/MultiArrayTest${CMAKE_EXECUTABLE_SUFFIX} )
 
 
 ADD_SUBDIRECTORY( Multimaps )
diff --git a/src/UnitTests/Containers/DistributedArrayTest.h b/src/UnitTests/Containers/DistributedArrayTest.h
index 15ed6214a1d0ef4f74a8fec6dfdf1a24ff31851d..381539af6b72ec44ce6f62497e2b1530d8edc9f9 100644
--- a/src/UnitTests/Containers/DistributedArrayTest.h
+++ b/src/UnitTests/Containers/DistributedArrayTest.h
@@ -88,11 +88,15 @@ TYPED_TEST( DistributedArrayTest, copyFromGlobal )
    using ArrayType = typename TestFixture::ArrayType;
 
    this->distributedArray.setValue( 0.0 );
-   ArrayViewType localArrayView = this->distributedArray.getLocalArrayView();
    ArrayType globalArray( this->globalSize );
    globalArray.setValue( 1.0 );
    this->distributedArray.copyFromGlobal( globalArray );
-   EXPECT_EQ( localArrayView, globalArray );
+
+   ArrayViewType localArrayView = this->distributedArray.getLocalArrayView();
+   auto globalView = globalArray.getConstView();
+   const auto localRange = this->distributedArray.getLocalRange();
+   globalView.bind( &globalArray[ localRange.getBegin() ], localRange.getEnd() - localRange.getBegin() );
+   EXPECT_EQ( localArrayView, globalView );
 }
 
 TYPED_TEST( DistributedArrayTest, setLike )
@@ -188,7 +192,7 @@ TYPED_TEST( DistributedArrayTest, copyConstructor )
    this->distributedArray.setValue( 1 );
    DistributedArrayType copy( this->distributedArray );
    // Array has "binding" copy-constructor
-   EXPECT_EQ( copy.getLocalArrayView().getData(), this->distributedArray.getLocalArrayView().getData() );
+   //EXPECT_EQ( copy.getLocalArrayView().getData(), this->distributedArray.getLocalArrayView().getData() );
 }
 
 TYPED_TEST( DistributedArrayTest, copyAssignment )
diff --git a/src/UnitTests/Containers/MultiArrayTest.cpp b/src/UnitTests/Containers/MultiArrayTest.cpp
deleted file mode 100644
index 18e7453ccf928f288127d2de469f60d63005ca7b..0000000000000000000000000000000000000000
--- a/src/UnitTests/Containers/MultiArrayTest.cpp
+++ /dev/null
@@ -1,11 +0,0 @@
-/***************************************************************************
-                          MultiArrayTest.cpp  -  description
-                             -------------------
-    begin                : Feb 3, 2014
-    copyright            : (C) 2014 by Tomas Oberhuber
-    email                : tomas.oberhuber@fjfi.cvut.cz
- ***************************************************************************/
-
-/* See Copyright Notice in tnl/Copyright */
-
-#include "MultiArrayTest.h"
\ No newline at end of file
diff --git a/src/UnitTests/Containers/MultiArrayTest.cu b/src/UnitTests/Containers/MultiArrayTest.cu
deleted file mode 100644
index 97d7ff312b645d87bbaa230cb355a883678508d1..0000000000000000000000000000000000000000
--- a/src/UnitTests/Containers/MultiArrayTest.cu
+++ /dev/null
@@ -1,11 +0,0 @@
-/***************************************************************************
-                          MultiArrayTest.cu  -  description
-                             -------------------
-    begin                : Feb 3, 2014
-    copyright            : (C) 2014 by Tomas Oberhuber
-    email                : tomas.oberhuber@fjfi.cvut.cz
- ***************************************************************************/
-
-/* See Copyright Notice in tnl/Copyright */
-
-#include "MultiArrayTest.h"
diff --git a/src/UnitTests/Containers/MultiArrayTest.h b/src/UnitTests/Containers/MultiArrayTest.h
deleted file mode 100644
index 66fc9dc08574d717409718c1ab7a97d94828941f..0000000000000000000000000000000000000000
--- a/src/UnitTests/Containers/MultiArrayTest.h
+++ /dev/null
@@ -1,237 +0,0 @@
-/***************************************************************************
-                          MultiArrayTester.h -  description
-                             -------------------
-    begin                : Jul 4, 2012
-    copyright            : (C) 2012 by Tomas Oberhuber
-    email                : tomas.oberhuber@fjfi.cvut.cz
- ***************************************************************************/
-
-/* See Copyright Notice in tnl/Copyright */
-
-#pragma once
-
-#include <TNL/Containers/MultiArray.h>
-
-#ifdef HAVE_GTEST 
-#include "gtest/gtest.h"
-#endif
-
-using namespace TNL;
-using namespace TNL::Containers;
-
-#ifdef HAVE_CUDA
-template< typename ValueType, typename IndexType >
-__global__ void testSetGetElementKernel( MultiArray< 1, ValueType, Devices::Cuda, IndexType >* u )
-{
-   if( threadIdx.x < ( *u ).getDimensions().x() )
-      ( *u )( threadIdx.x ) = threadIdx.x;
-}
-
-template< typename ValueType, typename IndexType >
-__global__ void testSetGetElementKernel( MultiArray< 2, ValueType, Devices::Cuda, IndexType >* u )
-{
-   if( threadIdx.x < ( *u ).getDimensions().x() &&
-       threadIdx.x < ( *u ).getDimensions().y() )
-      ( *u )( threadIdx.x, threadIdx.x ) = threadIdx.x;
-}
-
-template< typename ValueType, typename IndexType >
-__global__ void testSetGetElementKernel( MultiArray< 3, ValueType, Devices::Cuda, IndexType >* u )
-{
-   if( threadIdx.x < ( *u ).getDimensions().x() &&
-       threadIdx.x < ( *u ).getDimensions().y() &&
-       threadIdx.x < ( *u ).getDimensions().z() )
-      ( *u )( threadIdx.x, threadIdx.x, threadIdx.x ) = threadIdx.x;
-}
-
-#endif /* HAVE_CUDA */
-
-#ifdef HAVE_GTEST
-
-TEST( MultiArrayTest, testConstructorDestructor )
-{
-   using namespace TNL::Containers;
-   MultiArray< Dimension, ValueType, Device, IndexType > u;
-}
-
-TEST( MultiArrayTest, testSetSize )
-{
-   using namespace TNL::Containers;
-   MultiArray< Dimension, ValueType, Device, IndexType > u, v;
-   u. setDimensions( 10 );
-   v. setDimensions( 10 );
-}
-
-void setDiagonalElement( Containers::MultiArray< 1, ValueType, Device, IndexType >& u,
-                         const IndexType& i,
-                         const ValueType& v )
-{
-   u.setElement( i, v );
-}
-
-void setDiagonalElement( Containers::MultiArray< 2, ValueType, Device, IndexType >& u,
-                         const IndexType& i,
-                         const ValueType& v )
-{
-   u.setElement( i, i, v );
-}
-
-void setDiagonalElement( Containers::MultiArray< 3, ValueType, Device, IndexType >& u,
-                         const IndexType& i,
-                         const ValueType& v )
-{
-   u.setElement( i, i, i, v );
-}
-
-IndexType getDiagonalElement( Containers::MultiArray< 1, ValueType, Device, IndexType >& u,
-                              const IndexType& i )
-{
-   return u.getElement( i );
-}
-
-IndexType getDiagonalElement( Containers::MultiArray< 2, ValueType, Device, IndexType >& u,
-                              const IndexType& i )
-{
-   return u.getElement( i, i );
-}
-
-IndexType getDiagonalElement( Containers::MultiArray< 3, ValueType, Device, IndexType >& u,
-                              const IndexType& i )
-{
-   return u.getElement( i, i, i );
-}
-
-
-TEST( MultiArrayTest, testSetGetElement )
-{
-   using namespace TNL::Containers;
-   MultiArray< Dimension, ValueType, Device, IndexType > u;
-   u. setDimensions( 10 );
-   if( std::is_same< Device, Devices::Host >::value )
-   {
-      for( int i = 0; i < 10; i ++ )
-         this->setDiagonalElement( u, i, i  );
-   }
-   if( std::is_same< Device, Devices::Cuda >::value )
-   {
-#ifdef HAVE_CUDA
-      MultiArray< Dimension, ValueType, Device, IndexType >* kernel_u =
-               Devices::Cuda::passToDevice( u );
-      testSetGetElementKernel<<< 1, 16 >>>( kernel_u );
-      Devices::Cuda::freeFromDevice( kernel_u );
-      ASSERT_TRUE( TNL_CHECK_CUDA_DEVICE );
-#endif
-   }
-   for( int i = 0; i < 10; i ++ )
-      ASSERT_EQ( getDiagonalElement( u, i ), i );
-};
-
-TEST( MultiArrayTest, testComparisonOperator )
-{
-   using namespace TNL::Containers;
-   MultiArray< Dimension, ValueType, Device, IndexType > u, v, w;
-   u.setDimensions( 10 );
-   v.setDimensions( 10 );
-   w.setDimensions( 10 );
-   u.setValue( 0 );
-   v.setValue( 0 );
-   w.setValue( 0 );
-   for( int i = 0; i < 10; i ++ )
-   {
-      setDiagonalElement( u, i, i );
-      setDiagonalElement( v, i, i );
-      setDiagonalElement( w, i, 2*1 );
-   }
-   ASSERT_TRUE( u == v );
-   ASSERT_FALSE( u != v );
-   ASSERT_TRUE( u != w );
-   ASSERT_FALSE( u == w );
-};
-
-TEST( MultiArrayTest, testEquivalenceOperator )
-{
-   using namespace TNL::Containers;
-   MultiArray< Dimension, ValueType, Device, IndexType > u;
-   MultiArray< Dimension, ValueType, Device, IndexType > v;
-   u. setDimensions( 10 );
-   v. setDimensions( 10 );
-   for( int i = 0; i < 10; i ++ )
-      setDiagonalElement( u, i, i );
-   v = u;
-   ASSERT_TRUE( u == v );
-   ASSERT_FALSE( u != v );
-};
-
-TEST( MultiArrayTest, testGetSize )
-{
-   using namespace TNL::Containers;
-   MultiArray< Dimension, ValueType, Device, IndexType > u;
-   const int maxSize = 10;
-   for( int i = 1; i < maxSize; i ++ )
-      u. setDimensions( i );
-
-   ASSERT_EQ( u. getDimensions().x(), maxSize - 1 );
-};
-
-TEST( MultiArrayTest, testReset )
-{
-   using namespace TNL::Containers;
-   MultiArray< Dimension, ValueType, Device, IndexType > u;
-   u.setDimensions( 100 );
-   ASSERT_EQ( u. getDimensions().x(), 100 );
-   u.reset();
-   ASSERT_EQ( u. getDimensions().x(), 0 );
-   u.setDimensions( 100 );
-   ASSERT_EQ( u. getDimensions().x(), 100 );
-   u.reset();
-   ASSERT_EQ( u. getDimensions().x(), 0 );
-
-};
-
-TEST( MultiArrayTest, testSetSizeAndDestructor )
-{
-   using namespace TNL::Containers;
-   for( int i = 1; i < 100; i ++ )
-   {
-      MultiArray< Dimension, ValueType, Device, IndexType > u;
-      u. setDimensions( i );
-   }
-}
-
-TEST( MultiArrayTest, testSaveAndLoad )
-{
-   using namespace TNL::Containers;
-   MultiArray< Dimension, ValueType, Device, IndexType > v;
-   const int size( 10 );
-   ASSERT_TRUE( v. setDimensions( size ) );
-   for( int i = 0; i < size; i ++ )
-      setDiagonalElement( v, i, 3.14147 );
-   File file;
-   file. open( "test-file.tnl", IOMode::write );
-   ASSERT_TRUE( v. save( file ) );
-   file. close();
-   MultiArray< Dimension, ValueType, Device, IndexType > u;
-   file. open( "test-file.tnl", IOMode::read );
-   ASSERT_TRUE( u. load( file ) );
-   file. close();
-   ASSERT_TRUE( u == v );
-
-   EXPECT_EQ( std::remove( "test-file.tnl" ), 0 );
-}
-#endif /* HAVE_GTEST */
-
-int main( int argc, char* argv[] )
-{
-#ifdef HAVE_GTEST
-   ::testing::InitGoogleTest( &argc, argv );
-   return RUN_ALL_TESTS();
-#else
-   return EXIT_FAILURE;
-#endif
-}
-
-
-
-
-
-
diff --git a/src/UnitTests/Containers/Multimaps/MultimapTest.cpp b/src/UnitTests/Containers/Multimaps/MultimapTest.cpp
index 120a2451fb7a2989aad9bb23a31ce0689bc7bf30..4612c1dd3709efcc470fee9b70e0d3a359b6a693 100644
--- a/src/UnitTests/Containers/Multimaps/MultimapTest.cpp
+++ b/src/UnitTests/Containers/Multimaps/MultimapTest.cpp
@@ -42,20 +42,23 @@ TEST( MultimapTest, TestSettingSizes )
 
    for( IndexType i = 0; i < inputs; i++ ) {
       auto values = map.getValues( i );
-      const auto constValues = ( (const MultimapType) map ).getValues( i );
+      const auto constValues = ( (const MultimapType&) map ).getValues( i );
 
       // uninitialized should be equal to the value from the allocation vector
       ASSERT_EQ( values.getSize(), allocationRanges[ i ] );
+      // This does not work with Array deep copy constructor
       ASSERT_EQ( constValues.getSize(), allocationRanges[ i ] );
 
       // setting lower sizes
       values.setSize( valuesLocalMax );
       ASSERT_EQ( values.getSize(), valuesLocalMax );
+      // This does not work with Array deep copy constructor
       ASSERT_EQ( constValues.getSize(), valuesLocalMax );
 
       // setting global max
       values.setSize( valuesGlobalMax );
       ASSERT_EQ( values.getSize(), valuesGlobalMax );
+      // This does not work with Array deep copy constructor
       ASSERT_EQ( constValues.getSize(), valuesGlobalMax );
    }
 }
@@ -78,7 +81,7 @@ TEST( MultimapTest, TestSettingValues )
 
    for( IndexType i = 0; i < inputs; i++ ) {
       auto values = map.getValues( i );
-      const auto constValues = ( (const MultimapType) map ).getValues( i );
+      const auto constValues = ( (const MultimapType&) map ).getValues( i );
 
       values.setSize( allocatedValues );
 
@@ -126,8 +129,8 @@ TEST( MultimapTest, TestSaveAndLoad )
          values.setValue( o, i + o );
    }
 
-   ASSERT_TRUE( map.save( "multimap-test.tnl" ) );
-   ASSERT_TRUE( map2.load( "multimap-test.tnl" ) );
+   map.save( "multimap-test.tnl" );
+   map2.load( "multimap-test.tnl" );
 
    EXPECT_EQ( map, map2 );
    EXPECT_EQ( map.getKeysRange(), map2.getKeysRange() );
diff --git a/src/UnitTests/Containers/Multimaps/StaticMultimapTest.cpp b/src/UnitTests/Containers/Multimaps/StaticMultimapTest.cpp
index 3e29dadf00a1c9310b1de232c670e3b38da33f66..3602f53ca83708f874bd5a4492ec751800b4876f 100644
--- a/src/UnitTests/Containers/Multimaps/StaticMultimapTest.cpp
+++ b/src/UnitTests/Containers/Multimaps/StaticMultimapTest.cpp
@@ -77,8 +77,8 @@ TEST( MultimapTest, TestSaveAndLoad )
          values.setValue( o, i + o );
    }
 
-   ASSERT_TRUE( map.save( "multimap-test.tnl" ) );
-   ASSERT_TRUE( map2.load( "multimap-test.tnl" ) );
+   map.save( "multimap-test.tnl" );
+   map2.load( "multimap-test.tnl" );
 
    EXPECT_EQ( map, map2 );
    EXPECT_EQ( map.getKeysRange(), map2.getKeysRange() );
diff --git a/src/UnitTests/Containers/StaticArrayTest.cpp b/src/UnitTests/Containers/StaticArrayTest.cpp
index e3d0b1f63e28864b0980d71af6623b51224c1218..a418b9d06ce026fcb0584e3a71150fe332d1729b 100644
--- a/src/UnitTests/Containers/StaticArrayTest.cpp
+++ b/src/UnitTests/Containers/StaticArrayTest.cpp
@@ -246,10 +246,10 @@ TYPED_TEST( StaticArrayTest, SaveAndLoad )
 
    ArrayType u1( 7 ), u2;
    File file;
-   file.open( "tnl-static-array-test.tnl", IOMode::write );
+   file.open( "tnl-static-array-test.tnl", File::Mode::Out );
    u1.save( file );
    file.close();
-   file.open( "tnl-static-array-test.tnl", IOMode::read );
+   file.open( "tnl-static-array-test.tnl", File::Mode::In );
    u2.load( file );
    file.close();
 
diff --git a/src/UnitTests/FileTest.h b/src/UnitTests/FileTest.h
index 4da7418924b5b8e0089bac8f53b8daeb627f91bc..39671ba661ca77add041345206c9fd2926ce2879 100644
--- a/src/UnitTests/FileTest.h
+++ b/src/UnitTests/FileTest.h
@@ -15,38 +15,32 @@
 
 using namespace TNL;
 
-TEST( FileTest, CloseEmpty )
-{
-   File file;
-   ASSERT_TRUE( file.close() );
-}
-
 TEST( FileTest, OpenInvalid )
 {
    File file;
-   EXPECT_THROW( file.open( "invalid-file.tnl", IOMode::read ), std::ios_base::failure );
+   EXPECT_THROW( file.open( "invalid-file.tnl", File::Mode::In ), std::ios_base::failure );
 }
 
 TEST( FileTest, WriteAndRead )
 {
    File file;
-   ASSERT_TRUE( file.open( String( "test-file.tnl" ), IOMode::write ) );
+   file.open( String( "test-file.tnl" ), File::Mode::Out );
 
    int intData( 5 );
    double doubleData[ 3 ] = { 1.0, 2.0, 3.0 };
    const double constDoubleData = 3.14;
-   ASSERT_TRUE( file.write( &intData ) );
-   ASSERT_TRUE( file.write( doubleData, 3 ) );
-   ASSERT_TRUE( file.write( &constDoubleData ) );
-   ASSERT_TRUE( file.close() );
+   file.save( &intData );
+   file.save( doubleData, 3 );
+   file.save( &constDoubleData );
+   file.close();
 
-   ASSERT_TRUE( file.open( String( "test-file.tnl" ), IOMode::read ) );
+   file.open( String( "test-file.tnl" ), File::Mode::In );
    int newIntData;
    double newDoubleData[ 3 ];
    double newConstDoubleData;
-   ASSERT_TRUE( file.read( &newIntData, 1 ) );
-   ASSERT_TRUE( file.read( newDoubleData, 3 ) );
-   ASSERT_TRUE( file.read( &newConstDoubleData, 1 ) );
+   file.load( &newIntData, 1 );
+   file.load( newDoubleData, 3 );
+   file.load( &newConstDoubleData, 1 );
 
    EXPECT_EQ( newIntData, intData );
    for( int i = 0; i < 3; i ++ )
@@ -56,6 +50,37 @@ TEST( FileTest, WriteAndRead )
    EXPECT_EQ( std::remove( "test-file.tnl" ), 0 );
 };
 
+TEST( FileTest, WriteAndReadWithConversion )
+{
+   double doubleData[ 3 ] = {  3.1415926535897932384626433,
+                               2.7182818284590452353602874,
+                               1.6180339887498948482045868 };
+   float floatData[ 3 ];
+   int intData[ 3 ];
+   File file;
+   file.open( "test-file.tnl", File::Mode::Out | File::Mode::Truncate );
+   file.save< double, float, Devices::Host >( doubleData, 3 );
+   file.close();
+
+   file.open( "test-file.tnl", File::Mode::In );
+   file.load< float, float, Devices::Host >( floatData, 3 );
+   file.close();
+
+   file.open( "test-file.tnl", File::Mode::In );
+   file.load< int, float, Devices::Host >( intData, 3 );
+   file.close();
+
+   EXPECT_NEAR( floatData[ 0 ], 3.14159, 0.0001 );
+   EXPECT_NEAR( floatData[ 1 ], 2.71828, 0.0001 );
+   EXPECT_NEAR( floatData[ 2 ], 1.61803, 0.0001 );
+
+   EXPECT_EQ( intData[ 0 ], 3 );
+   EXPECT_EQ( intData[ 1 ], 2 );
+   EXPECT_EQ( intData[ 2 ], 1 );
+
+   EXPECT_EQ( std::remove( "test-file.tnl" ), 0 );
+}
+
 #ifdef HAVE_CUDA
 TEST( FileTest, WriteAndReadCUDA )
 {
@@ -83,17 +108,14 @@ TEST( FileTest, WriteAndReadCUDA )
                cudaMemcpyHostToDevice );
 
    File file;
-   ASSERT_TRUE( file.open( String( "test-file.tnl" ), IOMode::write ) );
+   file.open( String( "test-file.tnl" ), File::Mode::Out );
 
-   bool status = file.write< int, Devices::Cuda >( cudaIntData );
-   ASSERT_TRUE( status );
-   status = file.write< float, Devices::Cuda >( cudaFloatData, 3 );
-   ASSERT_TRUE( status );
-   status = file.write< const double, Devices::Cuda >( cudaConstDoubleData );
-   ASSERT_TRUE( status );
-   ASSERT_TRUE( file.close() );
+   file.save< int, int, Devices::Cuda >( cudaIntData );
+   file.save< float, float, Devices::Cuda >( cudaFloatData, 3 );
+   file.save< const double, double, Devices::Cuda >( cudaConstDoubleData );
+   file.close();
 
-   ASSERT_TRUE( file.open( String( "test-file.tnl" ), IOMode::read ) );
+   file.open( String( "test-file.tnl" ), File::Mode::In );
    int newIntData;
    float newFloatData[ 3 ];
    double newDoubleData;
@@ -103,12 +125,9 @@ TEST( FileTest, WriteAndReadCUDA )
    cudaMalloc( ( void** ) &newCudaIntData, sizeof( int ) );
    cudaMalloc( ( void** ) &newCudaFloatData, 3 * sizeof( float ) );
    cudaMalloc( ( void** ) &newCudaDoubleData, sizeof( double ) );
-   status = file.read< int, Devices::Cuda >( newCudaIntData, 1 );
-   ASSERT_TRUE( status );
-   status = file.read< float, Devices::Cuda >( newCudaFloatData, 3 );
-   ASSERT_TRUE( status );
-   status = file.read< double, Devices::Cuda >( newCudaDoubleData, 1 );
-   ASSERT_TRUE( status );
+   file.load< int, int, Devices::Cuda >( newCudaIntData, 1 );
+   file.load< float, float, Devices::Cuda >( newCudaFloatData, 3 );
+   file.load< double, double, Devices::Cuda >( newCudaDoubleData, 1 );
    cudaMemcpy( &newIntData,
                newCudaIntData,
                sizeof( int ),
@@ -129,6 +148,60 @@ TEST( FileTest, WriteAndReadCUDA )
 
    EXPECT_EQ( std::remove( "test-file.tnl" ), 0 );
 };
+
+TEST( FileTest, WriteAndReadCUDAWithConversion )
+{
+   const double constDoubleData[ 3 ] = {  3.1415926535897932384626433,
+                                          2.7182818284590452353602874,
+                                          1.6180339887498948482045868 };
+   float floatData[ 3 ];
+   int intData[ 3 ];
+
+   int* cudaIntData;
+   float* cudaFloatData;
+   const double* cudaConstDoubleData;
+   cudaMalloc( ( void** ) &cudaIntData, 3 * sizeof( int ) );
+   cudaMalloc( ( void** ) &cudaFloatData, 3 * sizeof( float ) );
+   cudaMalloc( ( void** ) &cudaConstDoubleData, 3 * sizeof( double ) );
+   cudaMemcpy( (void*) cudaConstDoubleData,
+               &constDoubleData,
+               3 * sizeof( double ),
+               cudaMemcpyHostToDevice );
+
+   File file;
+   file.open( String( "cuda-test-file.tnl" ), File::Mode::Out | File::Mode::Truncate );
+   file.save< double, float, Devices::Cuda >( cudaConstDoubleData, 3 );
+   file.close();
+
+   file.open( String( "cuda-test-file.tnl" ), File::Mode::In );
+   file.load< float, float, Devices::Cuda >( cudaFloatData, 3 );
+   file.close();
+
+   file.open( String( "cuda-test-file.tnl" ), File::Mode::In );
+   file.load< int, float, Devices::Cuda >( cudaIntData, 3 );
+   file.close();
+
+   cudaMemcpy( floatData,
+               cudaFloatData,
+               3 * sizeof( float ),
+               cudaMemcpyDeviceToHost );
+   cudaMemcpy( &intData,
+               cudaIntData,
+               3* sizeof( int ),
+               cudaMemcpyDeviceToHost );
+
+
+   EXPECT_NEAR( floatData[ 0 ], 3.14159, 0.0001 );
+   EXPECT_NEAR( floatData[ 1 ], 2.71828, 0.0001 );
+   EXPECT_NEAR( floatData[ 2 ], 1.61803, 0.0001 );
+
+   EXPECT_EQ( intData[ 0 ], 3 );
+   EXPECT_EQ( intData[ 1 ], 2 );
+   EXPECT_EQ( intData[ 2 ], 1 );
+
+   EXPECT_EQ( std::remove( "cuda-test-file.tnl" ), 0 );
+};
+
 #endif
 #endif
 
diff --git a/src/UnitTests/Meshes/DistributedMeshes/CutDistributedMeshFunctionTest.cpp b/src/UnitTests/Meshes/DistributedMeshes/CutDistributedMeshFunctionTest.cpp
index 000a832b6011cd7b444ed27d141a8debbfec7c38..caaf3f613e39a616da425b330799c6d12e817ae9 100644
--- a/src/UnitTests/Meshes/DistributedMeshes/CutDistributedMeshFunctionTest.cpp
+++ b/src/UnitTests/Meshes/DistributedMeshes/CutDistributedMeshFunctionTest.cpp
@@ -592,7 +592,7 @@ TEST(CutDistributedMeshFunction, 3D_2_Save)
         if(CommunicatorType::GetRank(*group)==0)
         {
             File meshFile;
-            meshFile.open( FileName+String("-mesh.tnl"),IOMode::write);
+            meshFile.open( FileName+String("-mesh.tnl"),File::Mode::Out);
             cutDistributedGrid.getGlobalGrid().save( meshFile );
             meshFile.close();
         }
@@ -612,8 +612,7 @@ TEST(CutDistributedMeshFunction, 3D_2_Save)
        loadMeshFunctionptr.bind(globalCutGrid,loaddof);
 
         File file;
-        bool ok=file.open( FileName, IOMode::read );
-        TNL_ASSERT_TRUE(ok,"Cannot open file");
+        file.open( FileName, File::Mode::In );
         loadMeshFunctionptr.boundLoad(file);
         file.close();
  
diff --git a/src/UnitTests/Meshes/DistributedMeshes/DistributedGridIOTest.h b/src/UnitTests/Meshes/DistributedMeshes/DistributedGridIOTest.h
index d8b19c229c53ce0d3a558b62399163a653b47cd0..09be099c5507654e5075cfd36e5764017524efd0 100644
--- a/src/UnitTests/Meshes/DistributedMeshes/DistributedGridIOTest.h
+++ b/src/UnitTests/Meshes/DistributedMeshes/DistributedGridIOTest.h
@@ -276,7 +276,7 @@ class TestDistributedGridIO
         String localFileName= fileName+String("-")+distributedGrid.printProcessCoords()+String(".tnl");
 
         File file;
-        ASSERT_TRUE( file.open(localFileName, IOMode::read ) );
+        file.open(localFileName, File::Mode::In );
         loadMeshFunctionptr->boundLoad(file);
         file.close();
 
@@ -336,7 +336,7 @@ class TestDistributedGridIO
         String fileName=String("test-file-distributedgrid-io-load.tnl");
         String localFileName=fileName+String("-")+distributedGrid.printProcessCoords()+String(".tnl");
         File file;
-        ASSERT_TRUE( file.open( localFileName, IOMode::write ) );
+        file.open( localFileName, File::Mode::Out );
         localMeshFunctionptr->save(file);
         file.close();
 
diff --git a/src/UnitTests/Meshes/DistributedMeshes/DistributedGridIO_MPIIOTest.h b/src/UnitTests/Meshes/DistributedMeshes/DistributedGridIO_MPIIOTest.h
index ef0160741641be58b36291cb0cf42b9594c9cc2d..b19c8641f2adfd3d30f8e3001b432d7231e9eab5 100644
--- a/src/UnitTests/Meshes/DistributedMeshes/DistributedGridIO_MPIIOTest.h
+++ b/src/UnitTests/Meshes/DistributedMeshes/DistributedGridIO_MPIIOTest.h
@@ -100,7 +100,7 @@ class TestDistributedGridMPIIO{
             loadDof.setValue(-1);
         
             File file;
-            file.open( FileName, IOMode::read );
+            file.open( FileName, File::Mode::In );
             loadMeshFunctionptr->boundLoad(file);
             file.close();
 
@@ -148,7 +148,7 @@ class TestDistributedGridMPIIO{
             linearFunctionEvaluator.evaluateAllEntities(saveMeshFunctionptr , linearFunctionPtr);
       
             File file;
-            file.open( FileName, IOMode::write );        
+            file.open( FileName, File::Mode::Out );        
             saveMeshFunctionptr->save(file);
             file.close();
         }
diff --git a/src/UnitTests/Meshes/DistributedMeshes/DistributedVectorFieldIO_MPIIOTestBase.h b/src/UnitTests/Meshes/DistributedMeshes/DistributedVectorFieldIO_MPIIOTestBase.h
index e668847832825318d7da057e2909ba350fbcd347..055faa81226f3716d49594fe255b475a366f2797 100644
--- a/src/UnitTests/Meshes/DistributedMeshes/DistributedVectorFieldIO_MPIIOTestBase.h
+++ b/src/UnitTests/Meshes/DistributedMeshes/DistributedVectorFieldIO_MPIIOTestBase.h
@@ -80,7 +80,7 @@ class TestDistributedVectorFieldMPIIO{
         String FileName=String("/tmp/test-file.tnl");
         DistributedGridIO<VectorFieldType,MpiIO> ::save(FileName, vectorField );
         /*File file;
-        file.open( FileName, IOMode::write );
+        file.open( FileName, File::Mode::Out );
 		vectorField.save(file);
 		file.close();		*/
 
@@ -102,17 +102,13 @@ class TestDistributedVectorFieldMPIIO{
             loadDof.setValue(-1);
         
             File file;
-            file.open( FileName, IOMode::read );
-			bool loaded=loadvct.boundLoad(file);
-			file.close();
-            if(!loaded)
-				EXPECT_TRUE(loaded)<< "Chyba načtení souboru" <<std::endl;
-            else
-		        for(int i=0;i<loadDof.getSize();i++)
-		        {
-		          EXPECT_EQ( globalEvaluatedDof.getElement(i), loadDof.getElement(i)) << "Compare Loaded and evaluated Dof Failed for: "<< i;
-		        }
-		    }
+            file.open( FileName, File::Mode::In );
+	    loadvct.boundLoad(file);
+            for(int i=0;i<loadDof.getSize();i++)
+	    {
+		EXPECT_EQ( globalEvaluatedDof.getElement(i), loadDof.getElement(i)) << "Compare Loaded and evaluated Dof Failed for: "<< i;
+	    }
+       }
     };
     
     static void TestLoad()
@@ -153,7 +149,7 @@ class TestDistributedVectorFieldMPIIO{
                 linearFunctionEvaluator.evaluateAllEntities(saveVectorField[i] , linearFunctionPtr);
       
             File file;
-            file.open( FileName, IOMode::write );        
+            file.open( FileName, File::Mode::Out );        
             saveVectorField.save(file);
             file.close();
         }
diff --git a/src/UnitTests/Meshes/MeshTest.h b/src/UnitTests/Meshes/MeshTest.h
index 3835df28d5cae1ac07d952ed861474561f03c4f9..65ec8c353b3f4b2addbe4d5cea188adc18185c82 100644
--- a/src/UnitTests/Meshes/MeshTest.h
+++ b/src/UnitTests/Meshes/MeshTest.h
@@ -107,13 +107,13 @@ void testMeshOnCuda( const Mesh& mesh )
    EXPECT_EQ( mesh2, mesh );
 
    // test load from file to CUDA
-   ASSERT_TRUE( mesh.save( "mesh.tnl" ) );
-   ASSERT_TRUE( dmesh1.load( "mesh.tnl" ) );
+   mesh.save( "mesh.tnl" );
+   dmesh1.load( "mesh.tnl" );
    EXPECT_EQ( dmesh1, mesh );
 
    // test save into file from CUDA
-   ASSERT_TRUE( dmesh1.save( "mesh.tnl" ) );
-   ASSERT_TRUE( mesh2.load( "mesh.tnl" ) );
+   dmesh1.save( "mesh.tnl" );
+   mesh2.load( "mesh.tnl" );
    EXPECT_EQ( mesh2, mesh );
 
    EXPECT_EQ( std::remove( "mesh.tnl" ), 0 );
@@ -154,8 +154,8 @@ template< typename Mesh >
 void testFinishedMesh( const Mesh& mesh )
 {
    Mesh mesh2;
-   ASSERT_TRUE( mesh.save( "mesh.tnl" ) );
-   ASSERT_TRUE( mesh2.load( "mesh.tnl" ) );
+   mesh.save( "mesh.tnl" );
+   mesh2.load( "mesh.tnl" );
    EXPECT_EQ( std::remove( "mesh.tnl" ), 0 );
    ASSERT_EQ( mesh, mesh2 );
    compareStringRepresentation( mesh, mesh2 );
diff --git a/src/UnitTests/ObjectTest.cpp b/src/UnitTests/ObjectTest.cpp
index 488f7a49756727fd9314a50413d3f40f85a70172..ac0281afa2fd66614da1393a8f12b027beaba8f8 100644
--- a/src/UnitTests/ObjectTest.cpp
+++ b/src/UnitTests/ObjectTest.cpp
@@ -24,11 +24,11 @@ TEST( ObjectTest, SaveAndLoadTest )
 {
    Object testObject;
    File file;
-   file.open( "test-file.tnl", IOMode::write );
-   ASSERT_TRUE( testObject.save( file ) );
+   file.open( "test-file.tnl", File::Mode::Out );
+   testObject.save( file );
    file.close();
-   file.open( "test-file.tnl", IOMode::read );
-   ASSERT_TRUE( testObject.load( file ) );
+   file.open( "test-file.tnl", File::Mode::In );
+   testObject.load( file );
 
    EXPECT_EQ( std::remove( "test-file.tnl" ), 0 );
 }
@@ -75,6 +75,24 @@ TEST( ObjectTest, parseObjectTypeTest )
    expected = { "A", "b", "c <E>", "d" };
    EXPECT_EQ( parsed, expected );
 }
+
+TEST( HeaderTest, SaveAndLoadTest )
+{
+   Object testObject;
+   File file;
+   file.open( "test-file.tnl", File::Mode::Out );
+   saveHeader( file, "TYPE" );
+   file.close();
+   file.open( "test-file.tnl", File::Mode::In );
+   String type;
+   loadHeader( file, type );
+   
+   EXPECT_EQ( type, "TYPE" );
+
+   EXPECT_EQ( std::remove( "test-file.tnl" ), 0 );
+}
+
+
 #endif
 
 
diff --git a/src/UnitTests/SaveAndLoadMeshfunctionTest.cpp b/src/UnitTests/SaveAndLoadMeshfunctionTest.cpp
index f4b0cc7e6467ded039417d15b60b2f99fdb55335..e7079e894b1353c969231c1efcd607e1e8d8e8c3 100644
--- a/src/UnitTests/SaveAndLoadMeshfunctionTest.cpp
+++ b/src/UnitTests/SaveAndLoadMeshfunctionTest.cpp
@@ -62,9 +62,9 @@ class TestSaveAndLoadMeshfunction
             linearFunctionEvaluator.evaluateAllEntities(localMeshFunctionptr , linearFunctionPtr);
 
             File file;
-            ASSERT_TRUE( file.open( String( FILENAME), IOMode::write ));        
-            ASSERT_TRUE( localMeshFunctionptr->save(file));        
-            ASSERT_TRUE( file.close() );
+            file.open( String( FILENAME), File::Mode::Out );
+            localMeshFunctionptr->save(file);
+            file.close();
 
             //load other meshfunction on same localgrid from created file
             Pointers::SharedPointer<MeshType>  loadGridptr;
@@ -80,9 +80,9 @@ class TestSaveAndLoadMeshfunction
                 loadDof[i]=-1;
             }
 
-            ASSERT_TRUE(  file.open( String( FILENAME ), IOMode::read ));
-            ASSERT_TRUE( loadMeshFunctionptr->boundLoad(file));
-            ASSERT_TRUE( file.close());
+            file.open( String( FILENAME ), File::Mode::In );
+            loadMeshFunctionptr->boundLoad(file);
+            file.close();
 
             for(int i=0;i<localDof.getSize();i++)
             {
diff --git a/src/UnitTests/StringTest.cpp b/src/UnitTests/StringTest.cpp
index 10c85497b0044d03653b91cdc8b8729862158074..f44eac1c68ee30bfc053325b4f9a9803b6b013e2 100644
--- a/src/UnitTests/StringTest.cpp
+++ b/src/UnitTests/StringTest.cpp
@@ -83,7 +83,7 @@ TEST( StringTest, SetSize )
 {
    String str;
    str.setSize( 42 );
-   EXPECT_GT( str.getAllocatedSize(), 0 );
+   EXPECT_EQ( str.getAllocatedSize(), 42 );
 }
 
 TEST( StringTest, GetString )
@@ -277,7 +277,7 @@ TEST( StringTest, split )
    EXPECT_EQ( parts[ 4 ], "br" );
    EXPECT_EQ( parts[ 5 ], "" );
 
-   parts = String( "abracadabra" ).split( 'a', true );
+   parts = String( "abracadabra" ).split( 'a', String::SplitSkip::SkipEmpty );
    ASSERT_EQ( (int) parts.size(), 4 );
    EXPECT_EQ( parts[ 0 ], "br" );
    EXPECT_EQ( parts[ 1 ], "c" );
@@ -306,10 +306,10 @@ TEST( StringTest, SaveLoad )
 {
    String str1( "testing-string" );
    File file;
-   file.open( "test-file.tnl", IOMode::write );
+   file.open( "test-file.tnl", File::Mode::Out );
    ASSERT_NO_THROW( file << str1 );
    file.close();
-   file.open( "test-file.tnl", IOMode::read );
+   file.open( "test-file.tnl", File::Mode::In );
    String str2;
    ASSERT_NO_THROW( file >> str2 );
    EXPECT_EQ( str1, str2 );